From 4333fb0627ca18f863314942adc9f81d452f8251 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= Date: Sun, 14 Jan 2024 13:48:23 +0100 Subject: [PATCH 001/179] Clarify prioritization alert --- triagebot.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/triagebot.toml b/triagebot.toml index 1e1db2d16632e..08ca2ae10a250 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -383,7 +383,7 @@ message_on_add = """\ - Priority? - Regression? - Notify people/groups? -- Needs `I-nominated`? +- Needs `I-{team}-nominated`? """ message_on_remove = "Issue #{number}'s prioritization request has been removed." message_on_close = "Issue #{number} has been closed while requested for prioritization." From cf836bcc3c1a3c630f40ceb68e2378bafb33b12b Mon Sep 17 00:00:00 2001 From: Slanterns Date: Fri, 12 Apr 2024 02:27:58 +0800 Subject: [PATCH 002/179] Stabilize `Seek::seek_relative` --- library/std/src/io/mod.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/library/std/src/io/mod.rs b/library/std/src/io/mod.rs index 980b3e7aa48d0..c0a82f5b60553 100644 --- a/library/std/src/io/mod.rs +++ b/library/std/src/io/mod.rs @@ -2055,7 +2055,6 @@ pub trait Seek { /// # Example /// /// ```no_run - /// #![feature(seek_seek_relative)] /// use std::{ /// io::{self, Seek}, /// fs::File, @@ -2070,7 +2069,7 @@ pub trait Seek { /// ``` /// /// [`BufReader`]: crate::io::BufReader - #[unstable(feature = "seek_seek_relative", issue = "117374")] + #[stable(feature = "seek_seek_relative", since = "CURRENT_RUSTC_VERSION")] fn seek_relative(&mut self, offset: i64) -> Result<()> { self.seek(SeekFrom::Current(offset))?; Ok(()) From b91c1aafecdd804f3d12eae857671d2059e87c2e Mon Sep 17 00:00:00 2001 From: Ben Kimock Date: Mon, 15 Apr 2024 23:46:27 -0400 Subject: [PATCH 003/179] Clean up users of rust_dbg_call --- tests/auxiliary/rust_test_helpers.c | 6 +- .../auxiliary/extern-crosscrate-source.rs | 25 +++----- tests/ui/abi/extern/extern-call-deep.rs | 28 ++++----- tests/ui/abi/extern/extern-call-deep2.rs | 29 ++++----- tests/ui/abi/extern/extern-call-indirect.rs | 26 +++----- tests/ui/abi/extern/extern-call-scrub.rs | 30 ++++------ tests/ui/abi/extern/extern-crosscrate.rs | 9 +-- .../ui/abi/foreign/foreign-call-no-runtime.rs | 60 ------------------- 8 files changed, 56 insertions(+), 157 deletions(-) delete mode 100644 tests/ui/abi/foreign/foreign-call-no-runtime.rs diff --git a/tests/auxiliary/rust_test_helpers.c b/tests/auxiliary/rust_test_helpers.c index 965df44c67608..34cc7fd5dfbed 100644 --- a/tests/auxiliary/rust_test_helpers.c +++ b/tests/auxiliary/rust_test_helpers.c @@ -27,10 +27,10 @@ rust_dbg_extern_identity_u8(char u) { return u; } -typedef void *(*dbg_callback)(void*); +typedef uint64_t (*dbg_callback)(uint64_t); -void * -rust_dbg_call(dbg_callback cb, void *data) { +uint64_t +rust_dbg_call(dbg_callback cb, uint64_t data) { return cb(data); } diff --git a/tests/ui/abi/extern/auxiliary/extern-crosscrate-source.rs b/tests/ui/abi/extern/auxiliary/extern-crosscrate-source.rs index 9c61518b94142..6b21877109664 100644 --- a/tests/ui/abi/extern/auxiliary/extern-crosscrate-source.rs +++ b/tests/ui/abi/extern/auxiliary/extern-crosscrate-source.rs @@ -1,28 +1,21 @@ #![crate_name = "externcallback"] #![crate_type = "lib"] -#![feature(rustc_private)] -extern crate libc; - -pub mod rustrt { - extern crate libc; - - #[link(name = "rust_test_helpers", kind = "static")] - extern "C" { - pub fn rust_dbg_call( - cb: extern "C" fn(libc::uintptr_t) -> libc::uintptr_t, - data: libc::uintptr_t, - ) -> libc::uintptr_t; - } +#[link(name = "rust_test_helpers", kind = "static")] +extern "C" { + pub fn rust_dbg_call( + cb: extern "C" fn(u64) -> u64, + data: u64, + ) -> u64; } -pub fn fact(n: libc::uintptr_t) -> libc::uintptr_t { +pub fn fact(n: u64) -> u64 { unsafe { println!("n = {}", n); - rustrt::rust_dbg_call(cb, n) + rust_dbg_call(cb, n) } } -pub extern "C" fn cb(data: libc::uintptr_t) -> libc::uintptr_t { +pub extern "C" fn cb(data: u64) -> u64 { if data == 1 { data } else { fact(data - 1) * data } } diff --git a/tests/ui/abi/extern/extern-call-deep.rs b/tests/ui/abi/extern/extern-call-deep.rs index 062e70b1b6ee5..40457ae57207d 100644 --- a/tests/ui/abi/extern/extern-call-deep.rs +++ b/tests/ui/abi/extern/extern-call-deep.rs @@ -1,35 +1,27 @@ //@ run-pass //@ ignore-emscripten blows the JS stack -#![feature(rustc_private)] - -extern crate libc; - -mod rustrt { - extern crate libc; - - #[link(name = "rust_test_helpers", kind = "static")] - extern "C" { - pub fn rust_dbg_call( - cb: extern "C" fn(libc::uintptr_t) -> libc::uintptr_t, - data: libc::uintptr_t, - ) -> libc::uintptr_t; - } +#[link(name = "rust_test_helpers", kind = "static")] +extern "C" { + pub fn rust_dbg_call( + cb: extern "C" fn(u64) -> u64, + data: u64, + ) -> u64; } -extern "C" fn cb(data: libc::uintptr_t) -> libc::uintptr_t { +extern "C" fn cb(data: u64) -> u64 { if data == 1 { data } else { count(data - 1) + 1 } } -fn count(n: libc::uintptr_t) -> libc::uintptr_t { +fn count(n: u64) -> u64 { unsafe { println!("n = {}", n); - rustrt::rust_dbg_call(cb, n) + rust_dbg_call(cb, n) } } pub fn main() { let result = count(1000); - println!("result = {}", result); + println!("result = {:?}", result); assert_eq!(result, 1000); } diff --git a/tests/ui/abi/extern/extern-call-deep2.rs b/tests/ui/abi/extern/extern-call-deep2.rs index c021bc223482d..91ca28d80c80f 100644 --- a/tests/ui/abi/extern/extern-call-deep2.rs +++ b/tests/ui/abi/extern/extern-call-deep2.rs @@ -1,31 +1,24 @@ //@ run-pass -#![allow(unused_must_use)] //@ needs-threads -#![feature(rustc_private)] -extern crate libc; use std::thread; -mod rustrt { - extern crate libc; - - #[link(name = "rust_test_helpers", kind = "static")] - extern "C" { - pub fn rust_dbg_call( - cb: extern "C" fn(libc::uintptr_t) -> libc::uintptr_t, - data: libc::uintptr_t, - ) -> libc::uintptr_t; - } +#[link(name = "rust_test_helpers", kind = "static")] +extern "C" { + pub fn rust_dbg_call( + cb: extern "C" fn(u64) -> u64, + data: u64, + ) -> u64; } -extern "C" fn cb(data: libc::uintptr_t) -> libc::uintptr_t { - if data == 1 { data } else { count(data - 1) + 1 } +extern "C" fn cb(data: u64) -> u64 { + if data == 1 { data } else { count(data - 1 ) + 1 } } -fn count(n: libc::uintptr_t) -> libc::uintptr_t { +fn count(n: u64) -> u64 { unsafe { println!("n = {}", n); - rustrt::rust_dbg_call(cb, n) + rust_dbg_call(cb, n) } } @@ -37,5 +30,5 @@ pub fn main() { println!("result = {}", result); assert_eq!(result, 1000); }) - .join(); + .join().unwrap(); } diff --git a/tests/ui/abi/extern/extern-call-indirect.rs b/tests/ui/abi/extern/extern-call-indirect.rs index 18fb07d8c8bbd..ef1e8ae5e760d 100644 --- a/tests/ui/abi/extern/extern-call-indirect.rs +++ b/tests/ui/abi/extern/extern-call-indirect.rs @@ -1,29 +1,21 @@ //@ run-pass -#![feature(rustc_private)] - -extern crate libc; - -mod rustrt { - extern crate libc; - - #[link(name = "rust_test_helpers", kind = "static")] - extern "C" { - pub fn rust_dbg_call( - cb: extern "C" fn(libc::uintptr_t) -> libc::uintptr_t, - data: libc::uintptr_t, - ) -> libc::uintptr_t; - } +#[link(name = "rust_test_helpers", kind = "static")] +extern "C" { + pub fn rust_dbg_call( + cb: extern "C" fn(u64) -> u64, + data: u64, + ) -> u64; } -extern "C" fn cb(data: libc::uintptr_t) -> libc::uintptr_t { +extern "C" fn cb(data: u64) -> u64 { if data == 1 { data } else { fact(data - 1) * data } } -fn fact(n: libc::uintptr_t) -> libc::uintptr_t { +fn fact(n: u64) -> u64 { unsafe { println!("n = {}", n); - rustrt::rust_dbg_call(cb, n) + rust_dbg_call(cb, n) } } diff --git a/tests/ui/abi/extern/extern-call-scrub.rs b/tests/ui/abi/extern/extern-call-scrub.rs index 7edf8975ad816..7df3a8f04ef1f 100644 --- a/tests/ui/abi/extern/extern-call-scrub.rs +++ b/tests/ui/abi/extern/extern-call-scrub.rs @@ -1,35 +1,27 @@ //@ run-pass -#![allow(unused_must_use)] +//@ needs-threads // This time we're testing repeatedly going up and down both stacks to // make sure the stack pointers are maintained properly in both // directions -//@ needs-threads -#![feature(rustc_private)] - -extern crate libc; use std::thread; -mod rustrt { - extern crate libc; - - #[link(name = "rust_test_helpers", kind = "static")] - extern "C" { - pub fn rust_dbg_call( - cb: extern "C" fn(libc::uintptr_t) -> libc::uintptr_t, - data: libc::uintptr_t, - ) -> libc::uintptr_t; - } +#[link(name = "rust_test_helpers", kind = "static")] +extern "C" { + pub fn rust_dbg_call( + cb: extern "C" fn(u64) -> u64, + data: u64, + ) -> u64; } -extern "C" fn cb(data: libc::uintptr_t) -> libc::uintptr_t { +extern "C" fn cb(data: u64) -> u64 { if data == 1 { data } else { count(data - 1) + count(data - 1) } } -fn count(n: libc::uintptr_t) -> libc::uintptr_t { +fn count(n: u64) -> u64 { unsafe { println!("n = {}", n); - rustrt::rust_dbg_call(cb, n) + rust_dbg_call(cb, n) } } @@ -41,5 +33,5 @@ pub fn main() { println!("result = {}", result); assert_eq!(result, 2048); }) - .join(); + .join().unwrap(); } diff --git a/tests/ui/abi/extern/extern-crosscrate.rs b/tests/ui/abi/extern/extern-crosscrate.rs index c283cbe321637..b467d9929844a 100644 --- a/tests/ui/abi/extern/extern-crosscrate.rs +++ b/tests/ui/abi/extern/extern-crosscrate.rs @@ -1,15 +1,12 @@ //@ run-pass //@ aux-build:extern-crosscrate-source.rs -#![feature(rustc_private)] - extern crate externcallback; -extern crate libc; -fn fact(n: libc::uintptr_t) -> libc::uintptr_t { +fn fact(n: u64) -> u64 { unsafe { - println!("n = {}", n); - externcallback::rustrt::rust_dbg_call(externcallback::cb, n) + println!("n = {:?}", n); + externcallback::rust_dbg_call(externcallback::cb, n) } } diff --git a/tests/ui/abi/foreign/foreign-call-no-runtime.rs b/tests/ui/abi/foreign/foreign-call-no-runtime.rs deleted file mode 100644 index fccd62b6100f3..0000000000000 --- a/tests/ui/abi/foreign/foreign-call-no-runtime.rs +++ /dev/null @@ -1,60 +0,0 @@ -//@ run-pass -//@ needs-threads - -#![feature(rustc_private)] - -extern crate libc; - -use std::mem; -use std::thread; - -#[link(name = "rust_test_helpers", kind = "static")] -extern "C" { - fn rust_dbg_call(cb: extern "C" fn(libc::uintptr_t), data: libc::uintptr_t) -> libc::uintptr_t; -} - -pub fn main() { - unsafe { - thread::spawn(move || { - let i: isize = 100; - rust_dbg_call(callback_isize, mem::transmute(&i)); - }) - .join() - .unwrap(); - - thread::spawn(move || { - let i: i32 = 100; - rust_dbg_call(callback_i32, mem::transmute(&i)); - }) - .join() - .unwrap(); - - thread::spawn(move || { - let i: i64 = 100; - rust_dbg_call(callback_i64, mem::transmute(&i)); - }) - .join() - .unwrap(); - } -} - -extern "C" fn callback_isize(data: libc::uintptr_t) { - unsafe { - let data = data as *const isize; - assert_eq!(*data, 100); - } -} - -extern "C" fn callback_i64(data: libc::uintptr_t) { - unsafe { - let data = data as *const i64; - assert_eq!(*data, 100); - } -} - -extern "C" fn callback_i32(data: libc::uintptr_t) { - unsafe { - let data = data as *const i32; - assert_eq!(*data, 100); - } -} From d5273fff484b0a88f599636b15b4efe2266749c3 Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Fri, 19 Apr 2024 18:45:25 +0000 Subject: [PATCH 004/179] Do intrinsic changes in `rustc_codegen_cranelift` --- example/example.rs | 2 +- example/mini_core.rs | 2 +- src/intrinsics/mod.rs | 10 +++++++--- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/example/example.rs b/example/example.rs index 885e55bc76423..1ef2aa5dd8ea4 100644 --- a/example/example.rs +++ b/example/example.rs @@ -149,7 +149,7 @@ pub fn array_as_slice(arr: &[u8; 3]) -> &[u8] { arr } -pub unsafe fn use_ctlz_nonzero(a: u16) -> u16 { +pub unsafe fn use_ctlz_nonzero(a: u16) -> u32 { intrinsics::ctlz_nonzero(a) } diff --git a/example/mini_core.rs b/example/mini_core.rs index e45c16ee280a7..5e535ff62e173 100644 --- a/example/mini_core.rs +++ b/example/mini_core.rs @@ -627,7 +627,7 @@ pub mod intrinsics { pub fn min_align_of_val(val: *const T) -> usize; pub fn copy(src: *const T, dst: *mut T, count: usize); pub fn transmute(e: T) -> U; - pub fn ctlz_nonzero(x: T) -> T; + pub fn ctlz_nonzero(x: T) -> u32; #[rustc_safe_intrinsic] pub fn needs_drop() -> bool; #[rustc_safe_intrinsic] diff --git a/src/intrinsics/mod.rs b/src/intrinsics/mod.rs index 0b213ff826969..79a90507fa2e1 100644 --- a/src/intrinsics/mod.rs +++ b/src/intrinsics/mod.rs @@ -26,6 +26,7 @@ use rustc_span::source_map::Spanned; use rustc_span::symbol::{sym, Symbol}; pub(crate) use self::llvm::codegen_llvm_intrinsic_call; +use crate::cast::clif_intcast; use crate::prelude::*; fn bug_on_incorrect_arg_count(intrinsic: impl std::fmt::Display) -> ! { @@ -627,7 +628,8 @@ fn codegen_regular_intrinsic_call<'tcx>( // FIXME trap on `ctlz_nonzero` with zero arg. let res = fx.bcx.ins().clz(val); - let res = CValue::by_val(res, arg.layout()); + let res = clif_intcast(fx, res, types::I32, false); + let res = CValue::by_val(res, ret.layout()); ret.write_cvalue(fx, res); } sym::cttz | sym::cttz_nonzero => { @@ -636,7 +638,8 @@ fn codegen_regular_intrinsic_call<'tcx>( // FIXME trap on `cttz_nonzero` with zero arg. let res = fx.bcx.ins().ctz(val); - let res = CValue::by_val(res, arg.layout()); + let res = clif_intcast(fx, res, types::I32, false); + let res = CValue::by_val(res, ret.layout()); ret.write_cvalue(fx, res); } sym::ctpop => { @@ -644,7 +647,8 @@ fn codegen_regular_intrinsic_call<'tcx>( let val = arg.load_scalar(fx); let res = fx.bcx.ins().popcnt(val); - let res = CValue::by_val(res, arg.layout()); + let res = clif_intcast(fx, res, types::I32, false); + let res = CValue::by_val(res, ret.layout()); ret.write_cvalue(fx, res); } sym::bitreverse => { From 4ad6c6c58157475af340241ee1c4f5d66472b3ea Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 23 Apr 2024 09:37:28 +0000 Subject: [PATCH 005/179] Merge commit 'de5d6523738fd44a0521b6abf3e73ae1df210741' into sync_cg_clif-2024-04-23 --- Cargo.lock | 239 +++++++----------- Cargo.toml | 14 +- build_system/abi_cafe.rs | 8 +- build_system/tests.rs | 10 +- example/alloc_example.rs | 1 + example/alloc_system.rs | 3 +- example/float-minmax-pass.rs | 2 +- example/mod_bench.rs | 1 + example/neon.rs | 2 + example/std_example.rs | 1 + ...e-some-test-on-x86_64-pc-windows-gnu.patch | 5 +- rust-toolchain | 2 +- src/abi/mod.rs | 2 + src/base.rs | 10 +- src/common.rs | 4 +- src/constant.rs | 27 +- src/debuginfo/mod.rs | 2 +- src/debuginfo/object.rs | 10 +- src/driver/jit.rs | 1 + src/inline_asm.rs | 26 +- src/lib.rs | 12 +- src/main_shim.rs | 1 + src/value_and_place.rs | 1 + 23 files changed, 189 insertions(+), 195 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8fdc1941de88f..33fe52ddbdd64 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,9 +4,9 @@ version = 3 [[package]] name = "ahash" -version = "0.8.7" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77c3a9648d43b9cd48db467b3f87fdd6e146bcc88ab0180006cef2179fe11d01" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" dependencies = [ "cfg-if", "once_cell", @@ -16,9 +16,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.75" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" +checksum = "f538837af36e6f6a9be0faa67f9a314f8119e4e4b5867c6ab40ed60360142519" [[package]] name = "arbitrary" @@ -34,9 +34,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bumpalo" -version = "3.14.0" +version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" [[package]] name = "cfg-if" @@ -46,18 +46,18 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "cranelift-bforest" -version = "0.106.0" +version = "0.107.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a535eb1cf5a6003197dc569320c40c1cb2d2f97ef5d5348eebf067f20957381" +checksum = "79b27922a6879b5b5361d0a084cb0b1941bf109a98540addcb932da13b68bed4" dependencies = [ "cranelift-entity", ] [[package]] name = "cranelift-codegen" -version = "0.106.0" +version = "0.107.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11b5066db32cec1492573827183af2142d2d88fe85a83cfc9e73f0f63d3788d4" +checksum = "304c455b28bf56372729acb356afbb55d622f2b0f2f7837aa5e57c138acaac4d" dependencies = [ "bumpalo", "cranelift-bforest", @@ -67,7 +67,7 @@ dependencies = [ "cranelift-entity", "cranelift-isle", "gimli", - "hashbrown 0.14.0", + "hashbrown 0.14.3", "log", "regalloc2", "smallvec", @@ -76,39 +76,39 @@ dependencies = [ [[package]] name = "cranelift-codegen-meta" -version = "0.106.0" +version = "0.107.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64942e5774308e835fbad4dd25f253105412c90324631910e1ec27963147bddb" +checksum = "1653c56b99591d07f67c5ca7f9f25888948af3f4b97186bff838d687d666f613" dependencies = [ "cranelift-codegen-shared", ] [[package]] name = "cranelift-codegen-shared" -version = "0.106.0" +version = "0.107.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c39c33db9a86dd6d8d04166a10c53deb477aeea3500eaaefca682e4eda9bb986" +checksum = "f5b6a9cf6b6eb820ee3f973a0db313c05dc12d370f37b4fe9630286e1672573f" [[package]] name = "cranelift-control" -version = "0.106.0" +version = "0.107.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b7fc4937613aea3156a0538800a17bf56f345a5da2e79ae3df58488c93d867f" +checksum = "d9d06e6bf30075fb6bed9e034ec046475093392eea1aff90eb5c44c4a033d19a" dependencies = [ "arbitrary", ] [[package]] name = "cranelift-entity" -version = "0.106.0" +version = "0.107.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f85575e79a153ce1ddbfb7fe1813519b4bfe1eb200cc9c8353b45ad123ae4d36" +checksum = "29be04f931b73cdb9694874a295027471817f26f26d2f0ebe5454153176b6e3a" [[package]] name = "cranelift-frontend" -version = "0.106.0" +version = "0.107.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbc31d6c0ab2249fe0c21e988256b42f5f401ab2673b4fc40076c82a698bdfb9" +checksum = "a07fd7393041d7faa2f37426f5dc7fc04003b70988810e8c063beefeff1cd8f9" dependencies = [ "cranelift-codegen", "log", @@ -118,15 +118,15 @@ dependencies = [ [[package]] name = "cranelift-isle" -version = "0.106.0" +version = "0.107.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc14f37e3314c0e4c53779c2f46753bf242efff76ee9473757a1fff3b495ad37" +checksum = "f341d7938caa6dff8149dac05bb2b53fc680323826b83b4cf175ab9f5139a3c9" [[package]] name = "cranelift-jit" -version = "0.106.0" +version = "0.107.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfdd1942f3233176a68c285380dbc84ff0440246a1bce308611c0a385b56ab18" +checksum = "42733555e06433f1461570e09dbd756dafc228b4dac75c597cdbdc518de07522" dependencies = [ "anyhow", "cranelift-codegen", @@ -139,14 +139,14 @@ dependencies = [ "region", "target-lexicon", "wasmtime-jit-icache-coherence", - "windows-sys 0.52.0", + "windows-sys", ] [[package]] name = "cranelift-module" -version = "0.106.0" +version = "0.107.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "121b2b5a16912554a1b9aace75b9b21eca49f28e33cbfbad4786dd9bc5361a5c" +checksum = "84950af02bb85f3da764d53a953b43bb29a732e793d4fe24637a61591be9a024" dependencies = [ "anyhow", "cranelift-codegen", @@ -155,9 +155,9 @@ dependencies = [ [[package]] name = "cranelift-native" -version = "0.106.0" +version = "0.107.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ea5375f76ab31f9800a23fb2b440810286a6f669a3eb467cdd7ff255ea64268" +checksum = "82af6066e6448d26eeabb7aa26a43f7ff79f8217b06bade4ee6ef230aecc8880" dependencies = [ "cranelift-codegen", "libc", @@ -166,9 +166,9 @@ dependencies = [ [[package]] name = "cranelift-object" -version = "0.106.0" +version = "0.107.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f34e04419ab41661e973d90a73aa7b12771455394dae7a69b101a9b7e7589db7" +checksum = "00af56107039ed150391df6f753298c7b08f2b6a2e0727d216b5fa599d684d8b" dependencies = [ "anyhow", "cranelift-codegen", @@ -181,9 +181,9 @@ dependencies = [ [[package]] name = "crc32fast" -version = "1.3.2" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +checksum = "b3855a8a784b474f333699ef2bbca9db2c4a1f6d9088a90a2d25b1eb53111eaa" dependencies = [ "cfg-if", ] @@ -222,21 +222,21 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.14.0" +version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" +checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" dependencies = [ "ahash", ] [[package]] name = "indexmap" -version = "2.0.0" +version = "2.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d" +checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" dependencies = [ "equivalent", - "hashbrown 0.14.0", + "hashbrown 0.14.3", ] [[package]] @@ -247,19 +247,19 @@ checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" [[package]] name = "libloading" -version = "0.8.1" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c571b676ddfc9a8c12f1f3d3085a7b163966a8fd8098a90640953ce5f6170161" +checksum = "0c2a198fb6b0eada2a8df47933734e6d35d350665a33a3593d7164fa52c75c19" dependencies = [ "cfg-if", - "windows-sys 0.48.0", + "windows-targets", ] [[package]] name = "log" -version = "0.4.20" +version = "0.4.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" +checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" [[package]] name = "mach" @@ -272,42 +272,42 @@ dependencies = [ [[package]] name = "memchr" -version = "2.6.3" +version = "2.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f232d6ef707e1956a43342693d2a31e72989554d58299d7a88738cc95b0d35c" +checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" [[package]] name = "object" -version = "0.32.0" +version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77ac5bbd07aea88c60a577a1ce218075ffd59208b2d7ca97adf9bfc5aeb21ebe" +checksum = "d8dd6c0cdf9429bce006e1362bfce61fa1bfd8c898a643ed8d2b471934701d3d" dependencies = [ "crc32fast", - "hashbrown 0.14.0", + "hashbrown 0.14.3", "indexmap", "memchr", ] [[package]] name = "once_cell" -version = "1.18.0" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" [[package]] name = "proc-macro2" -version = "1.0.75" +version = "1.0.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "907a61bd0f64c2f29cd1cf1dc34d05176426a3f504a78010f08416ddb7b13708" +checksum = "3d1597b0c024618f09a9c3b8655b7e430397a36d23fdafec26d6965e9eec3eba" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -369,9 +369,9 @@ checksum = "826167069c09b99d56f31e9ae5c99049e932a98c9dc2dac47645b08dbbf76ba7" [[package]] name = "smallvec" -version = "1.11.0" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "stable_deref_trait" @@ -381,9 +381,9 @@ checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" [[package]] name = "syn" -version = "2.0.47" +version = "2.0.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1726efe18f42ae774cc644f330953a5e7b3c3003d3edcecf18850fe9d4dd9afb" +checksum = "909518bc7b1c9b779f1bbf07f2929d35af9f0f37e47c6e9ef7f9dddc1e1821f3" dependencies = [ "proc-macro2", "quote", @@ -410,13 +410,13 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" [[package]] name = "wasmtime-jit-icache-coherence" -version = "19.0.0" +version = "20.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2796e4b4989db62899d2117e1e0258b839d088c044591b14e3a0396e7b3ae53a" +checksum = "7a9f93a3289057b26dc75eb84d6e60d7694f7d169c7c09597495de6e016a13ff" dependencies = [ "cfg-if", "libc", - "windows-sys 0.52.0", + "windows-sys", ] [[package]] @@ -441,137 +441,78 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" -[[package]] -name = "windows-sys" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" -dependencies = [ - "windows-targets 0.48.5", -] - [[package]] name = "windows-sys" version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.0", + "windows-targets", ] [[package]] name = "windows-targets" -version = "0.48.5" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" dependencies = [ - "windows_aarch64_gnullvm 0.48.5", - "windows_aarch64_msvc 0.48.5", - "windows_i686_gnu 0.48.5", - "windows_i686_msvc 0.48.5", - "windows_x86_64_gnu 0.48.5", - "windows_x86_64_gnullvm 0.48.5", - "windows_x86_64_msvc 0.48.5", + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", ] -[[package]] -name = "windows-targets" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" -dependencies = [ - "windows_aarch64_gnullvm 0.52.0", - "windows_aarch64_msvc 0.52.0", - "windows_i686_gnu 0.52.0", - "windows_i686_msvc 0.52.0", - "windows_x86_64_gnu 0.52.0", - "windows_x86_64_gnullvm 0.52.0", - "windows_x86_64_msvc 0.52.0", -] - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" - [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.48.5" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" +checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" [[package]] name = "windows_aarch64_msvc" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" - -[[package]] -name = "windows_i686_gnu" -version = "0.48.5" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" +checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" [[package]] name = "windows_i686_gnu" -version = "0.52.0" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" +checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" [[package]] -name = "windows_i686_msvc" -version = "0.48.5" +name = "windows_i686_gnullvm" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" +checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" [[package]] name = "windows_i686_msvc" -version = "0.52.0" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" +checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" [[package]] name = "windows_x86_64_gnu" -version = "0.48.5" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" +checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.0" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" +checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" [[package]] name = "windows_x86_64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.52.0" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" +checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" [[package]] name = "zerocopy" diff --git a/Cargo.toml b/Cargo.toml index d8a855b038307..2015cdbcc2a74 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,15 +8,15 @@ crate-type = ["dylib"] [dependencies] # These have to be in sync with each other -cranelift-codegen = { version = "0.106.0", default-features = false, features = ["std", "unwind", "all-arch"] } -cranelift-frontend = { version = "0.106.0" } -cranelift-module = { version = "0.106.0" } -cranelift-native = { version = "0.106.0" } -cranelift-jit = { version = "0.106.0", optional = true } -cranelift-object = { version = "0.106.0" } +cranelift-codegen = { version = "0.107.0", default-features = false, features = ["std", "unwind", "all-arch"] } +cranelift-frontend = { version = "0.107.0" } +cranelift-module = { version = "0.107.0" } +cranelift-native = { version = "0.107.0" } +cranelift-jit = { version = "0.107.0", optional = true } +cranelift-object = { version = "0.107.0" } target-lexicon = "0.12.0" gimli = { version = "0.28", default-features = false, features = ["write"]} -object = { version = "0.32", default-features = false, features = ["std", "read_core", "write", "archive", "coff", "elf", "macho", "pe"] } +object = { version = "0.33", default-features = false, features = ["std", "read_core", "write", "archive", "coff", "elf", "macho", "pe"] } indexmap = "2.0.0" libloading = { version = "0.8.0", optional = true } diff --git a/build_system/abi_cafe.rs b/build_system/abi_cafe.rs index 2e7ba1b2060b6..ecf303c30b6c3 100644 --- a/build_system/abi_cafe.rs +++ b/build_system/abi_cafe.rs @@ -43,7 +43,13 @@ pub(crate) fn run( let mut cmd = ABI_CAFE.run(bootstrap_host_compiler, dirs); cmd.arg("--"); cmd.arg("--pairs"); - cmd.args(pairs); + cmd.args( + if cfg!(not(any(target_os = "macos", all(target_os = "windows", target_env = "msvc")))) { + &pairs[..] + } else { + &pairs[..2] + }, + ); cmd.arg("--add-rustc-codegen-backend"); match cg_clif_dylib { CodegenBackend::Local(path) => { diff --git a/build_system/tests.rs b/build_system/tests.rs index 9efb6ed715ca7..76104901474c2 100644 --- a/build_system/tests.rs +++ b/build_system/tests.rs @@ -290,7 +290,7 @@ pub(crate) fn run_tests( && !skip_tests.contains(&"testsuite.extended_sysroot"); if run_base_sysroot || run_extended_sysroot { - let mut target_compiler = build_sysroot::build_sysroot( + let target_compiler = build_sysroot::build_sysroot( dirs, channel, sysroot_kind, @@ -299,11 +299,8 @@ pub(crate) fn run_tests( rustup_toolchain_name, target_triple.clone(), ); - // Rust's build system denies a couple of lints that trigger on several of the test - // projects. Changing the code to fix them is not worth it, so just silence all lints. - target_compiler.rustflags.push("--cap-lints=allow".to_owned()); - let runner = TestRunner::new( + let mut runner = TestRunner::new( dirs.clone(), target_compiler, use_unstable_features, @@ -319,6 +316,9 @@ pub(crate) fn run_tests( } if run_extended_sysroot { + // Rust's build system denies a couple of lints that trigger on several of the test + // projects. Changing the code to fix them is not worth it, so just silence all lints. + runner.target_compiler.rustflags.push("--cap-lints=allow".to_owned()); runner.run_testsuite(EXTENDED_SYSROOT_SUITE); } else { eprintln!("[SKIP] extended_sysroot tests"); diff --git a/example/alloc_example.rs b/example/alloc_example.rs index 117eed5afd8ab..da70ca7943983 100644 --- a/example/alloc_example.rs +++ b/example/alloc_example.rs @@ -1,4 +1,5 @@ #![feature(start, core_intrinsics, alloc_error_handler, lang_items)] +#![allow(internal_features)] #![no_std] extern crate alloc; diff --git a/example/alloc_system.rs b/example/alloc_system.rs index e64daf96b01c9..441f3cd298743 100644 --- a/example/alloc_system.rs +++ b/example/alloc_system.rs @@ -80,7 +80,6 @@ mod platform { extern "system" { fn GetProcessHeap() -> HANDLE; fn HeapAlloc(hHeap: HANDLE, dwFlags: DWORD, dwBytes: SIZE_T) -> LPVOID; - fn HeapReAlloc(hHeap: HANDLE, dwFlags: DWORD, lpMem: LPVOID, dwBytes: SIZE_T) -> LPVOID; fn HeapFree(hHeap: HANDLE, dwFlags: DWORD, lpMem: LPVOID) -> BOOL; fn GetLastError() -> DWORD; } @@ -111,7 +110,7 @@ mod platform { allocate_with_flags(layout, HEAP_ZERO_MEMORY) } #[inline] - unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) { + unsafe fn dealloc(&self, ptr: *mut u8, _layout: Layout) { let header = get_header(ptr); let err = HeapFree(GetProcessHeap(), 0, header.0 as LPVOID); debug_assert!(err != 0, "Failed to free heap memory: {}", GetLastError()); diff --git a/example/float-minmax-pass.rs b/example/float-minmax-pass.rs index a71217a554b57..c54574d801d3a 100644 --- a/example/float-minmax-pass.rs +++ b/example/float-minmax-pass.rs @@ -5,7 +5,7 @@ // Test that the simd_f{min,max} intrinsics produce the correct results. #![feature(repr_simd, core_intrinsics)] -#![allow(non_camel_case_types)] +#![allow(internal_features, non_camel_case_types)] #[repr(simd)] #[derive(Copy, Clone, PartialEq, Debug)] diff --git a/example/mod_bench.rs b/example/mod_bench.rs index f15e48acc41e5..11a3e8fc72d8d 100644 --- a/example/mod_bench.rs +++ b/example/mod_bench.rs @@ -1,4 +1,5 @@ #![feature(start, core_intrinsics, lang_items)] +#![allow(internal_features)] #![no_std] #[cfg_attr(unix, link(name = "c"))] diff --git a/example/neon.rs b/example/neon.rs index bad26947967dc..00e437d7e546a 100644 --- a/example/neon.rs +++ b/example/neon.rs @@ -4,7 +4,9 @@ #[cfg(target_arch = "aarch64")] use std::arch::aarch64::*; +#[cfg(target_arch = "aarch64")] use std::mem::transmute; +#[cfg(target_arch = "aarch64")] use std::simd::*; #[cfg(target_arch = "aarch64")] diff --git a/example/std_example.rs b/example/std_example.rs index 2fee912e52ccf..0205de5562287 100644 --- a/example/std_example.rs +++ b/example/std_example.rs @@ -7,6 +7,7 @@ tuple_trait, unboxed_closures )] +#![allow(internal_features)] #[cfg(target_arch = "x86_64")] use std::arch::x86_64::*; diff --git a/patches/0001-abi-cafe-Disable-some-test-on-x86_64-pc-windows-gnu.patch b/patches/0001-abi-cafe-Disable-some-test-on-x86_64-pc-windows-gnu.patch index 0e5e7cdfcdf1a..77716c5139978 100644 --- a/patches/0001-abi-cafe-Disable-some-test-on-x86_64-pc-windows-gnu.patch +++ b/patches/0001-abi-cafe-Disable-some-test-on-x86_64-pc-windows-gnu.patch @@ -11,7 +11,7 @@ diff --git a/src/report.rs b/src/report.rs index eeec614..f582867 100644 --- a/src/report.rs +++ b/src/report.rs -@@ -48,6 +48,12 @@ pub fn get_test_rules(test: &TestKey, caller: &dyn AbiImpl, callee: &dyn AbiImpl +@@ -48,6 +48,15 @@ pub fn get_test_rules(test: &TestKey, caller: &dyn AbiImpl, callee: &dyn AbiImpl // // THIS AREA RESERVED FOR VENDORS TO APPLY PATCHES @@ -19,6 +19,9 @@ index eeec614..f582867 100644 + if cfg!(all(target_os = "windows", target_env = "gnu")) && test.test_name == "ui128" { + result.run = Link; + result.check = Pass(Link); ++ } else if test.test_name == "ui128" { ++ result.run == Check; ++ result.check = Pass(Check); + } + // END OF VENDOR RESERVED AREA diff --git a/rust-toolchain b/rust-toolchain index 3e7da4e161f09..de340cf8c35cc 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2024-04-11" +channel = "nightly-2024-04-23" components = ["rust-src", "rustc-dev", "llvm-tools"] diff --git a/src/abi/mod.rs b/src/abi/mod.rs index 6363a0d59a4f2..6f346af25c6dd 100644 --- a/src/abi/mod.rs +++ b/src/abi/mod.rs @@ -7,11 +7,13 @@ mod returning; use std::borrow::Cow; use cranelift_codegen::ir::SigRef; +use cranelift_codegen::isa::CallConv; use cranelift_module::ModuleError; use rustc_codegen_ssa::errors::CompilerBuiltinsCannotCall; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc_middle::ty::layout::FnAbiOf; use rustc_middle::ty::print::with_no_trimmed_paths; +use rustc_middle::ty::TypeVisitableExt; use rustc_monomorphize::is_call_from_compiler_builtins_to_upstream_monomorphization; use rustc_session::Session; use rustc_span::source_map::Spanned; diff --git a/src/base.rs b/src/base.rs index f428c4c7c0de0..e3d050df4cd1b 100644 --- a/src/base.rs +++ b/src/base.rs @@ -2,12 +2,14 @@ use cranelift_codegen::ir::UserFuncName; use cranelift_codegen::CodegenError; +use cranelift_frontend::{FunctionBuilder, FunctionBuilderContext}; use cranelift_module::ModuleError; use rustc_ast::InlineAsmOptions; use rustc_index::IndexVec; use rustc_middle::ty::adjustment::PointerCoercion; use rustc_middle::ty::layout::FnAbiOf; use rustc_middle::ty::print::with_no_trimmed_paths; +use rustc_middle::ty::TypeVisitableExt; use rustc_monomorphize::is_call_from_compiler_builtins_to_upstream_monomorphization; use crate::constant::ConstantCx; @@ -823,7 +825,13 @@ fn codegen_stmt<'tcx>( }; let data = codegen_operand(fx, data); let meta = codegen_operand(fx, meta); - let ptr_val = CValue::pointer_from_data_and_meta(data, meta, layout); + assert!(data.layout().ty.is_unsafe_ptr()); + assert!(layout.ty.is_unsafe_ptr()); + let ptr_val = if meta.layout().is_zst() { + data.cast_pointer_to(layout) + } else { + CValue::by_val_pair(data.load_scalar(fx), meta.load_scalar(fx), layout) + }; lval.write_cvalue(fx, ptr_val); } Rvalue::Aggregate(ref kind, ref operands) => { diff --git a/src/common.rs b/src/common.rs index cf0b065414d88..2a24d6150bd6e 100644 --- a/src/common.rs +++ b/src/common.rs @@ -1,8 +1,10 @@ use cranelift_codegen::isa::TargetFrontendConfig; +use cranelift_frontend::{FunctionBuilder, FunctionBuilderContext}; use rustc_index::IndexVec; use rustc_middle::ty::layout::{ - FnAbiError, FnAbiOfHelpers, FnAbiRequest, LayoutError, LayoutOfHelpers, + self, FnAbiError, FnAbiOfHelpers, FnAbiRequest, LayoutError, LayoutOfHelpers, }; +use rustc_middle::ty::TypeFoldable; use rustc_span::source_map::Spanned; use rustc_target::abi::call::FnAbi; use rustc_target::abi::{Integer, Primitive}; diff --git a/src/constant.rs b/src/constant.rs index cb05c17ec2a88..cdf499a22f8dd 100644 --- a/src/constant.rs +++ b/src/constant.rs @@ -137,18 +137,23 @@ pub(crate) fn codegen_const_value<'tcx>( let alloc_id = prov.alloc_id(); let base_addr = match fx.tcx.global_alloc(alloc_id) { GlobalAlloc::Memory(alloc) => { - let data_id = data_id_for_alloc_id( - &mut fx.constants_cx, - fx.module, - alloc_id, - alloc.inner().mutability, - ); - let local_data_id = - fx.module.declare_data_in_func(data_id, &mut fx.bcx.func); - if fx.clif_comments.enabled() { - fx.add_comment(local_data_id, format!("{:?}", alloc_id)); + if alloc.inner().len() == 0 { + assert_eq!(offset, Size::ZERO); + fx.bcx.ins().iconst(fx.pointer_type, alloc.inner().align.bytes() as i64) + } else { + let data_id = data_id_for_alloc_id( + &mut fx.constants_cx, + fx.module, + alloc_id, + alloc.inner().mutability, + ); + let local_data_id = + fx.module.declare_data_in_func(data_id, &mut fx.bcx.func); + if fx.clif_comments.enabled() { + fx.add_comment(local_data_id, format!("{:?}", alloc_id)); + } + fx.bcx.ins().global_value(fx.pointer_type, local_data_id) } - fx.bcx.ins().global_value(fx.pointer_type, local_data_id) } GlobalAlloc::Function(instance) => { let func_id = crate::abi::import_function(fx.tcx, fx.module, instance); diff --git a/src/debuginfo/mod.rs b/src/debuginfo/mod.rs index 5d943b5d99657..f0b78e5d7c674 100644 --- a/src/debuginfo/mod.rs +++ b/src/debuginfo/mod.rs @@ -19,7 +19,7 @@ use rustc_codegen_ssa::debuginfo::type_names; use rustc_hir::def::DefKind; use rustc_hir::def_id::DefIdMap; use rustc_session::Session; -use rustc_span::{SourceFileHash, StableSourceFileId}; +use rustc_span::{FileNameDisplayPreference, SourceFileHash, StableSourceFileId}; use rustc_target::abi::call::FnAbi; pub(crate) use self::emit::{DebugReloc, DebugRelocName}; diff --git a/src/debuginfo/object.rs b/src/debuginfo/object.rs index 27eabd8a0a616..65f4c67b21f13 100644 --- a/src/debuginfo/object.rs +++ b/src/debuginfo/object.rs @@ -2,7 +2,7 @@ use cranelift_module::{DataId, FuncId}; use cranelift_object::ObjectProduct; use gimli::SectionId; use object::write::{Relocation, StandardSegment}; -use object::{RelocationEncoding, SectionKind}; +use object::{RelocationEncoding, RelocationFlags, SectionKind}; use rustc_data_structures::fx::FxHashMap; use crate::debuginfo::{DebugReloc, DebugRelocName}; @@ -72,9 +72,11 @@ impl WriteDebugInfo for ObjectProduct { Relocation { offset: u64::from(reloc.offset), symbol, - kind: reloc.kind, - encoding: RelocationEncoding::Generic, - size: reloc.size * 8, + flags: RelocationFlags::Generic { + kind: reloc.kind, + encoding: RelocationEncoding::Generic, + size: reloc.size * 8, + }, addend: i64::try_from(symbol_offset).unwrap() + reloc.addend, }, ) diff --git a/src/driver/jit.rs b/src/driver/jit.rs index 6dbc3f191278d..929fa92596dc6 100644 --- a/src/driver/jit.rs +++ b/src/driver/jit.rs @@ -6,6 +6,7 @@ use std::ffi::CString; use std::os::raw::{c_char, c_int}; use std::sync::{mpsc, Mutex, OnceLock}; +use cranelift_frontend::{FunctionBuilder, FunctionBuilderContext}; use cranelift_jit::{JITBuilder, JITModule}; use rustc_codegen_ssa::CrateInfo; use rustc_middle::mir::mono::MonoItem; diff --git a/src/inline_asm.rs b/src/inline_asm.rs index 171ee88a11c75..28b92f730da34 100644 --- a/src/inline_asm.rs +++ b/src/inline_asm.rs @@ -2,6 +2,7 @@ use std::fmt::Write; +use cranelift_codegen::isa::CallConv; use rustc_ast::ast::{InlineAsmOptions, InlineAsmTemplatePiece}; use rustc_span::sym; use rustc_target::asm::*; @@ -785,9 +786,9 @@ fn call_inline_asm<'tcx>( for (offset, place) in outputs { let ty = if place.layout().ty.is_simd() { let (lane_count, lane_type) = place.layout().ty.simd_size_and_type(fx.tcx); - fx.clif_type(lane_type).unwrap().by(lane_count.try_into().unwrap()).unwrap() + asm_clif_type(fx, lane_type).unwrap().by(lane_count.try_into().unwrap()).unwrap() } else { - fx.clif_type(place.layout().ty).unwrap() + asm_clif_type(fx, place.layout().ty).unwrap() }; let value = stack_slot.offset(fx, i32::try_from(offset.bytes()).unwrap().into()).load( fx, @@ -797,3 +798,24 @@ fn call_inline_asm<'tcx>( place.write_cvalue(fx, CValue::by_val(value, place.layout())); } } + +fn asm_clif_type<'tcx>(fx: &FunctionCx<'_, '_, 'tcx>, ty: Ty<'tcx>) -> Option { + match ty.kind() { + // Adapted from https://github.com/rust-lang/rust/blob/f3c66088610c1b80110297c2d9a8b5f9265b013f/compiler/rustc_hir_analysis/src/check/intrinsicck.rs#L136-L151 + ty::Adt(adt, args) if Some(adt.did()) == fx.tcx.lang_items().maybe_uninit() => { + let fields = &adt.non_enum_variant().fields; + let ty = fields[FieldIdx::from_u32(1)].ty(fx.tcx, args); + let ty::Adt(ty, args) = ty.kind() else { + unreachable!("expected first field of `MaybeUninit` to be an ADT") + }; + assert!( + ty.is_manually_drop(), + "expected first field of `MaybeUninit` to be `ManuallyDrop`" + ); + let fields = &ty.non_enum_variant().fields; + let ty = fields[FieldIdx::ZERO].ty(fx.tcx, args); + fx.clif_type(ty) + } + _ => fx.clif_type(ty), + } +} diff --git a/src/lib.rs b/src/lib.rs index d0ab64a558490..c9f84b6999718 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -87,21 +87,17 @@ mod prelude { AbiParam, Block, FuncRef, Inst, InstBuilder, MemFlags, Signature, SourceLoc, StackSlot, StackSlotData, StackSlotKind, TrapCode, Type, Value, }; - pub(crate) use cranelift_codegen::isa::{self, CallConv}; pub(crate) use cranelift_codegen::Context; - pub(crate) use cranelift_frontend::{FunctionBuilder, FunctionBuilderContext, Variable}; pub(crate) use cranelift_module::{self, DataDescription, FuncId, Linkage, Module}; pub(crate) use rustc_data_structures::fx::{FxHashMap, FxIndexMap}; pub(crate) use rustc_hir::def_id::{DefId, LOCAL_CRATE}; pub(crate) use rustc_index::Idx; - pub(crate) use rustc_middle::bug; pub(crate) use rustc_middle::mir::{self, *}; - pub(crate) use rustc_middle::ty::layout::{self, LayoutOf, TyAndLayout}; + pub(crate) use rustc_middle::ty::layout::{LayoutOf, TyAndLayout}; pub(crate) use rustc_middle::ty::{ - self, FloatTy, Instance, InstanceDef, IntTy, ParamEnv, Ty, TyCtxt, TypeAndMut, - TypeFoldable, TypeVisitableExt, UintTy, + self, FloatTy, Instance, InstanceDef, IntTy, ParamEnv, Ty, TyCtxt, TypeAndMut, UintTy, }; - pub(crate) use rustc_span::{FileNameDisplayPreference, Span}; + pub(crate) use rustc_span::Span; pub(crate) use rustc_target::abi::{Abi, FieldIdx, Scalar, Size, VariantIdx, FIRST_VARIANT}; pub(crate) use crate::abi::*; @@ -261,7 +257,7 @@ fn target_triple(sess: &Session) -> target_lexicon::Triple { } } -fn build_isa(sess: &Session, backend_config: &BackendConfig) -> Arc { +fn build_isa(sess: &Session, backend_config: &BackendConfig) -> Arc { use target_lexicon::BinaryFormat; let target_triple = crate::target_triple(sess); diff --git a/src/main_shim.rs b/src/main_shim.rs index 1abfded8b11f0..1f20ec42ddb3e 100644 --- a/src/main_shim.rs +++ b/src/main_shim.rs @@ -1,3 +1,4 @@ +use cranelift_frontend::{FunctionBuilder, FunctionBuilderContext}; use rustc_hir::LangItem; use rustc_middle::ty::AssocKind; use rustc_middle::ty::GenericArg; diff --git a/src/value_and_place.rs b/src/value_and_place.rs index 8d52fd9d7a8e4..38fedb6036cc0 100644 --- a/src/value_and_place.rs +++ b/src/value_and_place.rs @@ -2,6 +2,7 @@ use cranelift_codegen::entity::EntityRef; use cranelift_codegen::ir::immediates::Offset32; +use cranelift_frontend::Variable; use rustc_middle::ty::FnSig; use crate::prelude::*; From f7627c3baa51be16743a363827594121cb0b63b9 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 23 Apr 2024 14:56:13 +0000 Subject: [PATCH 006/179] Fix broken subtree sync --- src/value_and_place.rs | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/src/value_and_place.rs b/src/value_and_place.rs index 38fedb6036cc0..dded6df7771df 100644 --- a/src/value_and_place.rs +++ b/src/value_and_place.rs @@ -95,23 +95,6 @@ impl<'tcx> CValue<'tcx> { CValue(CValueInner::ByValPair(value, extra), layout) } - /// For `AggregateKind::RawPtr`, create a pointer from its parts. - /// - /// Panics if the `layout` is not a raw pointer. - pub(crate) fn pointer_from_data_and_meta( - data: CValue<'tcx>, - meta: CValue<'tcx>, - layout: TyAndLayout<'tcx>, - ) -> CValue<'tcx> { - assert!(layout.ty.is_unsafe_ptr()); - let inner = match (data.0, meta.0) { - (CValueInner::ByVal(p), CValueInner::ByVal(m)) => CValueInner::ByValPair(p, m), - (p @ CValueInner::ByVal(_), CValueInner::ByRef(..)) if meta.1.is_zst() => p, - _ => bug!("RawPtr operands {data:?} {meta:?}"), - }; - CValue(inner, layout) - } - pub(crate) fn layout(&self) -> TyAndLayout<'tcx> { self.1 } From dda4709b1cba078ab05a32aa9c9359537e0ae0ad Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 11 Apr 2024 13:15:34 +0000 Subject: [PATCH 007/179] Error on using `yield` without also using `#[coroutine]` on the closure And suggest adding the `#[coroutine]` to the closure --- example/polymorphize_coroutine.rs | 5 +++-- example/std_example.rs | 10 +++++++--- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/example/polymorphize_coroutine.rs b/example/polymorphize_coroutine.rs index c965b34e13b90..407da94c0f092 100644 --- a/example/polymorphize_coroutine.rs +++ b/example/polymorphize_coroutine.rs @@ -1,4 +1,4 @@ -#![feature(coroutines, coroutine_trait)] +#![feature(coroutines, coroutine_trait, stmt_expr_attributes)] use std::ops::Coroutine; use std::pin::Pin; @@ -8,7 +8,8 @@ fn main() { } fn run_coroutine() { - let mut coroutine = || { + let mut coroutine = #[coroutine] + || { yield; return; }; diff --git a/example/std_example.rs b/example/std_example.rs index 0205de5562287..90d4ab721daef 100644 --- a/example/std_example.rs +++ b/example/std_example.rs @@ -1,6 +1,7 @@ #![feature( core_intrinsics, coroutines, + stmt_expr_attributes, coroutine_trait, is_sorted, repr_simd, @@ -123,9 +124,12 @@ fn main() { test_simd(); } - Box::pin(move |mut _task_context| { - yield (); - }) + Box::pin( + #[coroutine] + move |mut _task_context| { + yield (); + }, + ) .as_mut() .resume(0); From 9a57c636e7e147184fa061aefdbb4086b305dadc Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Fri, 9 Feb 2024 15:39:25 +0300 Subject: [PATCH 008/179] debuginfo: Stabilize `-Z debug-macros`, `-Z collapse-macro-debuginfo` and `#[collapse_debuginfo]` `-Z debug-macros` is "stabilized" by enabling it by default and removing. `-Z collapse-macro-debuginfo` is stabilized as `-C collapse-macro-debuginfo`. It now supports all typical boolean values (`parse_opt_bool`) in addition to just yes/no. Default value of `collapse_debuginfo` was changed from `false` to `external` (i.e. collapsed if external, not collapsed if local). `#[collapse_debuginfo]` attribute without a value is no longer supported to avoid guessing the default. --- src/debuginfo/line_info.rs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/debuginfo/line_info.rs b/src/debuginfo/line_info.rs index 32b9c824ded2f..78b3d5a58f4a2 100644 --- a/src/debuginfo/line_info.rs +++ b/src/debuginfo/line_info.rs @@ -7,7 +7,7 @@ use cranelift_codegen::binemit::CodeOffset; use cranelift_codegen::MachSrcLoc; use gimli::write::{AttributeValue, FileId, FileInfo, LineProgram, LineString, LineStringTable}; use rustc_span::{ - FileName, Pos, SourceFile, SourceFileAndLine, SourceFileHash, SourceFileHashAlgorithm, + hygiene, FileName, Pos, SourceFile, SourceFileAndLine, SourceFileHash, SourceFileHashAlgorithm, }; use crate::debuginfo::emit::address_for_func; @@ -63,11 +63,8 @@ impl DebugContext { function_span: Span, span: Span, ) -> (FileId, u64, u64) { - // Based on https://github.com/rust-lang/rust/blob/e369d87b015a84653343032833d65d0545fd3f26/src/librustc_codegen_ssa/mir/mod.rs#L116-L131 - // In order to have a good line stepping behavior in debugger, we overwrite debug - // locations of macro expansions with that of the outermost expansion site (when the macro is - // annotated with `#[collapse_debuginfo]` or when `-Zdebug-macros` is provided). - let span = tcx.collapsed_debuginfo(span, function_span); + // Match behavior of `FunctionCx::adjusted_span_and_dbg_scope`. + let span = hygiene::walk_chain_collapsed(span, function_span); match tcx.sess.source_map().lookup_line(span.lo()) { Ok(SourceFileAndLine { sf: file, line }) => { let file_id = self.add_source_file(&file); From a07fd93698ad79c43b8191a164d6c666755a126b Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sun, 28 Apr 2024 15:43:50 +0000 Subject: [PATCH 009/179] Rustup to rustc 1.79.0-nightly (aed2187d5 2024-04-27) --- rust-toolchain | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-toolchain b/rust-toolchain index de340cf8c35cc..348280c2bcfd6 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2024-04-23" +channel = "nightly-2024-04-28" components = ["rust-src", "rustc-dev", "llvm-tools"] From 1e485f1bd482c7b742e2f8f07fa997f1867ad609 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sun, 28 Apr 2024 17:48:02 +0000 Subject: [PATCH 010/179] Fix rustc tests --- scripts/test_rustc_tests.sh | 2 ++ src/abi/mod.rs | 6 ++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/scripts/test_rustc_tests.sh b/scripts/test_rustc_tests.sh index 8580f4557e883..88c2950d8a24e 100755 --- a/scripts/test_rustc_tests.sh +++ b/scripts/test_rustc_tests.sh @@ -44,6 +44,7 @@ rm tests/incremental/hashes/statics.rs # same rm tests/ui/abi/mir/mir_codegen_calls_variadic.rs # requires float varargs rm tests/ui/abi/variadic-ffi.rs # requires callee side vararg support rm -r tests/run-make/c-link-to-rust-va-list-fn # requires callee side vararg support +rm tests/ui/delegation/fn-header.rs # unsized locals rm -r tests/run-pass-valgrind/unsized-locals @@ -120,6 +121,7 @@ rm -r tests/run-make/panic-abort-eh_frame # .eh_frame emitted with panic=abort # bugs in the test suite # ====================== rm tests/ui/process/nofile-limit.rs # TODO some AArch64 linking issue +rm tests/ui/attributes/unix_sigpipe/unix_sigpipe-inherit.rs # TODO some symbol not being found, but works fine when manually invoked rm tests/ui/stdio-is-blocking.rs # really slow with unoptimized libstd diff --git a/src/abi/mod.rs b/src/abi/mod.rs index 6f346af25c6dd..4bcef15ad0475 100644 --- a/src/abi/mod.rs +++ b/src/abi/mod.rs @@ -412,7 +412,7 @@ pub(crate) fn codegen_terminator_call<'tcx>( Err(instance) => Some(instance), } } - InstanceDef::DropGlue(_, None) => { + InstanceDef::DropGlue(_, None) | ty::InstanceDef::AsyncDropGlueCtorShim(_, None) => { // empty drop glue - a nop. let dest = target.expect("Non terminating drop_in_place_real???"); let ret_block = fx.get_block(dest); @@ -597,7 +597,9 @@ pub(crate) fn codegen_drop<'tcx>( let ty = drop_place.layout().ty; let drop_instance = Instance::resolve_drop_in_place(fx.tcx, ty).polymorphize(fx.tcx); - if let ty::InstanceDef::DropGlue(_, None) = drop_instance.def { + if let ty::InstanceDef::DropGlue(_, None) | ty::InstanceDef::AsyncDropGlueCtorShim(_, None) = + drop_instance.def + { // we don't actually need to drop anything } else { match ty.kind() { From 05367c5b9e4248fd1712341915ca2c77eb507bab Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sun, 28 Apr 2024 17:55:58 +0000 Subject: [PATCH 011/179] Downgrade XCode to workaround a bug in ld prime --- .github/workflows/abi-cafe.yml | 4 ++++ .github/workflows/main.yml | 8 ++++++++ 2 files changed, 12 insertions(+) diff --git a/.github/workflows/abi-cafe.yml b/.github/workflows/abi-cafe.yml index a745f2801cc4e..36ed44f9feccc 100644 --- a/.github/workflows/abi-cafe.yml +++ b/.github/workflows/abi-cafe.yml @@ -51,6 +51,10 @@ jobs: if: matrix.env.TARGET_TRIPLE == 'x86_64-pc-windows-gnu' run: rustup set default-host x86_64-pc-windows-gnu + - name: Select XCode version + if: matrix.os == 'macos-latest' + run: sudo xcode-select -s /Applications/Xcode_14.3.1.app + - name: Prepare dependencies run: ./y.sh prepare diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 14aa850ff5cb7..4ab50ab74fe8e 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -104,6 +104,10 @@ jobs: sudo apt-get update sudo apt-get install -y ${{ matrix.apt_deps }} + - name: Select XCode version + if: matrix.os == 'macos-latest' + run: sudo xcode-select -s /Applications/Xcode_14.3.1.app + - name: Prepare dependencies run: ./y.sh prepare @@ -236,6 +240,10 @@ jobs: sudo apt-get update sudo apt-get install -y gcc-mingw-w64-x86-64 + - name: Select XCode version + if: matrix.os == 'macos-latest' + run: sudo xcode-select -s /Applications/Xcode_14.3.1.app + - name: Prepare dependencies run: ./y.sh prepare From 18d2fb6e8c3d4a9cb54f629ff6c4b94a1145ea65 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 3 May 2024 10:01:25 +0000 Subject: [PATCH 012/179] Rustup to rustc 1.80.0-nightly (79734f1db 2024-05-02) --- rust-toolchain | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-toolchain b/rust-toolchain index 348280c2bcfd6..0bf9e1702c88e 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2024-04-28" +channel = "nightly-2024-05-03" components = ["rust-src", "rustc-dev", "llvm-tools"] From c41a7db24fa9c9f8ed43df518be80ba1b371fd9b Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 3 May 2024 10:15:38 +0000 Subject: [PATCH 013/179] Fix rustc test suite --- scripts/test_rustc_tests.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/test_rustc_tests.sh b/scripts/test_rustc_tests.sh index 88c2950d8a24e..2176f9d5ff314 100755 --- a/scripts/test_rustc_tests.sh +++ b/scripts/test_rustc_tests.sh @@ -88,6 +88,7 @@ rm -r tests/run-make/no-builtins-attribute # same rm tests/ui/abi/stack-protector.rs # requires stack protector support rm -r tests/run-make/emit-stack-sizes # requires support for -Z emit-stack-sizes rm -r tests/run-make/optimization-remarks-dir # remarks are LLVM specific +rm -r tests/run-make/print-to-output # requires --print relocation-models # requires asm, llvm-ir and/or llvm-bc emit support # ============================================= From 88d10687b003c97749306a64fc80d7fc89a6d959 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 3 May 2024 11:05:31 +0000 Subject: [PATCH 014/179] Remove special case in maybe_create_entry_wrapper --- src/driver/jit.rs | 15 ++++++++------- src/main_shim.rs | 2 +- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/driver/jit.rs b/src/driver/jit.rs index 929fa92596dc6..6f8be03065fb9 100644 --- a/src/driver/jit.rs +++ b/src/driver/jit.rs @@ -83,13 +83,6 @@ fn create_jit_module( ); crate::allocator::codegen(tcx, &mut jit_module, &mut cx.unwind_context); - crate::main_shim::maybe_create_entry_wrapper( - tcx, - &mut jit_module, - &mut cx.unwind_context, - true, - true, - ); (jit_module, cx) } @@ -153,6 +146,14 @@ pub(crate) fn run_jit(tcx: TyCtxt<'_>, backend_config: BackendConfig) -> ! { tcx.dcx().fatal("Inline asm is not supported in JIT mode"); } + crate::main_shim::maybe_create_entry_wrapper( + tcx, + &mut jit_module, + &mut cx.unwind_context, + true, + true, + ); + tcx.dcx().abort_if_errors(); jit_module.finalize_definitions().unwrap(); diff --git a/src/main_shim.rs b/src/main_shim.rs index 1f20ec42ddb3e..f9a729618a51a 100644 --- a/src/main_shim.rs +++ b/src/main_shim.rs @@ -29,7 +29,7 @@ pub(crate) fn maybe_create_entry_wrapper( if main_def_id.is_local() { let instance = Instance::mono(tcx, main_def_id).polymorphize(tcx); - if !is_jit && module.get_name(tcx.symbol_name(instance).name).is_none() { + if module.get_name(tcx.symbol_name(instance).name).is_none() { return; } } else if !is_primary_cgu { From b1ebc552407d26874c15b1d5167d85cd063e32f6 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 3 May 2024 11:11:39 +0000 Subject: [PATCH 015/179] Correctly handle missing CG_CLIF_JIT_ARGS --- src/config.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/config.rs b/src/config.rs index 9e92d656c76ef..12bce680d9e11 100644 --- a/src/config.rs +++ b/src/config.rs @@ -64,8 +64,13 @@ impl Default for BackendConfig { BackendConfig { codegen_mode: CodegenMode::Aot, jit_args: { - let args = std::env::var("CG_CLIF_JIT_ARGS").unwrap_or_else(|_| String::new()); - args.split(' ').map(|arg| arg.to_string()).collect() + match std::env::var("CG_CLIF_JIT_ARGS") { + Ok(args) => args.split(' ').map(|arg| arg.to_string()).collect(), + Err(std::env::VarError::NotPresent) => vec![], + Err(std::env::VarError::NotUnicode(s)) => { + panic!("CG_CLIF_JIT_ARGS not unicode: {:?}", s); + } + } }, enable_verifier: cfg!(debug_assertions) || bool_env_var("CG_CLIF_ENABLE_VERIFIER"), disable_incr_cache: bool_env_var("CG_CLIF_DISABLE_INCR_CACHE"), From 4d6ac059e547b3ff95e4c18ff933207aec8900b5 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 3 May 2024 11:11:58 +0000 Subject: [PATCH 016/179] Add missing arg for the jit.std_example test --- build_system/tests.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build_system/tests.rs b/build_system/tests.rs index 76104901474c2..278f334796a9b 100644 --- a/build_system/tests.rs +++ b/build_system/tests.rs @@ -77,7 +77,7 @@ const BASE_SYSROOT_SUITE: &[TestCase] = &[ ), TestCase::build_lib("build.alloc_system", "example/alloc_system.rs", "lib"), TestCase::build_bin_and_run("aot.alloc_example", "example/alloc_example.rs", &[]), - TestCase::jit_bin("jit.std_example", "example/std_example.rs", ""), + TestCase::jit_bin("jit.std_example", "example/std_example.rs", "arg"), TestCase::build_bin_and_run("aot.std_example", "example/std_example.rs", &["arg"]), TestCase::build_bin_and_run("aot.dst_field_align", "example/dst-field-align.rs", &[]), TestCase::build_bin_and_run( From 8f0d35769de3b54a5fd95ac61ce6a3ec4144f5f7 Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Sat, 4 May 2024 05:21:37 +0200 Subject: [PATCH 017/179] Refactor Apple `target_abi` This was bundled together with `Arch`, which complicated a few code paths and meant we had to do more string matching than necessary. --- .../rustc_target/src/spec/base/apple/mod.rs | 83 ++++++++++--------- .../src/spec/targets/aarch64_apple_darwin.rs | 4 +- .../src/spec/targets/aarch64_apple_ios.rs | 4 +- .../spec/targets/aarch64_apple_ios_macabi.rs | 6 +- .../src/spec/targets/aarch64_apple_ios_sim.rs | 6 +- .../src/spec/targets/aarch64_apple_tvos.rs | 4 +- .../spec/targets/aarch64_apple_tvos_sim.rs | 6 +- .../spec/targets/aarch64_apple_visionos.rs | 4 +- .../targets/aarch64_apple_visionos_sim.rs | 6 +- .../src/spec/targets/aarch64_apple_watchos.rs | 4 +- .../spec/targets/aarch64_apple_watchos_sim.rs | 6 +- .../spec/targets/arm64_32_apple_watchos.rs | 4 +- .../src/spec/targets/arm64e_apple_darwin.rs | 4 +- .../src/spec/targets/arm64e_apple_ios.rs | 4 +- .../src/spec/targets/armv7k_apple_watchos.rs | 4 +- .../src/spec/targets/armv7s_apple_ios.rs | 4 +- .../src/spec/targets/i386_apple_ios.rs | 7 +- .../src/spec/targets/i686_apple_darwin.rs | 4 +- .../src/spec/targets/x86_64_apple_darwin.rs | 4 +- .../src/spec/targets/x86_64_apple_ios.rs | 6 +- .../spec/targets/x86_64_apple_ios_macabi.rs | 6 +- .../src/spec/targets/x86_64_apple_tvos.rs | 7 +- .../spec/targets/x86_64_apple_watchos_sim.rs | 9 +- .../src/spec/targets/x86_64h_apple_darwin.rs | 4 +- 24 files changed, 103 insertions(+), 97 deletions(-) diff --git a/compiler/rustc_target/src/spec/base/apple/mod.rs b/compiler/rustc_target/src/spec/base/apple/mod.rs index d667bad44e3b7..c5b2065080b20 100644 --- a/compiler/rustc_target/src/spec/base/apple/mod.rs +++ b/compiler/rustc_target/src/spec/base/apple/mod.rs @@ -17,14 +17,9 @@ pub enum Arch { Arm64e, Arm64_32, I386, - I386_sim, I686, X86_64, X86_64h, - X86_64_sim, - X86_64_macabi, - Arm64_macabi, - Arm64_sim, } impl Arch { @@ -32,12 +27,12 @@ impl Arch { match self { Armv7k => "armv7k", Armv7s => "armv7s", - Arm64 | Arm64_macabi | Arm64_sim => "arm64", + Arm64 => "arm64", Arm64e => "arm64e", Arm64_32 => "arm64_32", - I386 | I386_sim => "i386", + I386 => "i386", I686 => "i686", - X86_64 | X86_64_sim | X86_64_macabi => "x86_64", + X86_64 => "x86_64", X86_64h => "x86_64h", } } @@ -45,61 +40,70 @@ impl Arch { pub fn target_arch(self) -> Cow<'static, str> { Cow::Borrowed(match self { Armv7k | Armv7s => "arm", - Arm64 | Arm64e | Arm64_32 | Arm64_macabi | Arm64_sim => "aarch64", - I386 | I386_sim | I686 => "x86", - X86_64 | X86_64_sim | X86_64_macabi | X86_64h => "x86_64", + Arm64 | Arm64e | Arm64_32 => "aarch64", + I386 | I686 => "x86", + X86_64 | X86_64h => "x86_64", }) } - fn target_abi(self) -> &'static str { - match self { - Armv7k | Armv7s | Arm64 | Arm64e | Arm64_32 | I386 | I686 | X86_64 | X86_64h => "", - X86_64_macabi | Arm64_macabi => "macabi", - I386_sim | Arm64_sim | X86_64_sim => "sim", - } - } - - fn target_cpu(self) -> &'static str { + fn target_cpu(self, abi: TargetAbi) -> &'static str { match self { Armv7k => "cortex-a8", Armv7s => "swift", // iOS 10 is only supported on iPhone 5 or higher. - Arm64 => "apple-a7", + Arm64 => match abi { + TargetAbi::Normal => "apple-a7", + TargetAbi::Simulator => "apple-a12", + TargetAbi::MacCatalyst => "apple-a12", + }, Arm64e => "apple-a12", Arm64_32 => "apple-s4", // Only macOS 10.12+ is supported, which means // all x86_64/x86 CPUs must be running at least penryn // https://github.com/llvm/llvm-project/blob/01f924d0e37a5deae51df0d77e10a15b63aa0c0f/clang/lib/Driver/ToolChains/Arch/X86.cpp#L79-L82 - I386 | I386_sim | I686 => "penryn", - X86_64 | X86_64_sim => "penryn", - X86_64_macabi => "penryn", + I386 | I686 => "penryn", + X86_64 => "penryn", // Note: `core-avx2` is slightly more advanced than `x86_64h`, see // comments (and disabled features) in `x86_64h_apple_darwin` for // details. It is a higher baseline then `penryn` however. X86_64h => "core-avx2", - Arm64_macabi => "apple-a12", - Arm64_sim => "apple-a12", } } fn stack_probes(self) -> StackProbeType { match self { Armv7k | Armv7s => StackProbeType::None, - Arm64 | Arm64e | Arm64_32 | I386 | I386_sim | I686 | X86_64 | X86_64h | X86_64_sim - | X86_64_macabi | Arm64_macabi | Arm64_sim => StackProbeType::Inline, + Arm64 | Arm64e | Arm64_32 | I386 | I686 | X86_64 | X86_64h => StackProbeType::Inline, } } } -fn pre_link_args(os: &'static str, arch: Arch, abi: &'static str) -> LinkArgs { +#[derive(Copy, Clone, PartialEq)] +pub enum TargetAbi { + Normal, + Simulator, + MacCatalyst, +} + +impl TargetAbi { + fn target_abi(self) -> &'static str { + match self { + Self::Normal => "", + Self::MacCatalyst => "macabi", + Self::Simulator => "sim", + } + } +} + +fn pre_link_args(os: &'static str, arch: Arch, abi: TargetAbi) -> LinkArgs { let platform_name: StaticCow = match abi { - "sim" => format!("{os}-simulator").into(), - "macabi" => "mac-catalyst".into(), - _ => os.into(), + TargetAbi::Normal => os.into(), + TargetAbi::Simulator => format!("{os}-simulator").into(), + TargetAbi::MacCatalyst => "mac-catalyst".into(), }; let min_version: StaticCow = { let (major, minor) = match os { - "ios" => ios_deployment_target(arch, abi), + "ios" => ios_deployment_target(arch, abi.target_abi()), "tvos" => tvos_deployment_target(), "watchos" => watchos_deployment_target(), "visionos" => visionos_deployment_target(), @@ -119,7 +123,7 @@ fn pre_link_args(os: &'static str, arch: Arch, abi: &'static str) -> LinkArgs { LinkerFlavor::Darwin(Cc::No, Lld::No), [platform_name, min_version, sdk_version].into_iter(), ); - if abi != "macabi" { + if abi != TargetAbi::MacCatalyst { add_link_args( &mut args, LinkerFlavor::Darwin(Cc::Yes, Lld::No), @@ -136,13 +140,11 @@ fn pre_link_args(os: &'static str, arch: Arch, abi: &'static str) -> LinkArgs { args } -pub fn opts(os: &'static str, arch: Arch) -> TargetOptions { - let abi = arch.target_abi(); - +pub fn opts(os: &'static str, arch: Arch, abi: TargetAbi) -> TargetOptions { TargetOptions { - abi: abi.into(), + abi: abi.target_abi().into(), os: os.into(), - cpu: arch.target_cpu().into(), + cpu: arch.target_cpu(abi).into(), link_env_remove: link_env_remove(os), vendor: "apple".into(), linker_flavor: LinkerFlavor::Darwin(Cc::Yes, Lld::No), @@ -263,8 +265,7 @@ fn from_set_deployment_target(var_name: &str) -> Option<(u32, u32)> { fn macos_default_deployment_target(arch: Arch) -> (u32, u32) { match arch { - // Note: Arm64_sim is not included since macOS has no simulator. - Arm64 | Arm64e | Arm64_macabi => (11, 0), + Arm64 | Arm64e => (11, 0), _ => (10, 12), } } diff --git a/compiler/rustc_target/src/spec/targets/aarch64_apple_darwin.rs b/compiler/rustc_target/src/spec/targets/aarch64_apple_darwin.rs index eff1617a4bf0b..14f1892e65643 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_apple_darwin.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_apple_darwin.rs @@ -1,9 +1,9 @@ -use crate::spec::base::apple::{macos_llvm_target, opts, Arch}; +use crate::spec::base::apple::{macos_llvm_target, opts, Arch, TargetAbi}; use crate::spec::{FramePointer, SanitizerSet, Target, TargetOptions}; pub fn target() -> Target { let arch = Arch::Arm64; - let mut base = opts("macos", arch); + let mut base = opts("macos", arch, TargetAbi::Normal); base.cpu = "apple-m1".into(); base.max_atomic_width = Some(128); diff --git a/compiler/rustc_target/src/spec/targets/aarch64_apple_ios.rs b/compiler/rustc_target/src/spec/targets/aarch64_apple_ios.rs index e9dddc7fae79a..30ffd399ddfe8 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_apple_ios.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_apple_ios.rs @@ -1,9 +1,9 @@ -use crate::spec::base::apple::{ios_llvm_target, opts, Arch}; +use crate::spec::base::apple::{ios_llvm_target, opts, Arch, TargetAbi}; use crate::spec::{FramePointer, SanitizerSet, Target, TargetOptions}; pub fn target() -> Target { let arch = Arch::Arm64; - let mut base = opts("ios", arch); + let mut base = opts("ios", arch, TargetAbi::Normal); base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::THREAD; Target { diff --git a/compiler/rustc_target/src/spec/targets/aarch64_apple_ios_macabi.rs b/compiler/rustc_target/src/spec/targets/aarch64_apple_ios_macabi.rs index 2d89b6083f7ec..f86fbda99796c 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_apple_ios_macabi.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_apple_ios_macabi.rs @@ -1,9 +1,9 @@ -use crate::spec::base::apple::{mac_catalyst_llvm_target, opts, Arch}; +use crate::spec::base::apple::{mac_catalyst_llvm_target, opts, Arch, TargetAbi}; use crate::spec::{FramePointer, SanitizerSet, Target, TargetOptions}; pub fn target() -> Target { - let arch = Arch::Arm64_macabi; - let mut base = opts("ios", arch); + let arch = Arch::Arm64; + let mut base = opts("ios", arch, TargetAbi::MacCatalyst); base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::LEAK | SanitizerSet::THREAD; Target { diff --git a/compiler/rustc_target/src/spec/targets/aarch64_apple_ios_sim.rs b/compiler/rustc_target/src/spec/targets/aarch64_apple_ios_sim.rs index fb4ae02325082..7edaeb5d04149 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_apple_ios_sim.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_apple_ios_sim.rs @@ -1,9 +1,9 @@ -use crate::spec::base::apple::{ios_sim_llvm_target, opts, Arch}; +use crate::spec::base::apple::{ios_sim_llvm_target, opts, Arch, TargetAbi}; use crate::spec::{FramePointer, SanitizerSet, Target, TargetOptions}; pub fn target() -> Target { - let arch = Arch::Arm64_sim; - let mut base = opts("ios", arch); + let arch = Arch::Arm64; + let mut base = opts("ios", arch, TargetAbi::Simulator); base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::THREAD; Target { diff --git a/compiler/rustc_target/src/spec/targets/aarch64_apple_tvos.rs b/compiler/rustc_target/src/spec/targets/aarch64_apple_tvos.rs index 0deadbdb02810..f77e9a989e4bb 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_apple_tvos.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_apple_tvos.rs @@ -1,4 +1,4 @@ -use crate::spec::base::apple::{opts, tvos_llvm_target, Arch}; +use crate::spec::base::apple::{opts, tvos_llvm_target, Arch, TargetAbi}; use crate::spec::{FramePointer, Target, TargetOptions}; pub fn target() -> Target { @@ -18,7 +18,7 @@ pub fn target() -> Target { features: "+neon,+fp-armv8,+apple-a7".into(), max_atomic_width: Some(128), frame_pointer: FramePointer::NonLeaf, - ..opts("tvos", arch) + ..opts("tvos", arch, TargetAbi::Normal) }, } } diff --git a/compiler/rustc_target/src/spec/targets/aarch64_apple_tvos_sim.rs b/compiler/rustc_target/src/spec/targets/aarch64_apple_tvos_sim.rs index f666c59252429..20200900451b5 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_apple_tvos_sim.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_apple_tvos_sim.rs @@ -1,8 +1,8 @@ -use crate::spec::base::apple::{opts, tvos_sim_llvm_target, Arch}; +use crate::spec::base::apple::{opts, tvos_sim_llvm_target, Arch, TargetAbi}; use crate::spec::{FramePointer, Target, TargetOptions}; pub fn target() -> Target { - let arch = Arch::Arm64_sim; + let arch = Arch::Arm64; Target { llvm_target: tvos_sim_llvm_target(arch).into(), metadata: crate::spec::TargetMetadata { @@ -18,7 +18,7 @@ pub fn target() -> Target { features: "+neon,+fp-armv8,+apple-a7".into(), max_atomic_width: Some(128), frame_pointer: FramePointer::NonLeaf, - ..opts("tvos", arch) + ..opts("tvos", arch, TargetAbi::Simulator) }, } } diff --git a/compiler/rustc_target/src/spec/targets/aarch64_apple_visionos.rs b/compiler/rustc_target/src/spec/targets/aarch64_apple_visionos.rs index 7afe224163bcc..441f7c58a7040 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_apple_visionos.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_apple_visionos.rs @@ -1,9 +1,9 @@ -use crate::spec::base::apple::{opts, visionos_llvm_target, Arch}; +use crate::spec::base::apple::{opts, visionos_llvm_target, Arch, TargetAbi}; use crate::spec::{FramePointer, SanitizerSet, Target, TargetOptions}; pub fn target() -> Target { let arch = Arch::Arm64; - let mut base = opts("visionos", arch); + let mut base = opts("visionos", arch, TargetAbi::Normal); base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::THREAD; Target { diff --git a/compiler/rustc_target/src/spec/targets/aarch64_apple_visionos_sim.rs b/compiler/rustc_target/src/spec/targets/aarch64_apple_visionos_sim.rs index 422b2d7b922fc..8c43de0e0db34 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_apple_visionos_sim.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_apple_visionos_sim.rs @@ -1,9 +1,9 @@ -use crate::spec::base::apple::{opts, visionos_sim_llvm_target, Arch}; +use crate::spec::base::apple::{opts, visionos_sim_llvm_target, Arch, TargetAbi}; use crate::spec::{FramePointer, SanitizerSet, Target, TargetOptions}; pub fn target() -> Target { - let arch = Arch::Arm64_sim; - let mut base = opts("visionos", arch); + let arch = Arch::Arm64; + let mut base = opts("visionos", arch, TargetAbi::Simulator); base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::THREAD; Target { diff --git a/compiler/rustc_target/src/spec/targets/aarch64_apple_watchos.rs b/compiler/rustc_target/src/spec/targets/aarch64_apple_watchos.rs index 5001444e1fae6..c0ab2a51f3da4 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_apple_watchos.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_apple_watchos.rs @@ -1,8 +1,8 @@ -use crate::spec::base::apple::{opts, Arch}; +use crate::spec::base::apple::{opts, Arch, TargetAbi}; use crate::spec::{Target, TargetOptions}; pub fn target() -> Target { - let base = opts("watchos", Arch::Arm64); + let base = opts("watchos", Arch::Arm64, TargetAbi::Normal); Target { llvm_target: "aarch64-apple-watchos".into(), metadata: crate::spec::TargetMetadata { diff --git a/compiler/rustc_target/src/spec/targets/aarch64_apple_watchos_sim.rs b/compiler/rustc_target/src/spec/targets/aarch64_apple_watchos_sim.rs index 5728f55baba0f..f24aa0fc8d1ce 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_apple_watchos_sim.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_apple_watchos_sim.rs @@ -1,8 +1,8 @@ -use crate::spec::base::apple::{opts, watchos_sim_llvm_target, Arch}; +use crate::spec::base::apple::{opts, watchos_sim_llvm_target, Arch, TargetAbi}; use crate::spec::{FramePointer, Target, TargetOptions}; pub fn target() -> Target { - let arch = Arch::Arm64_sim; + let arch = Arch::Arm64; Target { // Clang automatically chooses a more specific target based on // WATCHOS_DEPLOYMENT_TARGET. @@ -22,7 +22,7 @@ pub fn target() -> Target { features: "+neon,+fp-armv8,+apple-a7".into(), max_atomic_width: Some(128), frame_pointer: FramePointer::NonLeaf, - ..opts("watchos", arch) + ..opts("watchos", arch, TargetAbi::Simulator) }, } } diff --git a/compiler/rustc_target/src/spec/targets/arm64_32_apple_watchos.rs b/compiler/rustc_target/src/spec/targets/arm64_32_apple_watchos.rs index f842a834c05bf..4c939fda282b5 100644 --- a/compiler/rustc_target/src/spec/targets/arm64_32_apple_watchos.rs +++ b/compiler/rustc_target/src/spec/targets/arm64_32_apple_watchos.rs @@ -1,9 +1,9 @@ -use crate::spec::base::apple::{opts, watchos_llvm_target, Arch}; +use crate::spec::base::apple::{opts, watchos_llvm_target, Arch, TargetAbi}; use crate::spec::{Target, TargetOptions}; pub fn target() -> Target { let arch = Arch::Arm64_32; - let base = opts("watchos", arch); + let base = opts("watchos", arch, TargetAbi::Normal); Target { llvm_target: watchos_llvm_target(arch).into(), metadata: crate::spec::TargetMetadata { diff --git a/compiler/rustc_target/src/spec/targets/arm64e_apple_darwin.rs b/compiler/rustc_target/src/spec/targets/arm64e_apple_darwin.rs index 11c56cf411c37..9381c608181cb 100644 --- a/compiler/rustc_target/src/spec/targets/arm64e_apple_darwin.rs +++ b/compiler/rustc_target/src/spec/targets/arm64e_apple_darwin.rs @@ -1,9 +1,9 @@ -use crate::spec::base::apple::{macos_llvm_target, opts, Arch}; +use crate::spec::base::apple::{macos_llvm_target, opts, Arch, TargetAbi}; use crate::spec::{FramePointer, SanitizerSet, Target, TargetOptions}; pub fn target() -> Target { let arch = Arch::Arm64e; - let mut base = opts("macos", arch); + let mut base = opts("macos", arch, TargetAbi::Normal); base.cpu = "apple-m1".into(); base.max_atomic_width = Some(128); diff --git a/compiler/rustc_target/src/spec/targets/arm64e_apple_ios.rs b/compiler/rustc_target/src/spec/targets/arm64e_apple_ios.rs index fd8f0ddcb4ddd..3b7646b0f3e72 100644 --- a/compiler/rustc_target/src/spec/targets/arm64e_apple_ios.rs +++ b/compiler/rustc_target/src/spec/targets/arm64e_apple_ios.rs @@ -1,9 +1,9 @@ -use crate::spec::base::apple::{ios_llvm_target, opts, Arch}; +use crate::spec::base::apple::{ios_llvm_target, opts, Arch, TargetAbi}; use crate::spec::{FramePointer, SanitizerSet, Target, TargetOptions}; pub fn target() -> Target { let arch = Arch::Arm64e; - let mut base = opts("ios", arch); + let mut base = opts("ios", arch, TargetAbi::Normal); base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::THREAD; Target { diff --git a/compiler/rustc_target/src/spec/targets/armv7k_apple_watchos.rs b/compiler/rustc_target/src/spec/targets/armv7k_apple_watchos.rs index 42ad9e0a35e6a..5c675c22ef511 100644 --- a/compiler/rustc_target/src/spec/targets/armv7k_apple_watchos.rs +++ b/compiler/rustc_target/src/spec/targets/armv7k_apple_watchos.rs @@ -1,4 +1,4 @@ -use crate::spec::base::apple::{opts, Arch}; +use crate::spec::base::apple::{opts, Arch, TargetAbi}; use crate::spec::{Target, TargetOptions}; pub fn target() -> Target { @@ -19,7 +19,7 @@ pub fn target() -> Target { max_atomic_width: Some(64), dynamic_linking: false, position_independent_executables: true, - ..opts("watchos", arch) + ..opts("watchos", arch, TargetAbi::Normal) }, } } diff --git a/compiler/rustc_target/src/spec/targets/armv7s_apple_ios.rs b/compiler/rustc_target/src/spec/targets/armv7s_apple_ios.rs index 40e5fc3f20dab..4dd475e3a82da 100644 --- a/compiler/rustc_target/src/spec/targets/armv7s_apple_ios.rs +++ b/compiler/rustc_target/src/spec/targets/armv7s_apple_ios.rs @@ -1,4 +1,4 @@ -use crate::spec::base::apple::{ios_llvm_target, opts, Arch}; +use crate::spec::base::apple::{ios_llvm_target, opts, Arch, TargetAbi}; use crate::spec::{Target, TargetOptions}; pub fn target() -> Target { @@ -17,7 +17,7 @@ pub fn target() -> Target { options: TargetOptions { features: "+v7,+vfp4,+neon".into(), max_atomic_width: Some(64), - ..opts("ios", arch) + ..opts("ios", arch, TargetAbi::Normal) }, } } diff --git a/compiler/rustc_target/src/spec/targets/i386_apple_ios.rs b/compiler/rustc_target/src/spec/targets/i386_apple_ios.rs index afa92ba99c61f..c03a0974bc1cb 100644 --- a/compiler/rustc_target/src/spec/targets/i386_apple_ios.rs +++ b/compiler/rustc_target/src/spec/targets/i386_apple_ios.rs @@ -1,10 +1,11 @@ -use crate::spec::base::apple::{ios_sim_llvm_target, opts, Arch}; +use crate::spec::base::apple::{ios_sim_llvm_target, opts, Arch, TargetAbi}; use crate::spec::{Target, TargetOptions}; pub fn target() -> Target { + let arch = Arch::I386; // i386-apple-ios is a simulator target, even though it isn't declared // that way in the target name like the other ones... - let arch = Arch::I386_sim; + let abi = TargetAbi::Simulator; Target { // Clang automatically chooses a more specific target based on // IPHONEOS_DEPLOYMENT_TARGET. @@ -22,6 +23,6 @@ pub fn target() -> Target { i128:128-f64:32:64-f80:128-n8:16:32-S128" .into(), arch: arch.target_arch(), - options: TargetOptions { max_atomic_width: Some(64), ..opts("ios", arch) }, + options: TargetOptions { max_atomic_width: Some(64), ..opts("ios", arch, abi) }, } } diff --git a/compiler/rustc_target/src/spec/targets/i686_apple_darwin.rs b/compiler/rustc_target/src/spec/targets/i686_apple_darwin.rs index 34a447a97efb8..aea6a1ac4ecea 100644 --- a/compiler/rustc_target/src/spec/targets/i686_apple_darwin.rs +++ b/compiler/rustc_target/src/spec/targets/i686_apple_darwin.rs @@ -1,10 +1,10 @@ -use crate::spec::base::apple::{macos_llvm_target, opts, Arch}; +use crate::spec::base::apple::{macos_llvm_target, opts, Arch, TargetAbi}; use crate::spec::{Cc, FramePointer, LinkerFlavor, Lld, Target, TargetOptions}; pub fn target() -> Target { // ld64 only understands i386 and not i686 let arch = Arch::I386; - let mut base = opts("macos", arch); + let mut base = opts("macos", arch, TargetAbi::Normal); base.max_atomic_width = Some(64); base.add_pre_link_args(LinkerFlavor::Darwin(Cc::Yes, Lld::No), &["-m32"]); base.frame_pointer = FramePointer::Always; diff --git a/compiler/rustc_target/src/spec/targets/x86_64_apple_darwin.rs b/compiler/rustc_target/src/spec/targets/x86_64_apple_darwin.rs index 1716c590aa503..21acd750df2dc 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_apple_darwin.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_apple_darwin.rs @@ -1,10 +1,10 @@ -use crate::spec::base::apple::{macos_llvm_target, opts, Arch}; +use crate::spec::base::apple::{macos_llvm_target, opts, Arch, TargetAbi}; use crate::spec::{Cc, FramePointer, LinkerFlavor, Lld, SanitizerSet}; use crate::spec::{Target, TargetOptions}; pub fn target() -> Target { let arch = Arch::X86_64; - let mut base = opts("macos", arch); + let mut base = opts("macos", arch, TargetAbi::Normal); base.max_atomic_width = Some(128); // penryn+ supports cmpxchg16b base.frame_pointer = FramePointer::Always; base.add_pre_link_args(LinkerFlavor::Darwin(Cc::Yes, Lld::No), &["-m64"]); diff --git a/compiler/rustc_target/src/spec/targets/x86_64_apple_ios.rs b/compiler/rustc_target/src/spec/targets/x86_64_apple_ios.rs index fa22c2907d271..ec61b7967646e 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_apple_ios.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_apple_ios.rs @@ -1,11 +1,11 @@ -use crate::spec::base::apple::{ios_sim_llvm_target, opts, Arch}; +use crate::spec::base::apple::{ios_sim_llvm_target, opts, Arch, TargetAbi}; use crate::spec::{SanitizerSet, Target, TargetOptions}; pub fn target() -> Target { + let arch = Arch::X86_64; // x86_64-apple-ios is a simulator target, even though it isn't declared // that way in the target name like the other ones... - let arch = Arch::X86_64_sim; - let mut base = opts("ios", arch); + let mut base = opts("ios", arch, TargetAbi::Simulator); base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::THREAD; Target { diff --git a/compiler/rustc_target/src/spec/targets/x86_64_apple_ios_macabi.rs b/compiler/rustc_target/src/spec/targets/x86_64_apple_ios_macabi.rs index 9b479de81652c..bd967ee972b32 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_apple_ios_macabi.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_apple_ios_macabi.rs @@ -1,9 +1,9 @@ -use crate::spec::base::apple::{mac_catalyst_llvm_target, opts, Arch}; +use crate::spec::base::apple::{mac_catalyst_llvm_target, opts, Arch, TargetAbi}; use crate::spec::{SanitizerSet, Target, TargetOptions}; pub fn target() -> Target { - let arch = Arch::X86_64_macabi; - let mut base = opts("ios", arch); + let arch = Arch::X86_64; + let mut base = opts("ios", arch, TargetAbi::MacCatalyst); base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::LEAK | SanitizerSet::THREAD; Target { diff --git a/compiler/rustc_target/src/spec/targets/x86_64_apple_tvos.rs b/compiler/rustc_target/src/spec/targets/x86_64_apple_tvos.rs index f62d31c51662b..55b2e1afcd392 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_apple_tvos.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_apple_tvos.rs @@ -1,10 +1,11 @@ -use crate::spec::base::apple::{opts, tvos_sim_llvm_target, Arch}; +use crate::spec::base::apple::{opts, tvos_sim_llvm_target, Arch, TargetAbi}; use crate::spec::{Target, TargetOptions}; pub fn target() -> Target { + let arch = Arch::X86_64; // x86_64-apple-tvos is a simulator target, even though it isn't declared // that way in the target name like the other ones... - let arch = Arch::X86_64_sim; + let abi = TargetAbi::Simulator; Target { llvm_target: tvos_sim_llvm_target(arch).into(), metadata: crate::spec::TargetMetadata { @@ -17,6 +18,6 @@ pub fn target() -> Target { data_layout: "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128".into(), arch: arch.target_arch(), - options: TargetOptions { max_atomic_width: Some(128), ..opts("tvos", arch) }, + options: TargetOptions { max_atomic_width: Some(128), ..opts("tvos", arch, abi) }, } } diff --git a/compiler/rustc_target/src/spec/targets/x86_64_apple_watchos_sim.rs b/compiler/rustc_target/src/spec/targets/x86_64_apple_watchos_sim.rs index 371aab8b50805..a783eff15b261 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_apple_watchos_sim.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_apple_watchos_sim.rs @@ -1,8 +1,8 @@ -use crate::spec::base::apple::{opts, watchos_sim_llvm_target, Arch}; +use crate::spec::base::apple::{opts, watchos_sim_llvm_target, Arch, TargetAbi}; use crate::spec::{Target, TargetOptions}; pub fn target() -> Target { - let arch = Arch::X86_64_sim; + let arch = Arch::X86_64; Target { llvm_target: watchos_sim_llvm_target(arch).into(), metadata: crate::spec::TargetMetadata { @@ -15,6 +15,9 @@ pub fn target() -> Target { data_layout: "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128".into(), arch: arch.target_arch(), - options: TargetOptions { max_atomic_width: Some(128), ..opts("watchos", arch) }, + options: TargetOptions { + max_atomic_width: Some(128), + ..opts("watchos", arch, TargetAbi::Simulator) + }, } } diff --git a/compiler/rustc_target/src/spec/targets/x86_64h_apple_darwin.rs b/compiler/rustc_target/src/spec/targets/x86_64h_apple_darwin.rs index b17e21e5d1206..fe6cbca32c748 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64h_apple_darwin.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64h_apple_darwin.rs @@ -1,10 +1,10 @@ -use crate::spec::base::apple::{macos_llvm_target, opts, Arch}; +use crate::spec::base::apple::{macos_llvm_target, opts, Arch, TargetAbi}; use crate::spec::{Cc, FramePointer, LinkerFlavor, Lld, SanitizerSet}; use crate::spec::{Target, TargetOptions}; pub fn target() -> Target { let arch = Arch::X86_64h; - let mut base = opts("macos", arch); + let mut base = opts("macos", arch, TargetAbi::Normal); base.max_atomic_width = Some(128); base.frame_pointer = FramePointer::Always; base.add_pre_link_args(LinkerFlavor::Darwin(Cc::Yes, Lld::No), &["-m64"]); From 1d45f47d24e43546b2a3e71fea80660c86343f41 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Sun, 5 May 2024 19:03:38 +0000 Subject: [PATCH 018/179] std::rand: adding solaris/illumos for getrandom support. To help solarish support for miri https://rust-lang/miri/issues/3567 --- library/std/src/sys/pal/unix/rand.rs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/library/std/src/sys/pal/unix/rand.rs b/library/std/src/sys/pal/unix/rand.rs index d8f227b4ef444..e6df109a6b8f2 100644 --- a/library/std/src/sys/pal/unix/rand.rs +++ b/library/std/src/sys/pal/unix/rand.rs @@ -59,7 +59,14 @@ mod imp { unsafe { getrandom(buf.as_mut_ptr().cast(), buf.len(), libc::GRND_NONBLOCK) } } - #[cfg(any(target_os = "espidf", target_os = "horizon", target_os = "freebsd", netbsd10))] + #[cfg(any( + target_os = "espidf", + target_os = "horizon", + target_os = "freebsd", + netbsd10, + target_os = "illumos", + target_os = "solaris" + ))] fn getrandom(buf: &mut [u8]) -> libc::ssize_t { unsafe { libc::getrandom(buf.as_mut_ptr().cast(), buf.len(), 0) } } @@ -83,6 +90,8 @@ mod imp { target_os = "horizon", target_os = "freebsd", target_os = "dragonfly", + target_os = "solaris", + target_os = "illumos", netbsd10 )))] fn getrandom_fill_bytes(_buf: &mut [u8]) -> bool { @@ -96,6 +105,8 @@ mod imp { target_os = "horizon", target_os = "freebsd", target_os = "dragonfly", + target_os = "solaris", + target_os = "illumos", netbsd10 ))] fn getrandom_fill_bytes(v: &mut [u8]) -> bool { From 617c3f63601102be629f42941d8d1e8e9f2dcc71 Mon Sep 17 00:00:00 2001 From: beetrees Date: Mon, 6 May 2024 13:27:40 +0100 Subject: [PATCH 019/179] Refactor float `Primitive`s to a separate `Float` type --- src/common.rs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/common.rs b/src/common.rs index 2a24d6150bd6e..21d0cd2d30f2a 100644 --- a/src/common.rs +++ b/src/common.rs @@ -7,7 +7,7 @@ use rustc_middle::ty::layout::{ use rustc_middle::ty::TypeFoldable; use rustc_span::source_map::Spanned; use rustc_target::abi::call::FnAbi; -use rustc_target::abi::{Integer, Primitive}; +use rustc_target::abi::{Float, Integer, Primitive}; use rustc_target::spec::{HasTargetSpec, Target}; use crate::constant::ConstantCx; @@ -32,10 +32,12 @@ pub(crate) fn scalar_to_clif_type(tcx: TyCtxt<'_>, scalar: Scalar) -> Type { Integer::I64 => types::I64, Integer::I128 => types::I128, }, - Primitive::F16 => unimplemented!("f16_f128"), - Primitive::F32 => types::F32, - Primitive::F64 => types::F64, - Primitive::F128 => unimplemented!("f16_f128"), + Primitive::Float(float) => match float { + Float::F16 => unimplemented!("f16_f128"), + Float::F32 => types::F32, + Float::F64 => types::F64, + Float::F128 => unimplemented!("f16_f128"), + }, // FIXME(erikdesjardins): handle non-default addrspace ptr sizes Primitive::Pointer(_) => pointer_ty(tcx), } From 2af0871297634b918ccb52b95f7de875237fa092 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 6 May 2024 14:32:39 -0400 Subject: [PATCH 020/179] Update ena to 0.14.3 --- Cargo.lock | 6 +++--- compiler/rustc_data_structures/Cargo.toml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 84f7d21239a29..f103acda0f283 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1218,9 +1218,9 @@ dependencies = [ [[package]] name = "ena" -version = "0.14.2" +version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c533630cf40e9caa44bd91aadc88a75d75a4c3a12b4cfde353cbed41daa1e1f1" +checksum = "3d248bdd43ce613d87415282f69b9bb99d947d290b10962dd6c56233312c2ad5" dependencies = [ "log", ] @@ -2219,7 +2219,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c2a198fb6b0eada2a8df47933734e6d35d350665a33a3593d7164fa52c75c19" dependencies = [ "cfg-if", - "windows-targets 0.48.5", + "windows-targets 0.52.4", ] [[package]] diff --git a/compiler/rustc_data_structures/Cargo.toml b/compiler/rustc_data_structures/Cargo.toml index 80b6e72e49ba1..2b61e17efa28d 100644 --- a/compiler/rustc_data_structures/Cargo.toml +++ b/compiler/rustc_data_structures/Cargo.toml @@ -9,7 +9,7 @@ arrayvec = { version = "0.7", default-features = false } bitflags = "2.4.1" either = "1.0" elsa = "=1.7.1" -ena = "0.14.2" +ena = "0.14.3" indexmap = { version = "2.0.0" } jobserver_crate = { version = "0.1.28", package = "jobserver" } libc = "0.2" From de9b3b788f60f94ded75f4a1d199192d58e44c8c Mon Sep 17 00:00:00 2001 From: Brian Smith Date: Mon, 6 May 2024 15:25:37 -0700 Subject: [PATCH 021/179] Enable profiler for armv7-unknown-linux-gnueabihf. --- src/ci/docker/host-x86_64/dist-armv7-linux/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ci/docker/host-x86_64/dist-armv7-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-armv7-linux/Dockerfile index dab0667ed55c4..e718437aaaa39 100644 --- a/src/ci/docker/host-x86_64/dist-armv7-linux/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-armv7-linux/Dockerfile @@ -25,5 +25,5 @@ ENV CC_armv7_unknown_linux_gnueabihf=armv7-unknown-linux-gnueabihf-gcc \ ENV HOSTS=armv7-unknown-linux-gnueabihf -ENV RUST_CONFIGURE_ARGS --enable-full-tools --disable-docs +ENV RUST_CONFIGURE_ARGS --enable-full-tools --enable-profiler --disable-docs ENV SCRIPT python3 ../x.py dist --host $HOSTS --target $HOSTS From 1adfffd07f8704ca722f3897719ace079944b0c5 Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Wed, 8 May 2024 15:00:09 +0300 Subject: [PATCH 022/179] use key-value format in stage0 file Currently, we are working on the python removal task on bootstrap. Which means we have to extract some data from the stage0 file using shell scripts. However, parsing values from the stage0.json file is painful because shell scripts don't have a built-in way to parse json files. This change simplifies the stage0 file format to key-value pairs, which makes it easily readable from any environment. Signed-off-by: onur-ozkan --- src/stage0 | 447 ++++++++++++++++++++++++++++++ src/tools/bump-stage0/src/main.rs | 148 +++++++--- 2 files changed, 552 insertions(+), 43 deletions(-) create mode 100644 src/stage0 diff --git a/src/stage0 b/src/stage0 new file mode 100644 index 0000000000000..ed06372741eb1 --- /dev/null +++ b/src/stage0 @@ -0,0 +1,447 @@ +# The configuration above this comment is editable, and can be changed +# by forks of the repository if they have alternate values. +# +# The section below is generated by `./x.py run src/tools/bump-stage0`, +# run that command again to update the bootstrap compiler. +# +# All changes below this comment will be overridden the next time the +# tool is executed. + +dist_server=https://static.rust-lang.org +artifacts_server=https://ci-artifacts.rust-lang.org/rustc-builds +artifacts_with_llvm_assertions_server=https://ci-artifacts.rust-lang.org/rustc-builds-alt +git_merge_commit_email=bors@rust-lang.org +git_repository=rust-lang/rust +nightly_branch=master + +compiler_date=2024-04-29 +compiler_version=beta +rustfmt_date=2024-04-29 +rustfmt_version=nightly + +dist/2024-04-29/cargo-beta-aarch64-apple-darwin.tar.gz=5a8c5e48a88e7c7b41eb720d60fbd2e879b97639c7ff83710526e8e6caaf8afb +dist/2024-04-29/cargo-beta-aarch64-apple-darwin.tar.xz=0d237535ae8d435d99104fa5b9dbf41878e2304bb0f2eb574bf17dd685caadc2 +dist/2024-04-29/cargo-beta-aarch64-pc-windows-msvc.tar.gz=c56733bb6198af0a9b0df9a44ef979150e00de33b70853c239cccfcce23c328f +dist/2024-04-29/cargo-beta-aarch64-pc-windows-msvc.tar.xz=7da5f887151215ddec640684077d98551fe2aed75a3ece2c73b20698754a70bb +dist/2024-04-29/cargo-beta-aarch64-unknown-linux-gnu.tar.gz=73851e304a539d41bedc0d8a5d98800c8279ae623d3e58e863f8c1f8b458b01c +dist/2024-04-29/cargo-beta-aarch64-unknown-linux-gnu.tar.xz=db9c28841344b0154756e19a21795ef6e0c4e27c7844be9996824f1039edaa81 +dist/2024-04-29/cargo-beta-aarch64-unknown-linux-musl.tar.gz=a706c8c7e37b9e80d7faa000c5d179a772746eef071387fb2879fdeab1f1f891 +dist/2024-04-29/cargo-beta-aarch64-unknown-linux-musl.tar.xz=2060634afe1b4a19bae874c6ce3cf4256e613af26e06104b45da5bd71cfb133c +dist/2024-04-29/cargo-beta-arm-unknown-linux-gnueabi.tar.gz=7af61e74faea669fdd41793e4b88eb6a37bfacf845af364ee02bb7cf08c612c7 +dist/2024-04-29/cargo-beta-arm-unknown-linux-gnueabi.tar.xz=4759fb3e3d89ead605c4eeba23be5cb9b3ac98086a9de20f8dbfdfa9282ee486 +dist/2024-04-29/cargo-beta-arm-unknown-linux-gnueabihf.tar.gz=4cab18df2d94702e8b551357373bcae60d1023e644148f0f82e8971023362121 +dist/2024-04-29/cargo-beta-arm-unknown-linux-gnueabihf.tar.xz=7de4f0d72b4e5770376ede82b02d6bcfd450788a40375fad34d75524c941d72c +dist/2024-04-29/cargo-beta-armv7-unknown-linux-gnueabihf.tar.gz=6401391a426cf33d6c58f07e7b2828b178720cb4f2b8577ae932b5f5b7d6744e +dist/2024-04-29/cargo-beta-armv7-unknown-linux-gnueabihf.tar.xz=c3f6729bc769325046f0f62c51b5bed30068c37dc2a36a6283e50565d8cb7d5c +dist/2024-04-29/cargo-beta-i686-pc-windows-gnu.tar.gz=d116c97c1242220c7972b63010aee1ed36bf5353e84a06d3561cd5fe9d7dae84 +dist/2024-04-29/cargo-beta-i686-pc-windows-gnu.tar.xz=65eba577f7775b3eef36e7f000b5007264392b20a7759f8ed567f3a45b2877db +dist/2024-04-29/cargo-beta-i686-pc-windows-msvc.tar.gz=d418a3371b3631328bde2b1e0c3159700f12424e83b1d8ece1349fea90f9e403 +dist/2024-04-29/cargo-beta-i686-pc-windows-msvc.tar.xz=23ae73c776fdb0795944656d743444e3b4c440f45084028206c1aec52333b1ba +dist/2024-04-29/cargo-beta-i686-unknown-linux-gnu.tar.gz=b6bbdeb7c8bfac2e8a083adb4782caf5321799f47acb4eaf81da32bd11730e9c +dist/2024-04-29/cargo-beta-i686-unknown-linux-gnu.tar.xz=6b409691da6ddb8c04409667b2c3d9d6429c6b5bf53ad18177248406a5f06cb9 +dist/2024-04-29/cargo-beta-loongarch64-unknown-linux-gnu.tar.gz=24cd888d14a788e8fb5b886735f3c07a028a8681df48a777b2bb971c62a175ae +dist/2024-04-29/cargo-beta-loongarch64-unknown-linux-gnu.tar.xz=e8eece6412936fe4dc863a5e19e6766fbb20e81da0069ad7831465e638db23da +dist/2024-04-29/cargo-beta-powerpc-unknown-linux-gnu.tar.gz=8f007a2aa02e35c5ddb2152cc7589092a0e3083211c6aa23e676e3a3ad5a4b8d +dist/2024-04-29/cargo-beta-powerpc-unknown-linux-gnu.tar.xz=3e423e693dd0813f5d87d9eded94894076258ece56684f3598321cd013aeef3c +dist/2024-04-29/cargo-beta-powerpc64-unknown-linux-gnu.tar.gz=2eec5e45e389a52b526a5cf683d56a9df92004f6095936b16cd8d7d63722cc6c +dist/2024-04-29/cargo-beta-powerpc64-unknown-linux-gnu.tar.xz=64c5135cbff9d4fa9575074c55e79d85f72cb1783498a72e1f77865b9b2d1ba3 +dist/2024-04-29/cargo-beta-powerpc64le-unknown-linux-gnu.tar.gz=d64552a80ca386728e42f00d7f1c700b5e30e5a6939f32ffa15a7ce715d4c8e9 +dist/2024-04-29/cargo-beta-powerpc64le-unknown-linux-gnu.tar.xz=fe91adce8ba35bf06251448b5214ed112556dc8814de92e66bc5dc51193c442f +dist/2024-04-29/cargo-beta-riscv64gc-unknown-linux-gnu.tar.gz=77aafa8b63a4bf4475e82cd777646be5254e1f62d44b2a8fbd40066fdd7020d3 +dist/2024-04-29/cargo-beta-riscv64gc-unknown-linux-gnu.tar.xz=c38f0b4adcc8e48f70b475636bbd5851406bba296d66df12e1ba54888a4bf21a +dist/2024-04-29/cargo-beta-s390x-unknown-linux-gnu.tar.gz=c05df24d7e8dff26c01055ad40f9e81e6fcb3ae634ecc1f7cc43c3108677fa0e +dist/2024-04-29/cargo-beta-s390x-unknown-linux-gnu.tar.xz=47e8f4ec4d996600e60ddc49daeeb43d4c21e0583a86c12395c16eddc7db76ee +dist/2024-04-29/cargo-beta-x86_64-apple-darwin.tar.gz=f024bd225b77160dc2fabde78002c8deac5cbb9a35345340964c3b988b0d1791 +dist/2024-04-29/cargo-beta-x86_64-apple-darwin.tar.xz=96c9e44bd9f0c85c793e3dd6043cc4f89fbeeab5ddf0fdb5daefca8f690bce05 +dist/2024-04-29/cargo-beta-x86_64-pc-windows-gnu.tar.gz=517889f222b62150fe16bcfd3a0eb5f353956b0084d85713480197bff4558145 +dist/2024-04-29/cargo-beta-x86_64-pc-windows-gnu.tar.xz=a6653ea4aec51569c1300c044d8bf2517a1f5111f710d12cd352190425b8f317 +dist/2024-04-29/cargo-beta-x86_64-pc-windows-msvc.tar.gz=4cb5b5054dffe6721efbbf29192a67e59cda69ea4ab4791aaec6f314eefa5a5e +dist/2024-04-29/cargo-beta-x86_64-pc-windows-msvc.tar.xz=08bc45be22e9e4f615d1c9e70500046c8db89045f5d40dcde853c610591712a7 +dist/2024-04-29/cargo-beta-x86_64-unknown-freebsd.tar.gz=9661357ee8ea8973016fdbaa2de3cb98713136dcd25f07aa9f9d101180276815 +dist/2024-04-29/cargo-beta-x86_64-unknown-freebsd.tar.xz=7fab806227d1a3be817602abb121ac7e039ba0bbf81e0a1d47bdcccca74203c6 +dist/2024-04-29/cargo-beta-x86_64-unknown-illumos.tar.gz=4c79bb48cfe64bd38af7fe3660cd8bdc99ec90738a0d8fdf80843ecda910dab0 +dist/2024-04-29/cargo-beta-x86_64-unknown-illumos.tar.xz=0fb9edfdafde1820ccb25c22369cafb0e75e68795effeb615cb284a5837c75ba +dist/2024-04-29/cargo-beta-x86_64-unknown-linux-gnu.tar.gz=c1902a072e61ab5ae9737a1092732e3972deee426424bc85fcf8702adffdd41d +dist/2024-04-29/cargo-beta-x86_64-unknown-linux-gnu.tar.xz=d39ea1195dcc95e428bd540abd2db5b5d4c997a7661a41a4c0ca41cbdd18d27e +dist/2024-04-29/cargo-beta-x86_64-unknown-linux-musl.tar.gz=0edfdb6f6bb2a4a1a96a5e95cec897c444c936e6624bb4a530ffed4847b97445 +dist/2024-04-29/cargo-beta-x86_64-unknown-linux-musl.tar.xz=70c264b7845febdee45d0c6e44b65d47ba7f367ef33ec906a9fd7f992ba7cc13 +dist/2024-04-29/cargo-beta-x86_64-unknown-netbsd.tar.gz=f1bd6417a54f3b53d572ce4af799242db7c11265c71201cc09c78d71be38c13a +dist/2024-04-29/cargo-beta-x86_64-unknown-netbsd.tar.xz=53569810469c483785333759f86434706ee5368d5e18270ee13a17817ad57d40 +dist/2024-04-29/clippy-beta-aarch64-apple-darwin.tar.gz=7b693bde61a090854527a145455ff774314c65ec0cd47d25a19c76c6a166d96c +dist/2024-04-29/clippy-beta-aarch64-apple-darwin.tar.xz=2494e9fdd8d342b6bc3e55eecfd555c43e3cca8421f3236df2d5a366288fec62 +dist/2024-04-29/clippy-beta-aarch64-pc-windows-msvc.tar.gz=90307f09c6fcb0c1fbe3ad1522a5381a17e2f69637c6d00f4a2cb5f3149bf736 +dist/2024-04-29/clippy-beta-aarch64-pc-windows-msvc.tar.xz=f7e0dec4a4862bd85d894252366152b3b6a7627e7e5a25ce323fa2db3bd87c2b +dist/2024-04-29/clippy-beta-aarch64-unknown-linux-gnu.tar.gz=7c719e38f2a1030ae61985205df52f9a0c37b659463a5e2dea8e60e632de2d73 +dist/2024-04-29/clippy-beta-aarch64-unknown-linux-gnu.tar.xz=181ff4ae6adced6522a4c29869be3cc5dac8b961c7c88f2957cd31f831490807 +dist/2024-04-29/clippy-beta-aarch64-unknown-linux-musl.tar.gz=4e0e63e6f200386995e369a2673867d1bc3005d51d6a57c00ca80056dd85316b +dist/2024-04-29/clippy-beta-aarch64-unknown-linux-musl.tar.xz=3d5b22a13aed6821482e60d9cc8571e2da9d95d82104284b77c56985a35a9c4e +dist/2024-04-29/clippy-beta-arm-unknown-linux-gnueabi.tar.gz=9f788db76a5d55b3ecdd04a70b0e2be466959f76ae9fd3497ca2c503504e0c03 +dist/2024-04-29/clippy-beta-arm-unknown-linux-gnueabi.tar.xz=f4d8fc103807fba61d71d88b8e25a7016bfbd1a2905330f9a9fb3d7ba082713a +dist/2024-04-29/clippy-beta-arm-unknown-linux-gnueabihf.tar.gz=d61bec3d017dd0be43e48350190ad18c0a0269e43d964600b62e1f7fd4f84399 +dist/2024-04-29/clippy-beta-arm-unknown-linux-gnueabihf.tar.xz=c00cbdc41a4da0c313a1a282b0158b059dd34f640b582cb7ca18e3d290ca8fa5 +dist/2024-04-29/clippy-beta-armv7-unknown-linux-gnueabihf.tar.gz=52143a530ca5274fbb760beecddff16f860ea787443d3dc708dda7c8f32ca9bd +dist/2024-04-29/clippy-beta-armv7-unknown-linux-gnueabihf.tar.xz=c6d2dfeac6f40811bc9b4cec3c23f9c3bb46f761e006257b9313aa7c1a647b5a +dist/2024-04-29/clippy-beta-i686-pc-windows-gnu.tar.gz=325d39e426b1907fa17d93c0752d3d73bd95750f4f967c2a84aab2c5dac8a588 +dist/2024-04-29/clippy-beta-i686-pc-windows-gnu.tar.xz=536f591d4da455302029384ed196932d71119ef0160ac5415617d6b777c51123 +dist/2024-04-29/clippy-beta-i686-pc-windows-msvc.tar.gz=c3684c9bf471669d444853bf484880d17e150ecb0e7505de90883382023e343b +dist/2024-04-29/clippy-beta-i686-pc-windows-msvc.tar.xz=0b00e6132f73d5dc762e359b0005fceab0cf7b01337d8f4aa9eacfb4552f9245 +dist/2024-04-29/clippy-beta-i686-unknown-linux-gnu.tar.gz=c91c1eadfc4cbae360a0eecf11c32d2509b68aca86c7b1de3b102944f43e1511 +dist/2024-04-29/clippy-beta-i686-unknown-linux-gnu.tar.xz=6f7a5a287dd6226c203bb674ff02ec773e5d0813091b2af744b88ecd6997a304 +dist/2024-04-29/clippy-beta-loongarch64-unknown-linux-gnu.tar.gz=58383f094995823ea6db6a87b9ad4b33bdae2264d29bab88ab71ec60ccab3b93 +dist/2024-04-29/clippy-beta-loongarch64-unknown-linux-gnu.tar.xz=dbf4680a6fd4dca54acca5503a7fd94502b8e85819bc02346ae9cecd275e4514 +dist/2024-04-29/clippy-beta-powerpc-unknown-linux-gnu.tar.gz=e28eb32cda42654c0f0247aa8e15f01f73770b36f7626c8d6f1b7659accc56e6 +dist/2024-04-29/clippy-beta-powerpc-unknown-linux-gnu.tar.xz=fcc48a83b748e1e46f9daef40563f8e5abbb0e3f014a168b04f3c700c2ace2b8 +dist/2024-04-29/clippy-beta-powerpc64-unknown-linux-gnu.tar.gz=b626faf3275fcd196cd627e8a36c67721bae16a56f61cd080c79d137b3ec7737 +dist/2024-04-29/clippy-beta-powerpc64-unknown-linux-gnu.tar.xz=2c599d2dc719d69f67625f3c6573fcc4f1ea3266801557dd3892bdb7c761b4cf +dist/2024-04-29/clippy-beta-powerpc64le-unknown-linux-gnu.tar.gz=0bc1f546fe0cef2b9516231ab608de68d55f72022fbc9ced5101b600e005f8c4 +dist/2024-04-29/clippy-beta-powerpc64le-unknown-linux-gnu.tar.xz=993294f2ae5202785ab242c1c6567df9c8ab1ef44ad35748c526b7fe854fb94e +dist/2024-04-29/clippy-beta-riscv64gc-unknown-linux-gnu.tar.gz=210a4f0d208e0c8e13a57fb3b3e6c98ab5f620e4988d10a127ff1424ac1d5ca9 +dist/2024-04-29/clippy-beta-riscv64gc-unknown-linux-gnu.tar.xz=f10f7df41a13ee2ecdc25d60e697cba2342129a912ef20d8bfca5f611a9ec97f +dist/2024-04-29/clippy-beta-s390x-unknown-linux-gnu.tar.gz=3e24d2af65f0c9667c9997ce091711b2be48e673de3707cddfd8cda455dfecc7 +dist/2024-04-29/clippy-beta-s390x-unknown-linux-gnu.tar.xz=0e7b8fbd0207489e38c78c2ae1aa0df4fcbdd84741aa50a86379e4d7ede286b1 +dist/2024-04-29/clippy-beta-x86_64-apple-darwin.tar.gz=9c0c47fd97ce72abcd6126315834c62aa7297fe09d447ee4cefa1eb46a116326 +dist/2024-04-29/clippy-beta-x86_64-apple-darwin.tar.xz=49dd65c5340fd804399edfa2402cf255fd9bfce1f4aa7fbb3c193c11bc03f8af +dist/2024-04-29/clippy-beta-x86_64-pc-windows-gnu.tar.gz=6c1c3bdf097a1846ae08b098c555c0c5e9e9b646c744d6bb5a855789196b8bf6 +dist/2024-04-29/clippy-beta-x86_64-pc-windows-gnu.tar.xz=0a7319d1062f73af1c8f0efe6ad970d10d02259162c5bc84bb1f3a10f3911bcb +dist/2024-04-29/clippy-beta-x86_64-pc-windows-msvc.tar.gz=52fef3f8a64fa58934a633bd4944e8ba9e15f2c2766d0f302dea1a6523864dab +dist/2024-04-29/clippy-beta-x86_64-pc-windows-msvc.tar.xz=8fdbe7590e62ab68a2e463b14da2595e8c4592744f578a813f64d430ed7db4b6 +dist/2024-04-29/clippy-beta-x86_64-unknown-freebsd.tar.gz=509bf535622bd26385184ee0c17e4e27a5061a8aeebf5759f24bd578692b2f5d +dist/2024-04-29/clippy-beta-x86_64-unknown-freebsd.tar.xz=2fcd10ada329ba7633616bebc584dca13f11c465e7cf513e76efeb0c3174486f +dist/2024-04-29/clippy-beta-x86_64-unknown-illumos.tar.gz=ea8cea0d4a2379bcd0693f6174b25bc1f90a016dbe8280159cbb61d859806fb0 +dist/2024-04-29/clippy-beta-x86_64-unknown-illumos.tar.xz=5a243df8d1345db6bd18e4386ba628e6d302bce1cc572fb447cca4264fda3ee9 +dist/2024-04-29/clippy-beta-x86_64-unknown-linux-gnu.tar.gz=2ee560d3c1e306e103eb06d8e8033cd1489b3f6ff9df3bd8a95e25e977befa27 +dist/2024-04-29/clippy-beta-x86_64-unknown-linux-gnu.tar.xz=aaf6e54184a65ad6592bf03955a84ad12b561afd86064b1ac5fa03cf637052f8 +dist/2024-04-29/clippy-beta-x86_64-unknown-linux-musl.tar.gz=1b3877424a0a0eb507675a50e9d2c793f00ab85f6f12b1e27f871331070325b8 +dist/2024-04-29/clippy-beta-x86_64-unknown-linux-musl.tar.xz=6df5eaae5afb64557ba5c3a53ee3e56dab85455838a6044c7671c1180acfeaf9 +dist/2024-04-29/clippy-beta-x86_64-unknown-netbsd.tar.gz=1ac05ed7b607fff8b77ff203a663e9f4f2487779bc25e2dcd454cdf5b7583328 +dist/2024-04-29/clippy-beta-x86_64-unknown-netbsd.tar.xz=da502375b3cee8b254ab5999809f522692c2d1d90ea0544ad03c0ca514c65ef4 +dist/2024-04-29/rust-std-beta-aarch64-apple-darwin.tar.gz=2fdd35ca3b3e3d6f548f11c93337f5bf2e3c088bc78a79881e6f8e230b38b9a5 +dist/2024-04-29/rust-std-beta-aarch64-apple-darwin.tar.xz=bc16b3a1ab6ed69f0121a117c50cbcd201500dae4d72ad0dab148913d04cc529 +dist/2024-04-29/rust-std-beta-aarch64-apple-ios-sim.tar.gz=9375c786703c17baae1c2066f8d972ac316bc840e478ecd1b94288a1d428324e +dist/2024-04-29/rust-std-beta-aarch64-apple-ios-sim.tar.xz=50d6818a8dd3ab7a3ddbbd7a062b538d9ff3ceb6eada031d1c22ab1dc7ba512c +dist/2024-04-29/rust-std-beta-aarch64-apple-ios.tar.gz=56c3a01e8fd5c2ed75df811993b0b724709fb5473cc308ac09e7f5644468f751 +dist/2024-04-29/rust-std-beta-aarch64-apple-ios.tar.xz=3527d1f2c99c806479fb4b3801335dc921b514f171b82cd252cbbfc9ed30b163 +dist/2024-04-29/rust-std-beta-aarch64-linux-android.tar.gz=bf8cae7c66489f1aa27f1dea1b37f0d0ae514a6e21b93ff2dc6400dc88feca03 +dist/2024-04-29/rust-std-beta-aarch64-linux-android.tar.xz=46799f0bc1b3c13877f6cb732774cb3b33e0d8a081bfb56d0f877e79482aa1de +dist/2024-04-29/rust-std-beta-aarch64-pc-windows-gnullvm.tar.gz=9f90fadab5104e1d415edf3b4edfaf7222f9f0d55f849851efdec74ffee16f8d +dist/2024-04-29/rust-std-beta-aarch64-pc-windows-gnullvm.tar.xz=87ed6774202b18691bd6884df6944c7e9fe9c944b57a2837e7a7647518bf94e8 +dist/2024-04-29/rust-std-beta-aarch64-pc-windows-msvc.tar.gz=4a0692ad28f7f130b472ffa4aa766b745ba01fb75aa921f2da6622c9c68750df +dist/2024-04-29/rust-std-beta-aarch64-pc-windows-msvc.tar.xz=a3d45962489a1e18a87e567cbbc8d3665f38809d0ad2ef15bcf0ff9fb9f470a4 +dist/2024-04-29/rust-std-beta-aarch64-unknown-fuchsia.tar.gz=c724f4eb135f73b9c79618f27a1ab35dc7b9d26ca62ed796accce68f9e747a66 +dist/2024-04-29/rust-std-beta-aarch64-unknown-fuchsia.tar.xz=8eab25782d16bcee75f86ecbb826346beb4a7525b220b45b3ba05a567c6d4391 +dist/2024-04-29/rust-std-beta-aarch64-unknown-linux-gnu.tar.gz=33ab1f8410edf590570d7468dbe2ebb5a0907125bbc8d360a928dcb355f0d0e6 +dist/2024-04-29/rust-std-beta-aarch64-unknown-linux-gnu.tar.xz=d3d870209a55ac96391affaa347c04f48cf98c089ac5056f340b8bb38bcc8e60 +dist/2024-04-29/rust-std-beta-aarch64-unknown-linux-musl.tar.gz=4d2bb72b898c30a2fc8d5d3333c2e99a8e30c15891fab641b6a519dc9f0cb611 +dist/2024-04-29/rust-std-beta-aarch64-unknown-linux-musl.tar.xz=fa343e6b6110fcd0c5dae4287ff1a799de5d7e4a805dbf4e9a034bbaed2bf269 +dist/2024-04-29/rust-std-beta-aarch64-unknown-linux-ohos.tar.gz=f1ec4139783169fd83e1b0184518ed25d26cee7b21f196deecc74e83a1d78725 +dist/2024-04-29/rust-std-beta-aarch64-unknown-linux-ohos.tar.xz=d100be2f6f0346c4b1f5b41aec0c13a47426bf4d49127f2341c8332903e4e782 +dist/2024-04-29/rust-std-beta-aarch64-unknown-none-softfloat.tar.gz=bab6051e1071a58cd126580f6644decf16edb4473fe4be6a34791610d820a294 +dist/2024-04-29/rust-std-beta-aarch64-unknown-none-softfloat.tar.xz=d9b68f06ff23629063e92dfc42aa3115a858238d368e4b52b35c1ea4491b1402 +dist/2024-04-29/rust-std-beta-aarch64-unknown-none.tar.gz=96804c2d9accd3242bdc22dad688b2ccee071952477b9c592f099377aee6c591 +dist/2024-04-29/rust-std-beta-aarch64-unknown-none.tar.xz=3fed6812d84bdaf787e85c37e23ba729b81a6d25a2b33fed75320e66e6641c89 +dist/2024-04-29/rust-std-beta-aarch64-unknown-uefi.tar.gz=8da5f301bff35fc067ec7cfb878ebfa5607af7dbc276a6b34a77404432c700d2 +dist/2024-04-29/rust-std-beta-aarch64-unknown-uefi.tar.xz=80d643189dc9af98b6410a01261ce6ad34b1325f3aebf3ff61fb43f1261b41ff +dist/2024-04-29/rust-std-beta-arm-linux-androideabi.tar.gz=2e86b54b0d1f7fefead11d6383bdc80fe0a7b3ccf58381d2a731e6f1c62926de +dist/2024-04-29/rust-std-beta-arm-linux-androideabi.tar.xz=9831a0270457cad2798b5ae4fe956c257c7e10ce5ad211793dc467577cdec29e +dist/2024-04-29/rust-std-beta-arm-unknown-linux-gnueabi.tar.gz=f96bc303c0c2be9cf589f00aa63b2cf3fb8585ca9dd8860fe525821bfa1fe19a +dist/2024-04-29/rust-std-beta-arm-unknown-linux-gnueabi.tar.xz=e57a053b1c2bb6fad93dfaffedce7f48fa292196fc8ba6fd2f0c74dc810a13a9 +dist/2024-04-29/rust-std-beta-arm-unknown-linux-gnueabihf.tar.gz=49b2cb2ba5296871b5fac5ad9a74a2891e8b78321078a455ba4a65e003bebd40 +dist/2024-04-29/rust-std-beta-arm-unknown-linux-gnueabihf.tar.xz=0f9c15d834a9d282a4018934759f7b48ef3d275e09679a68c5fd1b3f047d02e4 +dist/2024-04-29/rust-std-beta-arm-unknown-linux-musleabi.tar.gz=e59f92827241e670c1aa92b35235ad12340869d59327fb83084b5f4149acbe06 +dist/2024-04-29/rust-std-beta-arm-unknown-linux-musleabi.tar.xz=ad1cf96bb1fcceaa016e29e8ad34b4cfd711d2e0bd7cabb9cd7cc28abf64d894 +dist/2024-04-29/rust-std-beta-arm-unknown-linux-musleabihf.tar.gz=14a6d318af85bb9fa5c229e45a88a32a71f44ed02cd90a24bb67921eb64dee41 +dist/2024-04-29/rust-std-beta-arm-unknown-linux-musleabihf.tar.xz=ed6b48502ab9169818bceb300b4e6b4fd63366ad5808b047bf9988dae04c2729 +dist/2024-04-29/rust-std-beta-armebv7r-none-eabi.tar.gz=345e8a023be55e3b88a0c2677ea28c7bb4fcc5f3ab707638de76065c7592c2d5 +dist/2024-04-29/rust-std-beta-armebv7r-none-eabi.tar.xz=6d9b11d08f2d62611327a893b45ba07c36df11f077250496ab0881eb7ac84c65 +dist/2024-04-29/rust-std-beta-armebv7r-none-eabihf.tar.gz=a2ae1bf003a8a12b2ecb6bde9868a978820f184af523f0e4c3fc935edd509423 +dist/2024-04-29/rust-std-beta-armebv7r-none-eabihf.tar.xz=3d1dcf8308f9d4590b429f6abbf8f42f04496ab490ccf4ed8c9e381e6d886cae +dist/2024-04-29/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.gz=a54106d27e4ce97463e7867ceff9dd22ba456f840ec23229e6909b37d48ad554 +dist/2024-04-29/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.xz=e6abfaa0905a00efeaee85b9f93793bab93e2cf4e172c9d829c5ba85006c688a +dist/2024-04-29/rust-std-beta-armv5te-unknown-linux-musleabi.tar.gz=cbed18e5dc61fcecb2920affc3890c3b8ae46b7fe5a80b3288689e18d490f3f4 +dist/2024-04-29/rust-std-beta-armv5te-unknown-linux-musleabi.tar.xz=2b58bb0dd5cd2c5f7f93f4c6e9135090b931e0ffa27ff9efe2b8ff9fbbb7e48c +dist/2024-04-29/rust-std-beta-armv7-linux-androideabi.tar.gz=6a371c2ececd349dfa76a02563069912fc91577ac4446d36c22f96723d7f5e9f +dist/2024-04-29/rust-std-beta-armv7-linux-androideabi.tar.xz=9325daf41ddab02fa845971c10a5e0538a18c7bea14e66fa0f5f6fb16654c7ae +dist/2024-04-29/rust-std-beta-armv7-unknown-linux-gnueabi.tar.gz=7f5ba76cfb7c85333c8dab76fb4ad3f12ddc254b95f9ee07fadb8e1270a4f767 +dist/2024-04-29/rust-std-beta-armv7-unknown-linux-gnueabi.tar.xz=f853b7f929b7a309ed6c08ff8c57d583ce0ccb19270674fb30e63a873834dc87 +dist/2024-04-29/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.gz=0680005d0a12498b687afc583d4f36bd67d0877cd9d3323bfd2df50d15c27afe +dist/2024-04-29/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.xz=a494b78fcad01c83df9522d460ac2d35d2d00736a921381f2c611dc516edaa16 +dist/2024-04-29/rust-std-beta-armv7-unknown-linux-musleabi.tar.gz=cfa555db31b5470e878b0f53d86617e7342e8bf018fe62cb0271dfe13db95f51 +dist/2024-04-29/rust-std-beta-armv7-unknown-linux-musleabi.tar.xz=0a8ccd6d88cbe79a855111fbda45aa1a728de655b6927f3d429d901d2afc6503 +dist/2024-04-29/rust-std-beta-armv7-unknown-linux-musleabihf.tar.gz=eac53424001c884a540c42f0b68447349ec5d0601a030c060aaed76d54895728 +dist/2024-04-29/rust-std-beta-armv7-unknown-linux-musleabihf.tar.xz=42d78fca62361ff28db5bc43bb01cef7af5c6f4ab2110fe6170c3dce4707aab8 +dist/2024-04-29/rust-std-beta-armv7-unknown-linux-ohos.tar.gz=c88de9f2e667da73177fb9c9309d7f1f467e31c18e3ae50d722c71ec8dd876a4 +dist/2024-04-29/rust-std-beta-armv7-unknown-linux-ohos.tar.xz=24b3c04a42d511cdc8c6107b597be38981114f0574eced493d0e90fc748094bc +dist/2024-04-29/rust-std-beta-armv7a-none-eabi.tar.gz=cd4ad182a098c61550265879ccc04733c39110827f7ef62eecfb8c120ae4ece8 +dist/2024-04-29/rust-std-beta-armv7a-none-eabi.tar.xz=8499a014dfdf448f474a58f148784c2eef245dc909587d876d2fb9ddc6a4ec3f +dist/2024-04-29/rust-std-beta-armv7r-none-eabi.tar.gz=e8e1870e5b12b3d8643d712efb91eb86b2081284cada4a140c1526692ab183c4 +dist/2024-04-29/rust-std-beta-armv7r-none-eabi.tar.xz=d6029121eacc44bd4dcd9ef6dd3cd0d775cb6e9a3d99f3d62d746fcbf8981cab +dist/2024-04-29/rust-std-beta-armv7r-none-eabihf.tar.gz=1e0fc42c3802e205130c01ca90f92d793c1c5427b34da66fe77b97cf67b4a5c1 +dist/2024-04-29/rust-std-beta-armv7r-none-eabihf.tar.xz=4c8cfdb11bb686111fa4842d13430c86d9d14ada30e9df334b3777fe899233e0 +dist/2024-04-29/rust-std-beta-i586-pc-windows-msvc.tar.gz=ff895c1b39b84587f10903f4be13d275b545e690da6761190d12c01acc25c6d8 +dist/2024-04-29/rust-std-beta-i586-pc-windows-msvc.tar.xz=fdcbcff7b740235bb16e44174fff9080a7c0a31be358c8abc41805c02c20c3b2 +dist/2024-04-29/rust-std-beta-i586-unknown-linux-gnu.tar.gz=6b227f3b9001e148b66b7001f753a6f88fef9677e39d8fcf4d9c35fe8d345568 +dist/2024-04-29/rust-std-beta-i586-unknown-linux-gnu.tar.xz=1e29297beb8de3778ba958731294823d9a93aac1e0d8833abc5aa99e2935965b +dist/2024-04-29/rust-std-beta-i586-unknown-linux-musl.tar.gz=26481ad5f22a319830d42f69b1c0195bd65900ebe112e659432334b3468f3d0e +dist/2024-04-29/rust-std-beta-i586-unknown-linux-musl.tar.xz=c8a837e0d9da8ad976fc1539541c085365aac9dd28b34e4a289d38a823d1b065 +dist/2024-04-29/rust-std-beta-i686-linux-android.tar.gz=f05e28a52f17e22f36ffc70018012a1fe6a07f4b461e774b36464f32bc8f8dea +dist/2024-04-29/rust-std-beta-i686-linux-android.tar.xz=f9501b2691c51e54a6f4cc6fb72e41901eb551d3a7be5f82a94ce2d3e217828b +dist/2024-04-29/rust-std-beta-i686-pc-windows-gnu.tar.gz=8d9a782d4f7450bca536aab45147c6ef08bc3847b43fdd171c6449e29762eda0 +dist/2024-04-29/rust-std-beta-i686-pc-windows-gnu.tar.xz=4008712e03fb6494eaba3d79051c5e3fdd93d4c52ae8d86cf8f344b5f051cbca +dist/2024-04-29/rust-std-beta-i686-pc-windows-gnullvm.tar.gz=cfb23242e495834a3d0f7ffa3da4a0b206dcae35872b1455b11faeee5511ba5f +dist/2024-04-29/rust-std-beta-i686-pc-windows-gnullvm.tar.xz=95415742c0171945ffc2b67c913ebd1330e29634af238f5ccc843a965340374a +dist/2024-04-29/rust-std-beta-i686-pc-windows-msvc.tar.gz=e9354d69e39ecfac1d2928664d17d73f808256a4076b849171a9667705c0aa08 +dist/2024-04-29/rust-std-beta-i686-pc-windows-msvc.tar.xz=a34bb0a91170d84195f35ba52afa4c9be8a2f2706dbeea02bd6e8908e08ac65e +dist/2024-04-29/rust-std-beta-i686-unknown-freebsd.tar.gz=d65f286de399ccc9e9acaf7a4dc4f885357c750231d54a144ba9a59181814f11 +dist/2024-04-29/rust-std-beta-i686-unknown-freebsd.tar.xz=4c93a7da70a69b2ebbac01df64af16344e523d16470b29e57237b1d0925f7721 +dist/2024-04-29/rust-std-beta-i686-unknown-linux-gnu.tar.gz=1b978bfd1a9234be7ef197c8c98c5a6b625f6fbb7b0fca58695986768bdca176 +dist/2024-04-29/rust-std-beta-i686-unknown-linux-gnu.tar.xz=98d4eb5b89a593c8c4f86244c9a7c737d9c18c0168aebe5923b8d9145adcf89a +dist/2024-04-29/rust-std-beta-i686-unknown-linux-musl.tar.gz=dbf9b3c5b54b3eb0727f976f5632c5b0fcb2f90ac7453962d6cef20f7dae4284 +dist/2024-04-29/rust-std-beta-i686-unknown-linux-musl.tar.xz=f209ade093753342dda6e710ee832a538dbdaa08a24d606f9a2a1bc59b83da29 +dist/2024-04-29/rust-std-beta-i686-unknown-uefi.tar.gz=3c3ca7f34569b2c70c6b223754418a535dd7dfa087ab6e28ed2ec78d20065887 +dist/2024-04-29/rust-std-beta-i686-unknown-uefi.tar.xz=72a7cd0f430ab40d80e93f409b8e26a181010ab4bb75d151e829d51ccdcf8c62 +dist/2024-04-29/rust-std-beta-loongarch64-unknown-linux-gnu.tar.gz=b7dfa59bb05cf806c87854d6fce5ef0f160697052fdf6e5a0cad121499108608 +dist/2024-04-29/rust-std-beta-loongarch64-unknown-linux-gnu.tar.xz=88bc22f68bab3367cdfa91676418ce1ffc0ec002afb32aed7def880bdd4be402 +dist/2024-04-29/rust-std-beta-loongarch64-unknown-none-softfloat.tar.gz=d61019048b941064a99d19e46ff3236a88a2e8fcfb963cedd1d9d1c47963c170 +dist/2024-04-29/rust-std-beta-loongarch64-unknown-none-softfloat.tar.xz=7474bda08134c676d74afe5263317af3f271963d8ceaa5efbfa1b657f885c572 +dist/2024-04-29/rust-std-beta-loongarch64-unknown-none.tar.gz=e089c77d433d838ca02d7531d6f4a1770fb4a0568acbd96c8f43034d76f2990b +dist/2024-04-29/rust-std-beta-loongarch64-unknown-none.tar.xz=364ae6c89c7a930098286e55193d2f5ee3d5ea80b7cca73046e41725f4a8a2f9 +dist/2024-04-29/rust-std-beta-nvptx64-nvidia-cuda.tar.gz=c17bfad87d16f3a8d26646525dc59a352718db9e7572acb583b68a18cfdc338a +dist/2024-04-29/rust-std-beta-nvptx64-nvidia-cuda.tar.xz=f5c4ecef1c08d19ba6fddbd359a0ce94e46888021cae057fce969276026d086c +dist/2024-04-29/rust-std-beta-powerpc-unknown-linux-gnu.tar.gz=3e7e13b0d2e804d228e1e3a9dac0205d294ae29dcc37132f15fb1e218861eb39 +dist/2024-04-29/rust-std-beta-powerpc-unknown-linux-gnu.tar.xz=ea31b7678e6f64c2f9c28a9af120be04ed6f2a25a496e40afbf6e9aa0dd20b60 +dist/2024-04-29/rust-std-beta-powerpc64-unknown-linux-gnu.tar.gz=f0e1b314c3d5ad1676c68c112581dce62fa06ad557cd5f61034e147b064ed270 +dist/2024-04-29/rust-std-beta-powerpc64-unknown-linux-gnu.tar.xz=8ab7bbea6e2f72df1286facc7d306d01809a4dd9f8901dfdec7e50b594658d49 +dist/2024-04-29/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.gz=48f6abda1c7dac185858744aa2cdc3513cdfb6552535282ee83cf9c5365573c7 +dist/2024-04-29/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.xz=d920d97f15b56ba6ea81e08b3c29dc7f44f5f30b7513c53446edf95843c332af +dist/2024-04-29/rust-std-beta-riscv32i-unknown-none-elf.tar.gz=0a198a770f6e6043e923b0ab1a508fd8b190612d0370c33c8dd2c5f63b6f19dd +dist/2024-04-29/rust-std-beta-riscv32i-unknown-none-elf.tar.xz=424a93313cfe2d85acf956be3d9ac71ea8e34ee61617a550ad6ff5360e1dff52 +dist/2024-04-29/rust-std-beta-riscv32im-unknown-none-elf.tar.gz=2e2b0a8e41f4ea774d665d6248cbc2fdbe3e582206efeb87d250786ebaad0b1a +dist/2024-04-29/rust-std-beta-riscv32im-unknown-none-elf.tar.xz=2da372c091017b7096e473e5c7016a504d2e041e14173d2520086cb43e0a615a +dist/2024-04-29/rust-std-beta-riscv32imac-unknown-none-elf.tar.gz=69d3b21403181b2df14243816388169db2466477ec34bcca5693fb017703686c +dist/2024-04-29/rust-std-beta-riscv32imac-unknown-none-elf.tar.xz=281b9c20f8641a3d1b349e762b7f713fb0b91da0d21eec798e639e36a0ea3dab +dist/2024-04-29/rust-std-beta-riscv32imafc-unknown-none-elf.tar.gz=dd9bfd3fd8446d35180fe781139dfb4e04dd658b112eb2a749e8f4aea14f0271 +dist/2024-04-29/rust-std-beta-riscv32imafc-unknown-none-elf.tar.xz=b1366375e0c5f53da581741dec91972b0c46d7d466052539207e8feaab0ba3ec +dist/2024-04-29/rust-std-beta-riscv32imc-unknown-none-elf.tar.gz=7c6650d8cf8abd51547010e8211af3ef3195099ef43a563460ad4780de20ba17 +dist/2024-04-29/rust-std-beta-riscv32imc-unknown-none-elf.tar.xz=bab46f3c0078ce346de563bb7a248ca92f15dbdc73bf5a3bc520486118442320 +dist/2024-04-29/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.gz=01735b4ad5bc0a53087dd0ccaef2cf174b27e45bf4d2e3c15e64f7522f059c63 +dist/2024-04-29/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.xz=0bb272c2c235583ed3e9ec151b3bfc601f8cd07822c2fe47a1258b358be507f0 +dist/2024-04-29/rust-std-beta-riscv64gc-unknown-none-elf.tar.gz=b2c7f8ee0efe6d0812e4b5dd0979f60f105b84d34d4f600ef75f2eacd954893d +dist/2024-04-29/rust-std-beta-riscv64gc-unknown-none-elf.tar.xz=0d5301fc553a6911af6643ab7f57b6438bf649ffcd050d486278c0c5fe38eeba +dist/2024-04-29/rust-std-beta-riscv64imac-unknown-none-elf.tar.gz=0d1d35ecb88ee717720ad8e74bd5b602fd6011fe321baddb939f3b161e9cd8c5 +dist/2024-04-29/rust-std-beta-riscv64imac-unknown-none-elf.tar.xz=a5cf0b98596e68e6f72be2e83c61b8aaa19ead42f248ee2408a3b8f4e97a6657 +dist/2024-04-29/rust-std-beta-s390x-unknown-linux-gnu.tar.gz=629ed749cdae110668ad9ddbc5c61e99e8d400f3dd0981146c3820deadc360f6 +dist/2024-04-29/rust-std-beta-s390x-unknown-linux-gnu.tar.xz=192819438ed27a565cdb67b51d2f5caeb6ae258de86191d6922574327f132acd +dist/2024-04-29/rust-std-beta-sparc64-unknown-linux-gnu.tar.gz=84286f6cf6f00f3c92dc881f64a31e1ec5910102d8d3d4faf6fc7e2ddf1544a7 +dist/2024-04-29/rust-std-beta-sparc64-unknown-linux-gnu.tar.xz=304b5f876b47dcbb7c3483c49295b822e8ba83234bb568ce67896ae4773ae2fa +dist/2024-04-29/rust-std-beta-sparcv9-sun-solaris.tar.gz=25062159b859e21dda76ca22d4a31d3aba4fcdb0def78bc5b5cf9887c07c1be9 +dist/2024-04-29/rust-std-beta-sparcv9-sun-solaris.tar.xz=5d557ee86457f288462603fe53bcc2e092d84faee543659419fa68c1bd88f554 +dist/2024-04-29/rust-std-beta-thumbv6m-none-eabi.tar.gz=a9663048aad82ef832b2cf82fa9fb94be047f77e283e8aa3e2df6ad957d0782d +dist/2024-04-29/rust-std-beta-thumbv6m-none-eabi.tar.xz=4c4b703a846b4123d09c1eace6322e82784a004b278f1f3b1ca1279e96207f18 +dist/2024-04-29/rust-std-beta-thumbv7em-none-eabi.tar.gz=32907c33f240abb1cb17ac438da42c5fa3932b270ad08fd6914775c5b59a02f5 +dist/2024-04-29/rust-std-beta-thumbv7em-none-eabi.tar.xz=112583227d2b6abfef6eeb78d980bf2efef392f3b66e433c4959a642d72ffc7b +dist/2024-04-29/rust-std-beta-thumbv7em-none-eabihf.tar.gz=7ba0084527a18479c4b6f6a0dba8ae23a0ed50e9fc5fbfce23cae1babb5a1e12 +dist/2024-04-29/rust-std-beta-thumbv7em-none-eabihf.tar.xz=49eb4e2efe3a76713ce1fecacaf915717eeed8552912b92895c7fee068a85a36 +dist/2024-04-29/rust-std-beta-thumbv7m-none-eabi.tar.gz=518a532b52f2dad2825158614cd00b12aac6c6e1983a1ad53e2b0e26d1f1b845 +dist/2024-04-29/rust-std-beta-thumbv7m-none-eabi.tar.xz=2895e5796a29fd016462694d880e38eb191cb92c9bdb14414c1d6e63b23d3394 +dist/2024-04-29/rust-std-beta-thumbv7neon-linux-androideabi.tar.gz=2af590c063344c4c3f65d704fa255232b5f5954872d03c4c55d48662cbe6bb17 +dist/2024-04-29/rust-std-beta-thumbv7neon-linux-androideabi.tar.xz=a09df5f38183d9fe6116c807619f812410763ddedf06055bfe8040b5794104d3 +dist/2024-04-29/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.gz=eac22c4972bde3a57cf2ec4e31b43db3c4b7d961ae31475d8942e898c07640cc +dist/2024-04-29/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.xz=104f2c6490e30cc47833edbd806c2efe6256d1194600b2278339612f94704d45 +dist/2024-04-29/rust-std-beta-thumbv8m.base-none-eabi.tar.gz=b3c9c9d7ce8c1db6f20e8ede542e67aacd6047c52882a5d06c4f96a40a7304d9 +dist/2024-04-29/rust-std-beta-thumbv8m.base-none-eabi.tar.xz=76bfb114bc7674792934a4892d2db41fdc8f5bd30c3aa96c43e8055199157476 +dist/2024-04-29/rust-std-beta-thumbv8m.main-none-eabi.tar.gz=1308335fe80dcafaba511ee589959d461145533de5f76118fee29a7e9a15841f +dist/2024-04-29/rust-std-beta-thumbv8m.main-none-eabi.tar.xz=cb8acdb8920983c03b9495cf3506a3014384b4d2f6a53e7907924d38a0baf7f0 +dist/2024-04-29/rust-std-beta-thumbv8m.main-none-eabihf.tar.gz=9dd2e5ce7534ab4fbb93ff652196e877f4e9eea3863920c3d34a05d9a3598c81 +dist/2024-04-29/rust-std-beta-thumbv8m.main-none-eabihf.tar.xz=4b6e962facf7c54846965a8d6880e4a980804459151f2e22ac5af79bc79e26bb +dist/2024-04-29/rust-std-beta-wasm32-unknown-emscripten.tar.gz=731603392b6e3d36b3a4956928d084e293ef18c8b8593efa756e753a2a309709 +dist/2024-04-29/rust-std-beta-wasm32-unknown-emscripten.tar.xz=8b681b3af47855eb63c4ffe06a2bc6bc4f365354ffbc171ce8cbd8c2a3588a07 +dist/2024-04-29/rust-std-beta-wasm32-unknown-unknown.tar.gz=7b87e59391493c3147c03794061111e25bdae669aea58190a951cdef111e75e0 +dist/2024-04-29/rust-std-beta-wasm32-unknown-unknown.tar.xz=d15eaadb101027906c2fce15b95a3f820bdbc4cf145b705bafc2ac5291289c3b +dist/2024-04-29/rust-std-beta-wasm32-wasi.tar.gz=07390ec742b79ec11b2c3ec65f60efe5d7c616f50c33058fce346f6e9ad21af3 +dist/2024-04-29/rust-std-beta-wasm32-wasi.tar.xz=79e34d46621c298cadb98c00ce3b25d97474aec300d85255153b47e21b7bb744 +dist/2024-04-29/rust-std-beta-wasm32-wasip1-threads.tar.gz=b916dc9051b0278f820ea0b093db3ecae2e27de641ef67a9b508df75dc92c938 +dist/2024-04-29/rust-std-beta-wasm32-wasip1-threads.tar.xz=2867922a39da3b02ebdb93fb78b010695daf468f87485ad8ab79c7f3eeb18b11 +dist/2024-04-29/rust-std-beta-wasm32-wasip1.tar.gz=792b718c0a72e97ba85a17ba67ee09e55b85de829fe4021f828ce54ff8cb31e0 +dist/2024-04-29/rust-std-beta-wasm32-wasip1.tar.xz=abff86499119bddfeda9059004549941dbcd3d911702d4a9c198b94f60e60f4e +dist/2024-04-29/rust-std-beta-x86_64-apple-darwin.tar.gz=0bcc7698efafb42a37f20815f5660e39829a42a2776304e7129d0a4ec0c7520b +dist/2024-04-29/rust-std-beta-x86_64-apple-darwin.tar.xz=c437626e250b0d06c05dc828ab81d0d2c543ffce4b100567910508974ea50045 +dist/2024-04-29/rust-std-beta-x86_64-apple-ios.tar.gz=7c98c9f491bfc837111769a45c10ce2f1ef73c22377158ef9ae80b38034892c0 +dist/2024-04-29/rust-std-beta-x86_64-apple-ios.tar.xz=f4bda724e6e382e02ddf4e4e7a479120420666a5a1ad3c87a85d4d3c763f2cb2 +dist/2024-04-29/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.gz=01efbb2e48045318e18bfc7b6c190b461a219e81fc1cca6c855bf0c658aef556 +dist/2024-04-29/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.xz=9bff316c6d2fbb3c0889f9ffe4eae496b293fb3afaf8d597155e6badbf0c6a8e +dist/2024-04-29/rust-std-beta-x86_64-linux-android.tar.gz=5da713547a8af2c86da7db5d8aa4c27188dea1089fded81ffbbeb0f78952a10f +dist/2024-04-29/rust-std-beta-x86_64-linux-android.tar.xz=9d6a45d6af395360c63ce97bcfc2f9a2967c708afcd979f17fa447239703a92b +dist/2024-04-29/rust-std-beta-x86_64-pc-solaris.tar.gz=d1a71110bee002c8edfbcc00e0f5eede5afa005b09944bb2cde469c658049e70 +dist/2024-04-29/rust-std-beta-x86_64-pc-solaris.tar.xz=6b8d18c83b9fffdddf9e55c807dc7d5784cc6d7ae90a57c29b87d707f0656964 +dist/2024-04-29/rust-std-beta-x86_64-pc-windows-gnu.tar.gz=28921ee14426f54aa09523547516437130654b2d9814120d286f209666c88533 +dist/2024-04-29/rust-std-beta-x86_64-pc-windows-gnu.tar.xz=7c3125cce30978ca2619e9aab150cb5b9b2535fbb6274d4ac1b1d4342c7b0220 +dist/2024-04-29/rust-std-beta-x86_64-pc-windows-gnullvm.tar.gz=ee5c237f092f8a4ba797c4c7769dfd4da81b5c86d2f4b88704d127642d222a22 +dist/2024-04-29/rust-std-beta-x86_64-pc-windows-gnullvm.tar.xz=30c84b04bd2d4d33abf1875cfee5f227ef6484edc67b3cc4c9c96d92c8406d6f +dist/2024-04-29/rust-std-beta-x86_64-pc-windows-msvc.tar.gz=81274050e72c5a8ffdead83f7be62434f35a65517a1b3c6f7d9d14d0d59da710 +dist/2024-04-29/rust-std-beta-x86_64-pc-windows-msvc.tar.xz=215e20c78a2a4edf9b8368a29a09af5f4cf8d0edd1995de3bbf2eff01127cab7 +dist/2024-04-29/rust-std-beta-x86_64-unknown-freebsd.tar.gz=340131cba121827a9753e19cb3a4b9ba2ebe30569fb20d7f9300b4dbe2a15cf4 +dist/2024-04-29/rust-std-beta-x86_64-unknown-freebsd.tar.xz=69626178bc5309afc8a02c941bd77e70e1aa6917ffb6bf0d67a57d921b5c664a +dist/2024-04-29/rust-std-beta-x86_64-unknown-fuchsia.tar.gz=22c6c90533dad3a731ad8a6696e6cdc1b15579e25c658fa2b094185e1893934f +dist/2024-04-29/rust-std-beta-x86_64-unknown-fuchsia.tar.xz=30d7ef6684fa98e28037b69d4220cba40489c23e80fe7793c98b388dc161757d +dist/2024-04-29/rust-std-beta-x86_64-unknown-illumos.tar.gz=9d7192d32eaa6b6ccb0f615da0f4cd80827ba6484eabeaf401d8217678f1e313 +dist/2024-04-29/rust-std-beta-x86_64-unknown-illumos.tar.xz=7a3fb35e0bb252d5f90773136d1417c26d5601beadb77d6da6f5ad3081977f07 +dist/2024-04-29/rust-std-beta-x86_64-unknown-linux-gnu.tar.gz=e987635519c1edc8a1d147ca4a86283637e4dbd0a49736b01d605e45a3a14e8f +dist/2024-04-29/rust-std-beta-x86_64-unknown-linux-gnu.tar.xz=c3ab6b97dccc0038c68494b03b6d444d534e447226a2b2e140af54c94fca0b2d +dist/2024-04-29/rust-std-beta-x86_64-unknown-linux-gnux32.tar.gz=72e8113687be8f947c50befb42b0957dd564f01693cf4d68d749a9e074032ada +dist/2024-04-29/rust-std-beta-x86_64-unknown-linux-gnux32.tar.xz=867b24f33b19f40727c71818c8a002718d44d4cd4ceca44314331e19c1adc1a4 +dist/2024-04-29/rust-std-beta-x86_64-unknown-linux-musl.tar.gz=f9b0fd9605bd4e264f5303bd740d9a0195bc147132969965b221f9da0d7875bf +dist/2024-04-29/rust-std-beta-x86_64-unknown-linux-musl.tar.xz=022dcf4887df41d776ba2666858b9aaab479758134a71f7c6b2172ed7c1a1752 +dist/2024-04-29/rust-std-beta-x86_64-unknown-linux-ohos.tar.gz=b5ff4a0ecd7e0f71a9557b6096bb907e5cbc8982431f0d9b01d8e1a895d8b37e +dist/2024-04-29/rust-std-beta-x86_64-unknown-linux-ohos.tar.xz=e40d5bfb46aadf6faf849df548154db3f35f356f8b98037a056802a235922b8a +dist/2024-04-29/rust-std-beta-x86_64-unknown-netbsd.tar.gz=57cfb1fa472dd9c01fc0caf605a55b7248375d616acf84ec12f6430d5e07e2ee +dist/2024-04-29/rust-std-beta-x86_64-unknown-netbsd.tar.xz=e4121f060b917c811d971e85ce02495e83150ddcceb2204615edff24bd55bfa6 +dist/2024-04-29/rust-std-beta-x86_64-unknown-none.tar.gz=d63559803c8eb47e0d10d9f3a2284477b570a2536bb541762774271451e1f0ce +dist/2024-04-29/rust-std-beta-x86_64-unknown-none.tar.xz=5388cf8ecaa234d507e505e8c6d433c5de8811b2717aa254e4caac9f4aa6cd97 +dist/2024-04-29/rust-std-beta-x86_64-unknown-redox.tar.gz=0f027163f37618df4330ecd82afece432b0a509ab20333d7b787c0d139ea89c2 +dist/2024-04-29/rust-std-beta-x86_64-unknown-redox.tar.xz=b1c722e894b145c2183183fa58762c64402fac077419dc7874f8b08eee665651 +dist/2024-04-29/rust-std-beta-x86_64-unknown-uefi.tar.gz=24e2ac0d44619ef9b76cb1af6178103d65ab12e2677b366e8aee0604798fe5f1 +dist/2024-04-29/rust-std-beta-x86_64-unknown-uefi.tar.xz=1d8a45f1bfe6650edc5ddfc8683190eff5a74384abcb2f73eb3d1e88d566ccfc +dist/2024-04-29/rustc-beta-aarch64-apple-darwin.tar.gz=ea113c567692d54983ab6c376761651b6dcf9bedad5b5d822d28c0d0d0733cf2 +dist/2024-04-29/rustc-beta-aarch64-apple-darwin.tar.xz=e36363f1ea531d2fd563f471758e387de37a34e7ef6f4c12175979657333c5b4 +dist/2024-04-29/rustc-beta-aarch64-pc-windows-msvc.tar.gz=52d77d540fc3f83d82f35f358ccd9055fb75453af3e3bee4b11636742559db13 +dist/2024-04-29/rustc-beta-aarch64-pc-windows-msvc.tar.xz=843c56f5431c1feda85ceaeef0daf988e8ae020b3556326fb1f75ea7968bf2df +dist/2024-04-29/rustc-beta-aarch64-unknown-linux-gnu.tar.gz=ba2fe37dda1a487a2c75151895f4f6e886e9476a992272ce26e9b5fd7adb11f9 +dist/2024-04-29/rustc-beta-aarch64-unknown-linux-gnu.tar.xz=ccb7be3935de1920509d2061d38f92f1fb8d2a5dd6cef392492242a929363fa9 +dist/2024-04-29/rustc-beta-aarch64-unknown-linux-musl.tar.gz=40636e0936bd311803317825c5fb6b446cdb5536ada1db097b567df04a86d7dd +dist/2024-04-29/rustc-beta-aarch64-unknown-linux-musl.tar.xz=804ef68f24bc0ba5150177d8b8515daa54aa82fcb61472385ef1a1d897c5c3e1 +dist/2024-04-29/rustc-beta-arm-unknown-linux-gnueabi.tar.gz=a320c2869d1d2c92b698397d4467c8498cad9481f38d28ac810bd165399ca46b +dist/2024-04-29/rustc-beta-arm-unknown-linux-gnueabi.tar.xz=7ce92211d87068d9c223806929adc34ca611a1321cd58b5bd81aabb0ec3ff085 +dist/2024-04-29/rustc-beta-arm-unknown-linux-gnueabihf.tar.gz=79c16b902884301882d16be36fe75ecb32a8e49abde0038ce21cfbee883c2c3a +dist/2024-04-29/rustc-beta-arm-unknown-linux-gnueabihf.tar.xz=9384eb9bdbb585b414b6c04c592a79e90a0c0ebfeeb970e5e1b920cb638807cc +dist/2024-04-29/rustc-beta-armv7-unknown-linux-gnueabihf.tar.gz=ff99de5b819a4fb9adce9386a309b9841bd33632eb7d5079415a6ca6fc86b9dd +dist/2024-04-29/rustc-beta-armv7-unknown-linux-gnueabihf.tar.xz=55635cde13af11dd8cc007d2e0499bfee493bdfba87b6efd7b1fa4115f5728dc +dist/2024-04-29/rustc-beta-i686-pc-windows-gnu.tar.gz=de82ac745275f069225b84574ed145afaf9f54abde5246592e49d5d1cf40cac1 +dist/2024-04-29/rustc-beta-i686-pc-windows-gnu.tar.xz=a8a7bf64d33c95a2f94265fba8dd9ac50bbb727f4bc3e79be5bf61212cb5d22b +dist/2024-04-29/rustc-beta-i686-pc-windows-msvc.tar.gz=88967a99c993d6e0c3c7948308510644286ac826266dbd3d89aaa083100711db +dist/2024-04-29/rustc-beta-i686-pc-windows-msvc.tar.xz=1804f75786482946258ff0e827274357c49e90a7f2f568add7353249f2ab78b9 +dist/2024-04-29/rustc-beta-i686-unknown-linux-gnu.tar.gz=3cb7e02c61d4a21d8289289b874b25e8b020c1d553e5af950160bffc14f51c18 +dist/2024-04-29/rustc-beta-i686-unknown-linux-gnu.tar.xz=2ad4b1311a0e39c359798375912faa91b4e13cd473bd59efd1e4f721777d254f +dist/2024-04-29/rustc-beta-loongarch64-unknown-linux-gnu.tar.gz=ab19efb741a127615b9022dedf1d895b53c69740cc3da745f9b9888bade9d98b +dist/2024-04-29/rustc-beta-loongarch64-unknown-linux-gnu.tar.xz=492cc11d54df410c2547890803930fc65950e6b81ced512e24bef56c3e70f3d2 +dist/2024-04-29/rustc-beta-powerpc-unknown-linux-gnu.tar.gz=c5a631a41f417336f3f65c85adefd1fb0bacc02465485f37d29fc1223c9f6cec +dist/2024-04-29/rustc-beta-powerpc-unknown-linux-gnu.tar.xz=0701183b615d9eec9daea724d4cd8fa98dede2260cfb6b137d6cbf8ad6b29a4f +dist/2024-04-29/rustc-beta-powerpc64-unknown-linux-gnu.tar.gz=cb70e92d5275862b500614d79eaea3d19319b96798f4850cb19dea9a8038a651 +dist/2024-04-29/rustc-beta-powerpc64-unknown-linux-gnu.tar.xz=908cbe562d82cca1bf176fdc99af867966ea423d244c4a50e14bad19f6878201 +dist/2024-04-29/rustc-beta-powerpc64le-unknown-linux-gnu.tar.gz=8580a3eb6d6df1774f4b6ca06dc1195c42b1e2a463488a5d851e99b0ca6d0249 +dist/2024-04-29/rustc-beta-powerpc64le-unknown-linux-gnu.tar.xz=2627948036e905f2e280663c56c86c172e2b0d057311ade7ca238953b7e0c36a +dist/2024-04-29/rustc-beta-riscv64gc-unknown-linux-gnu.tar.gz=526e4f129fdb4b2c8f4317c57105a09ff03e71771d6d6bbbc9380917b5440d71 +dist/2024-04-29/rustc-beta-riscv64gc-unknown-linux-gnu.tar.xz=fd9dcf60838376478d7cc505ec7fc39f86f9d042646a3b836e9c06825927c7eb +dist/2024-04-29/rustc-beta-s390x-unknown-linux-gnu.tar.gz=664c1255a9435d1ad086329a3c215974b9302d481762240cc9d0328d9f1b8c9a +dist/2024-04-29/rustc-beta-s390x-unknown-linux-gnu.tar.xz=a585ce7684e4174f03adb09df17221e1729e8179dbc91b9a0f8813c3ecc0822d +dist/2024-04-29/rustc-beta-x86_64-apple-darwin.tar.gz=59a1d91009b506a5bce3c276993cb8acfd71f73d01f9eaf4195b36114ac822c3 +dist/2024-04-29/rustc-beta-x86_64-apple-darwin.tar.xz=f86f3309cf2784b076f14e7da9e921c294a7701ea92d378c609061deccbc6bff +dist/2024-04-29/rustc-beta-x86_64-pc-windows-gnu.tar.gz=f5c074461409b33a9791325d4014e6861ad36f99b9e48e54ecceb73986450be1 +dist/2024-04-29/rustc-beta-x86_64-pc-windows-gnu.tar.xz=045431eec6f839b1c40b5a75c5000f80bd6351274a59b29d962833495324ecb6 +dist/2024-04-29/rustc-beta-x86_64-pc-windows-msvc.tar.gz=a3abfb68e60544170f47209bbf048f1374e5bb75901a529e2ac2f315758155f8 +dist/2024-04-29/rustc-beta-x86_64-pc-windows-msvc.tar.xz=398c41a3219781c7cf1a907406506526b672abca6d3ab59c30556390a5f992c9 +dist/2024-04-29/rustc-beta-x86_64-unknown-freebsd.tar.gz=38895e615efd0bf75ca14b0ab0a085527cca64fae17631d1780a8f51acd26d17 +dist/2024-04-29/rustc-beta-x86_64-unknown-freebsd.tar.xz=786f40030dbe5e6897aafe4bda44770920b2010b93fc5ce86574774e531e2eff +dist/2024-04-29/rustc-beta-x86_64-unknown-illumos.tar.gz=7003cab7650dae7e3d29032422a57782a2c146024c437a6466ae1dd2b61a6618 +dist/2024-04-29/rustc-beta-x86_64-unknown-illumos.tar.xz=bed3cc10203e8bd4d43b6245928c8a607acc5b6e633635caea45eb4eef4bda56 +dist/2024-04-29/rustc-beta-x86_64-unknown-linux-gnu.tar.gz=84cdea91c9f1e848ea17f554229ca80d18d093fc609641d8f003c4f2d4871866 +dist/2024-04-29/rustc-beta-x86_64-unknown-linux-gnu.tar.xz=a20fce7512f7c8cc6230a0f63f12855b04370d25e621183f71aa444c90c36b4b +dist/2024-04-29/rustc-beta-x86_64-unknown-linux-musl.tar.gz=87e0c484ade99efab57c655ef96dbabf7a02314540575b65a14372ab5496c36c +dist/2024-04-29/rustc-beta-x86_64-unknown-linux-musl.tar.xz=469757d8f35c9f4210aefd2ba660ee249e4409d47b908a6c68c1e650ee81ae67 +dist/2024-04-29/rustc-beta-x86_64-unknown-netbsd.tar.gz=4a38000480fe78fd5da7f9b71d36f296a6ae103254d932c4de6b902354e86bbf +dist/2024-04-29/rustc-beta-x86_64-unknown-netbsd.tar.xz=45945d6af237fe4c91fde7db02ca19e99bac56a911b8db79be9b6ab8bb3934e1 +dist/2024-04-29/rustc-nightly-aarch64-apple-darwin.tar.gz=0b07375a9a6507fd4932a05b5aaf28ed349fe2040103f1cb69c8a2494437258f +dist/2024-04-29/rustc-nightly-aarch64-apple-darwin.tar.xz=143bd7ed3ca7b913ddd0cea7cda8d1a0e4c29cc2ccbb7d29f0e45c2a87c3ec46 +dist/2024-04-29/rustc-nightly-aarch64-pc-windows-msvc.tar.gz=9404c111b91fd092367b88adbc37dce10a98c443bd8d9e13a860e1fb4e3af96e +dist/2024-04-29/rustc-nightly-aarch64-pc-windows-msvc.tar.xz=f9f432907c276edcae5ad8ade0264f3c03109be02e791a814edc8ad3d229637a +dist/2024-04-29/rustc-nightly-aarch64-unknown-linux-gnu.tar.gz=33425c90427424f0b30fa2a6331a3b59c680f1c1bd0d8845d7e6bc1e2f80292d +dist/2024-04-29/rustc-nightly-aarch64-unknown-linux-gnu.tar.xz=03792890c64c72f30143849894b15f0eb3d6ad735fceede9092abd900ee733e4 +dist/2024-04-29/rustc-nightly-aarch64-unknown-linux-musl.tar.gz=cf6f2bffa0db1b4b9b8e95801bf415dcce413f902e26f4c1831dff1a00752b99 +dist/2024-04-29/rustc-nightly-aarch64-unknown-linux-musl.tar.xz=9192fdb668df8d4cab776623db7d01e35af42fea94098c1d4ba53190825d81a8 +dist/2024-04-29/rustc-nightly-arm-unknown-linux-gnueabi.tar.gz=a174e7e08da2abc6b84499360670188f5cc61b6d055967e04bf602ff3d831f45 +dist/2024-04-29/rustc-nightly-arm-unknown-linux-gnueabi.tar.xz=5a59811027586863852b15fc2b603e7e69b19841f4c10d2527ef1fc5b77d8af2 +dist/2024-04-29/rustc-nightly-arm-unknown-linux-gnueabihf.tar.gz=645bb5dd7a96bb9292b9956cb9705e9aed2408e47728f245564f1f7404ede783 +dist/2024-04-29/rustc-nightly-arm-unknown-linux-gnueabihf.tar.xz=1fe34911b082c3a5ca4f24656675c095d2cf56f8005be9ca2517d0ef7d0a2b37 +dist/2024-04-29/rustc-nightly-armv7-unknown-linux-gnueabihf.tar.gz=f2d6403d81bb0afe2e14956828987a0bb044c95f2d9566e1d792dd922dad7914 +dist/2024-04-29/rustc-nightly-armv7-unknown-linux-gnueabihf.tar.xz=d93fdafcbbfd50c88c3f4feb4c68b053882ccae02c45e1615aeeae5a86f4aa98 +dist/2024-04-29/rustc-nightly-i686-pc-windows-gnu.tar.gz=a9e997b03559b3dfa2a0eba6ed7a142d7651ea7f4ba4e788d9de807b50558e58 +dist/2024-04-29/rustc-nightly-i686-pc-windows-gnu.tar.xz=4412b5fbfab8c5b31e57cf8c4ce9a9d13cfc9c0a8174ea1fc8a7c05281e1cb54 +dist/2024-04-29/rustc-nightly-i686-pc-windows-msvc.tar.gz=1725c41500dbf6bea554f3d4acaba70167f0e89087aaa3eb3c0f8a99047c55c4 +dist/2024-04-29/rustc-nightly-i686-pc-windows-msvc.tar.xz=27db022494afebbe05605f134191e8b2e78bfdeaa638d4215174038ca9dd2fd7 +dist/2024-04-29/rustc-nightly-i686-unknown-linux-gnu.tar.gz=dc1a05d49b773dba06808c1c50653ecac506b3433f0f6dfa307109a7c621cc1a +dist/2024-04-29/rustc-nightly-i686-unknown-linux-gnu.tar.xz=cc58ce3af8f5481ada4dc129079cd558664717526b2f7f9a02bde6bafb6f45ad +dist/2024-04-29/rustc-nightly-loongarch64-unknown-linux-gnu.tar.gz=34cfe803126ae9218b17adfe833a55c697dfa50729ac83b642529f3682d12d15 +dist/2024-04-29/rustc-nightly-loongarch64-unknown-linux-gnu.tar.xz=c752dc8962656c09047151fd24166f3134fbeed85006b5d22496691079c7fb9c +dist/2024-04-29/rustc-nightly-powerpc-unknown-linux-gnu.tar.gz=386b086b8aad922050c813dd58bb79a52ef806b2d1413e2e9cc46d6e43b81d7c +dist/2024-04-29/rustc-nightly-powerpc-unknown-linux-gnu.tar.xz=d9eec9ab7c265444ac5f04d4ec9e77d4c0c3c2e34c5804db8abf5f94c8fd2272 +dist/2024-04-29/rustc-nightly-powerpc64-unknown-linux-gnu.tar.gz=91df129046443554bfb836d25886aa9807b917acbc9dcf30f6531cde7bf912fa +dist/2024-04-29/rustc-nightly-powerpc64-unknown-linux-gnu.tar.xz=ca9b574b9f2e914b5a6d9e011aba805d1e6f9b687dc1a1868e88f0e4d9e4401c +dist/2024-04-29/rustc-nightly-powerpc64le-unknown-linux-gnu.tar.gz=8b44f96a1ccd6d501b0af3960edb2c1a6c93957676a1c2cdb831e614de398f8b +dist/2024-04-29/rustc-nightly-powerpc64le-unknown-linux-gnu.tar.xz=f8a10a6767b80bf24f73223b9e46e1b18b6bf6746ad2115eb8968a0e482f0e4e +dist/2024-04-29/rustc-nightly-riscv64gc-unknown-linux-gnu.tar.gz=a197208807503a9cfbc6df938d614a192da48884b2e4892f7b1d234579091be1 +dist/2024-04-29/rustc-nightly-riscv64gc-unknown-linux-gnu.tar.xz=af3a1a33942bd8a3417593dc118abb1db0373f5410f54771713c05bb86724fed +dist/2024-04-29/rustc-nightly-s390x-unknown-linux-gnu.tar.gz=5a3a3aa73b6a0f21c63b9a40bdbd0bb4dc59bd75add0a06e292ced791fad31be +dist/2024-04-29/rustc-nightly-s390x-unknown-linux-gnu.tar.xz=6d7903f1c9fc95a23448717326d667dce59e54aaff821443d3cd9137cf3537fb +dist/2024-04-29/rustc-nightly-x86_64-apple-darwin.tar.gz=64eede54da4bf88b0a42ecf7f7a4bf8002b5550e60a64e1e48244c7f5b04768c +dist/2024-04-29/rustc-nightly-x86_64-apple-darwin.tar.xz=0a8f95e3bb0bebf9bcc8116b91bab3ba97cb6ff4021713586280aaceed9da030 +dist/2024-04-29/rustc-nightly-x86_64-pc-windows-gnu.tar.gz=58f9e0dd9c1aadde2dfd869528adadd4acc29ab0850236f3cee5f023d4211939 +dist/2024-04-29/rustc-nightly-x86_64-pc-windows-gnu.tar.xz=a211a962093e0d09358d51a6eb48da0966a02383c6b00c8acc077b5663d7d707 +dist/2024-04-29/rustc-nightly-x86_64-pc-windows-msvc.tar.gz=5631926874dc54204c319137a77a89de5e6f408de2a832109e2be71ea79f27d1 +dist/2024-04-29/rustc-nightly-x86_64-pc-windows-msvc.tar.xz=a8cf87bc663b5e3dbcc97b0eb58bb1b9b5b0100aacb47dc0c372fe1612517244 +dist/2024-04-29/rustc-nightly-x86_64-unknown-freebsd.tar.gz=1011f98197a9fe82d6095f4521934a06eea5f7e9719a6e4c9e3bf13d68f799ca +dist/2024-04-29/rustc-nightly-x86_64-unknown-freebsd.tar.xz=79599b3f91f9372262e97a417f4e104ef5192c0f6f8df204aea9c8b3ee39430e +dist/2024-04-29/rustc-nightly-x86_64-unknown-illumos.tar.gz=7179a453bdcb17e401c0af8f4ab86cb5a4752a8ec80b0cbdd4cf1854c7f36a35 +dist/2024-04-29/rustc-nightly-x86_64-unknown-illumos.tar.xz=d565fc366fdbc305fbfe59e72b971c58f201d69e03a9ffa667d2ca0735cdb7f3 +dist/2024-04-29/rustc-nightly-x86_64-unknown-linux-gnu.tar.gz=ae6bd8e20560d48519290d78e3d21f84b983403ca1f8f466a85496276d7866da +dist/2024-04-29/rustc-nightly-x86_64-unknown-linux-gnu.tar.xz=c7c0f8f44b0275456a27952178caa04c32eb9a1507056ddc05926a0730e17359 +dist/2024-04-29/rustc-nightly-x86_64-unknown-linux-musl.tar.gz=3246797ddbc9118de819b13b005b83748338f3c825a7436ebd5aa79ca55539c0 +dist/2024-04-29/rustc-nightly-x86_64-unknown-linux-musl.tar.xz=c7e784e77dbabedad88d24d2ae6dc4abb68bc04b1cd6c9d45f6dc28b6d0e2edc +dist/2024-04-29/rustc-nightly-x86_64-unknown-netbsd.tar.gz=c9452de4b3f15f0cf0b7d737b217b2cc7b88a96543bd8ce587ee14be1e21a90a +dist/2024-04-29/rustc-nightly-x86_64-unknown-netbsd.tar.xz=de9b05278a5c69d53ccbb31223526ea2aa2275c0fb3f046d1c1b4d67c0b0c275 +dist/2024-04-29/rustfmt-nightly-aarch64-apple-darwin.tar.gz=3734353a58dbf6c3831cc6b4ea606357140c191c89e8dfca1d7aa2f3fb8ac53d +dist/2024-04-29/rustfmt-nightly-aarch64-apple-darwin.tar.xz=e5e3a6e609fbfd537aa4acfefd3681d4b6c8029e2801a1ef23e8b09cf5a47bfe +dist/2024-04-29/rustfmt-nightly-aarch64-pc-windows-msvc.tar.gz=22f54857e01d759301d099b67547cdc485596499088d0d749d38058c28e0f752 +dist/2024-04-29/rustfmt-nightly-aarch64-pc-windows-msvc.tar.xz=db48a9d45dc7c7aad4c9bb0d20789dd35fb6ef7a966948c44fbbae132de4c16b +dist/2024-04-29/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.gz=fa5d1fb9f3627e7d59269a1f8008d780c685ea04975473f1808287134e7bc5a7 +dist/2024-04-29/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.xz=61ab625b47fa9097af90a79a1e75a2f2492a415f4009c9043cf453bd4128f031 +dist/2024-04-29/rustfmt-nightly-aarch64-unknown-linux-musl.tar.gz=cc79969341fc60991059d0e3f13a69489c1e0915ea5787a88b8605ed5b7f3cd0 +dist/2024-04-29/rustfmt-nightly-aarch64-unknown-linux-musl.tar.xz=bbdb75f922b4b1716b033d91c76c4c0aa53061d6e7fa53a9bf16fe076814bbb2 +dist/2024-04-29/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.gz=13ca68afc3f3970a37951504664b58035102e1ae06d10a744389603b2f7499f5 +dist/2024-04-29/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.xz=04b174aa724945b6359a555892506c6a742a7c427464e8206433bb3f9a65fc02 +dist/2024-04-29/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.gz=430333380a590a9de211c8d735989fedb89321cf9f5f9a0b1ef651ec8b598691 +dist/2024-04-29/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.xz=924713e648806945cd56e54d4c11dc74b65241c8dbf6cc7b401c5c93d0f7ffdb +dist/2024-04-29/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.gz=bb6e5a8b5cc88099e613aa5f4d926165976d8e4a7fccbecf4ac3b0eb966d7a0f +dist/2024-04-29/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.xz=34d5e970304e1734aacb26c095e926c27a07e1a41fe70db9fa2997bef97ad3ec +dist/2024-04-29/rustfmt-nightly-i686-pc-windows-gnu.tar.gz=835447a1d9d60659e99903275f327641809fc0148f35149f980d1a17ff87cc9a +dist/2024-04-29/rustfmt-nightly-i686-pc-windows-gnu.tar.xz=ddd84a7f900aa239f93711f7da71e57aaedeeba2c9c8a8f23608acc7e48613c0 +dist/2024-04-29/rustfmt-nightly-i686-pc-windows-msvc.tar.gz=02f0af2bdae167c6091099a9b54ceb150c22b0f20dc861587a02cac78deb0b39 +dist/2024-04-29/rustfmt-nightly-i686-pc-windows-msvc.tar.xz=822f78f39dcbe3282bf7888a8cdae04efe7b023ded026a7e7f430e4ff15e7942 +dist/2024-04-29/rustfmt-nightly-i686-unknown-linux-gnu.tar.gz=68a6189652c11a2c142c5339e2f5fb09d5f3e85d860bff063f62d5d3a3d111bf +dist/2024-04-29/rustfmt-nightly-i686-unknown-linux-gnu.tar.xz=6740ea882effa2fb87dd72744c08888ce5ec59c9797c00369156b24847bb180e +dist/2024-04-29/rustfmt-nightly-loongarch64-unknown-linux-gnu.tar.gz=0bb365e2d895ef3c39c4899a01187a23f9b7c5195c30bf845da3917f62f5eafd +dist/2024-04-29/rustfmt-nightly-loongarch64-unknown-linux-gnu.tar.xz=2e54c9887bc6ed1eb09b9f69c8425da843ea12bf33248fa0ccdc0d14387c1c57 +dist/2024-04-29/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.gz=b0c0fe437921d17e2f50cbff87beeac067efa3d5211a241fb6f4c10b8ab500ac +dist/2024-04-29/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.xz=64e7282c0cf4a714b11eed1d28be3a64ba0ccc6d899211a872a5a7809d514c08 +dist/2024-04-29/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.gz=100cfde057c81460b8cfde2047fe83ddde360a6df1ff178da5a968b17ecc9df8 +dist/2024-04-29/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.xz=38e8712e98fa0bc6962ab2fd2e3b96a2a5dcaa6c16161d8caf71131a1ca5031e +dist/2024-04-29/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.gz=4dab52b50e19348fb39fdad39ab44189c27c10f80b5fbe2cc4723b644611fa87 +dist/2024-04-29/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.xz=36d1b2c9150fafc5976c296200ba3fac3e923df3e6f18032068200e2a887146c +dist/2024-04-29/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.gz=7cb4a536320c23d305ce3bd3b7a954d951bf4d358ef3732be75b9b290c4818a5 +dist/2024-04-29/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.xz=ede1afc7dc5892ef6f780e987737e145c4b4d00495da8c2e9902182a3a174e20 +dist/2024-04-29/rustfmt-nightly-s390x-unknown-linux-gnu.tar.gz=e2d2d561cbfa0add0e5349682976216d3a7cff4094372c1ed26854bb4e4d93fd +dist/2024-04-29/rustfmt-nightly-s390x-unknown-linux-gnu.tar.xz=e0380e65e83e4131f6aa7ee4e185689add4372b0c1653312e2ffd56072fdd0fe +dist/2024-04-29/rustfmt-nightly-x86_64-apple-darwin.tar.gz=73a140c7ed9c80f209ff976c63b0a34d625d651553c38692c91f048f4e0ae470 +dist/2024-04-29/rustfmt-nightly-x86_64-apple-darwin.tar.xz=9946b7120465181e05916b8023bc075b32bd85cf45a3b1d8bfba2f94ac78d927 +dist/2024-04-29/rustfmt-nightly-x86_64-pc-windows-gnu.tar.gz=eda273f27714b1e45adcc2388149f48de0e32a9104db0b9d1a02f6d37de43fef +dist/2024-04-29/rustfmt-nightly-x86_64-pc-windows-gnu.tar.xz=f2955a4b696d050c219a96c093162b42a2fab921f9f3cb7570f8462928306c6d +dist/2024-04-29/rustfmt-nightly-x86_64-pc-windows-msvc.tar.gz=ec900cc2d3c6d45ef039653f4418f9b9a4a5fddd5d7e8077c3fb08b36c539a28 +dist/2024-04-29/rustfmt-nightly-x86_64-pc-windows-msvc.tar.xz=04e6999a3405acc79f5fdcafeeab52880e5eeeedd3909b5f3c57e7647c86ef99 +dist/2024-04-29/rustfmt-nightly-x86_64-unknown-freebsd.tar.gz=0730c5ebd576fec5371085f9fac0adde9424e1d7626456ed33bc66351b0ad307 +dist/2024-04-29/rustfmt-nightly-x86_64-unknown-freebsd.tar.xz=90cbd84b8d48f0235a1954166f5edd53dc3031532ec6dfcb364f9a9624c9ce11 +dist/2024-04-29/rustfmt-nightly-x86_64-unknown-illumos.tar.gz=5f5c62d321db27eb495f6ea312ef8bea0bf17a7a501a44e062986c416951700f +dist/2024-04-29/rustfmt-nightly-x86_64-unknown-illumos.tar.xz=a3bf64e2f22436e4484fc818f69d2f750fddd05a96463fd4abfcf655edce36b9 +dist/2024-04-29/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.gz=a847a6f9c7a3ce71c7cd8d81bdfcfcd8e4d128aa28ba0dafea89b0cc37c6c36c +dist/2024-04-29/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.xz=21fa794456566c64d08f629a385f89b3cfe9d9b69f317ae85fbe7425419108ff +dist/2024-04-29/rustfmt-nightly-x86_64-unknown-linux-musl.tar.gz=b3f792f10a98993b4b55d1df951727a4422102d51b1145e51824268d48587ad0 +dist/2024-04-29/rustfmt-nightly-x86_64-unknown-linux-musl.tar.xz=d791f0ec3c004e7baa0381962bf8ca2f18a3c861152702de5301d0149260e7fa +dist/2024-04-29/rustfmt-nightly-x86_64-unknown-netbsd.tar.gz=9807b2887e976d29f0c04484f8459175b4f6b70ef000037cdc4dada48e3cbd74 +dist/2024-04-29/rustfmt-nightly-x86_64-unknown-netbsd.tar.xz=019920d64778af62879e2146c2c13d9f6e2165a38bbfa1982694bfb48864d308 \ No newline at end of file diff --git a/src/tools/bump-stage0/src/main.rs b/src/tools/bump-stage0/src/main.rs index bd97b4eaa3e4d..1999859ff9883 100644 --- a/src/tools/bump-stage0/src/main.rs +++ b/src/tools/bump-stage0/src/main.rs @@ -3,13 +3,12 @@ use curl::easy::Easy; use indexmap::IndexMap; use std::collections::HashMap; -const PATH: &str = "src/stage0.json"; +const PATH: &str = "src/stage0"; const COMPILER_COMPONENTS: &[&str] = &["rustc", "rust-std", "cargo", "clippy-preview"]; const RUSTFMT_COMPONENTS: &[&str] = &["rustfmt-preview", "rustc"]; struct Tool { config: Config, - comments: Vec, channel: Channel, date: Option, @@ -35,37 +34,111 @@ impl Tool { .try_into() .map_err(|_| anyhow::anyhow!("failed to parse version"))?; - let existing: Stage0 = serde_json::from_slice(&std::fs::read(PATH)?)?; + // let existing: Stage0 = serde_json::from_slice(&std::fs::read(PATH)?)?; + let existing = Self::parse_stage0_file()?; Ok(Self { channel, version, date, config: existing.config, - comments: existing.comments, checksums: IndexMap::new(), }) } - fn update_json(mut self) -> Result<(), Error> { - std::fs::write( - PATH, - format!( - "{}\n", - serde_json::to_string_pretty(&Stage0 { - compiler: self.detect_compiler()?, - rustfmt: self.detect_rustfmt()?, - checksums_sha256: { - // Keys are sorted here instead of beforehand because values in this map - // are added while filling the other struct fields just above this block. - self.checksums.sort_keys(); - self.checksums - }, - config: self.config, - comments: self.comments, - })? - ), - )?; + fn parse_stage0_file() -> Result { + let stage0_content = include_str!("../../../stage0"); + + let mut stage0 = Stage0::default(); + + for line in stage0_content.lines() { + let line = line.trim(); + + if line.is_empty() { + continue; + } + + // Ignore comments + if line.starts_with('#') { + continue; + } + + let key_value: Vec<&str> = line.splitn(2, '=').collect(); + let (key, value) = (*key_value.get(0).unwrap(), *key_value.get(1).unwrap()); + + match key { + "dist_server" => stage0.config.dist_server = value.to_owned(), + "artifacts_server" + | "artifacts_with_llvm_assertions_server" + | "git_merge_commit_email" + | "git_repository" + | "nightly_branch" => { + stage0.config.other.insert(key.to_owned(), value.to_owned()); + } + + "compiler_date" => stage0.compiler.date = value.to_owned(), + "compiler_version" => stage0.compiler.version = value.to_owned(), + + "rustfmt_date" => { + let mut rustfmt = stage0.rustfmt.unwrap_or(Stage0Toolchain::default()); + rustfmt.date = value.to_owned(); + stage0.rustfmt = Some(rustfmt); + } + "rustfmt_version" => { + let mut rustfmt = stage0.rustfmt.unwrap_or(Stage0Toolchain::default()); + rustfmt.version = value.to_owned(); + stage0.rustfmt = Some(rustfmt); + } + + dist if dist.starts_with("dist") => { + stage0.checksums_sha256.insert(key.to_owned(), value.to_owned()); + } + + unsupported => { + println!("'{unsupported}' field is not supported."); + } + } + } + + Ok(stage0) + } + + fn update_stage0_file(mut self) -> Result<(), Error> { + const HEADER: &str = r#"# The configuration above this comment is editable, and can be changed +# by forks of the repository if they have alternate values. +# +# The section below is generated by `./x.py run src/tools/bump-stage0`, +# run that command again to update the bootstrap compiler. +# +# All changes below this comment will be overridden the next time the +# tool is executed. + "#; + + let mut file_content = HEADER.to_owned(); + file_content.push_str(&format!("\ndist_server={}", self.config.dist_server)); + + for (key, value) in &self.config.other { + file_content.push_str(&format!("\n{}={}", key, value.as_str())); + } + + file_content.push_str("\n"); + + let compiler = self.detect_compiler()?; + file_content.push_str(&format!("\ncompiler_date={}", compiler.date)); + file_content.push_str(&format!("\ncompiler_version={}", compiler.version)); + + if let Some(rustfmt) = self.detect_rustfmt()? { + file_content.push_str(&format!("\nrustfmt_date={}", rustfmt.date)); + file_content.push_str(&format!("\nrustfmt_version={}", rustfmt.version)); + } + + file_content.push_str("\n"); + + for (key, value) in self.checksums { + file_content.push_str(&format!("\n{}={}", key, value)); + } + + std::fs::write(PATH, file_content)?; Ok(()) } @@ -143,7 +216,7 @@ impl Tool { fn main() -> Result<(), Error> { let tool = Tool::new(std::env::args().nth(1))?; - tool.update_json()?; + tool.update_stage0_file()?; Ok(()) } @@ -180,37 +253,26 @@ enum Channel { Nightly, } -#[derive(Debug, serde::Serialize, serde::Deserialize)] +#[derive(Debug, Default, serde::Serialize, serde::Deserialize)] struct Stage0 { config: Config, - // Comments are explicitly below the config, do not move them above. - // - // Downstream forks of the compiler codebase can change the configuration values defined above, - // but doing so would risk merge conflicts whenever they import new changes that include a - // bootstrap compiler bump. - // - // To lessen the pain, a big block of comments is placed between the configuration and the - // auto-generated parts of the file, preventing git diffs of the config to include parts of the - // auto-generated content and vice versa. This should prevent merge conflicts. - #[serde(rename = "__comments")] - comments: Vec, compiler: Stage0Toolchain, rustfmt: Option, checksums_sha256: IndexMap, } -#[derive(Debug, serde::Serialize, serde::Deserialize)] +#[derive(Debug, Default, serde::Serialize, serde::Deserialize)] struct Config { dist_server: String, - // There are other fields in the configuration, which will be read by src/bootstrap or other - // tools consuming stage0.json. To avoid the need to update bump-stage0 every time a new field - // is added, we collect all the fields in an untyped Value and serialize them back with the - // same order and structure they were deserialized in. + /// There are other fields in the configuration, which will be read by src/bootstrap or other + /// tools consuming stage0 file. To avoid the need to update bump-stage0 every time a new field + /// is added, we collect all the fields in `IndexMap` and serialize them back with the + /// same order and structure they were deserialized in. #[serde(flatten)] - other: serde_json::Value, + other: IndexMap, } -#[derive(Debug, serde::Serialize, serde::Deserialize)] +#[derive(Debug, Default, serde::Serialize, serde::Deserialize)] struct Stage0Toolchain { date: String, version: String, From efb153eb5a85499e71c424af9261e4b339c83c5e Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Thu, 9 May 2024 16:49:51 +0300 Subject: [PATCH 023/179] awk stage0 file on CI Signed-off-by: onur-ozkan --- .github/workflows/dependencies.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dependencies.yml b/.github/workflows/dependencies.yml index f4e409e0d4910..03584aed08d94 100644 --- a/.github/workflows/dependencies.yml +++ b/.github/workflows/dependencies.yml @@ -56,7 +56,7 @@ jobs: - name: install the bootstrap toolchain run: | # Extract the stage0 version - TOOLCHAIN=$(jq -r '.compiler | {version,date} | join("-")' -- src/stage0.json) + TOOLCHAIN=$(awk -F= '{a[$1]=$2} END {print(a["compiler_version"] "-" a["compiler_date"])}' src/stage0) # Install and set as default rustup toolchain install --no-self-update --profile minimal $TOOLCHAIN rustup default $TOOLCHAIN From f2d50b6d36f6c1a2b00c7dc6dcbcbc422957c443 Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Thu, 9 May 2024 17:26:35 +0300 Subject: [PATCH 024/179] use stage0 file in `bootstrap.py` Signed-off-by: onur-ozkan --- src/bootstrap/bootstrap.py | 38 ++++++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py index e464e444fea20..e60e8f0aa1f70 100644 --- a/src/bootstrap/bootstrap.py +++ b/src/bootstrap/bootstrap.py @@ -3,7 +3,6 @@ import contextlib import datetime import hashlib -import json import os import re import shutil @@ -52,7 +51,7 @@ def get(base, url, path, checksums, verbose=False): try: if url not in checksums: - raise RuntimeError(("src/stage0.json doesn't contain a checksum for {}. " + raise RuntimeError(("src/stage0 doesn't contain a checksum for {}. " "Pre-built artifacts might not be available for this " "target at this time, see https://doc.rust-lang.org/nightly" "/rustc/platform-support.html for more information.") @@ -421,9 +420,9 @@ def output(filepath): class Stage0Toolchain: - def __init__(self, stage0_payload): - self.date = stage0_payload["date"] - self.version = stage0_payload["version"] + def __init__(self, date, version): + self.date = date + self.version = version def channel(self): return self.version + "-" + self.date @@ -439,7 +438,7 @@ def __init__( bin_root, tarball_path, tarball_suffix, - checksums_sha256, + stage0_data, pattern, verbose, ): @@ -448,7 +447,7 @@ def __init__( self.bin_root = bin_root self.tarball_path = tarball_path self.tarball_suffix = tarball_suffix - self.checksums_sha256 = checksums_sha256 + self.stage0_data = stage0_data self.pattern = pattern self.verbose = verbose @@ -458,7 +457,7 @@ def download_component(download_info): download_info.base_download_url, download_info.download_path, download_info.tarball_path, - download_info.checksums_sha256, + download_info.stage0_data, verbose=download_info.verbose, ) @@ -510,11 +509,12 @@ def __init__(self, config_toml="", args=None): build_dir = args.build_dir or self.get_toml('build-dir', 'build') or 'build' self.build_dir = os.path.abspath(build_dir) - with open(os.path.join(self.rust_root, "src", "stage0.json")) as f: - data = json.load(f) - self.checksums_sha256 = data["checksums_sha256"] - self.stage0_compiler = Stage0Toolchain(data["compiler"]) - self.download_url = os.getenv("RUSTUP_DIST_SERVER") or data["config"]["dist_server"] + self.stage0_data = parse_stage0_file(os.path.join(self.rust_root, "src", "stage0")) + self.stage0_compiler = Stage0Toolchain( + self.stage0_data["compiler_date"], + self.stage0_data["compiler_version"] + ) + self.download_url = os.getenv("RUSTUP_DIST_SERVER") or self.stage0_data["dist_server"] self.build = args.build or self.build_triple() @@ -581,7 +581,7 @@ def download_toolchain(self): bin_root=self.bin_root(), tarball_path=os.path.join(rustc_cache, filename), tarball_suffix=tarball_suffix, - checksums_sha256=self.checksums_sha256, + stage0_data=self.stage0_data, pattern=pattern, verbose=self.verbose, ) @@ -1071,6 +1071,16 @@ def parse_args(args): return parser.parse_known_args(args)[0] +def parse_stage0_file(path): + result = {} + with open(path, 'r') as file: + for line in file: + line = line.strip() + if line and not line.startswith('#'): + key, value = line.split('=', 1) + result[key.strip()] = value.strip() + return result + def bootstrap(args): """Configure, fetch, build and run the initial bootstrap""" rust_root = os.path.abspath(os.path.join(__file__, '../../..')) From c21c5baad9e8404777297705b6e55c0abcc7e6d9 Mon Sep 17 00:00:00 2001 From: Kevin Reid Date: Thu, 9 May 2024 16:58:25 -0700 Subject: [PATCH 025/179] Document proper usage of `fmt::Error` and `fmt()`'s `Result`. Documentation of these properties previously existed in a lone paragraph in the `fmt` module's documentation: However, users looking to implement a formatting trait won't necessarily look there. Therefore, let's add the critical information (that formatting per se is infallible) to all the involved items. --- library/alloc/src/fmt.rs | 2 +- library/core/src/fmt/fmt_trait_method_doc.md | 8 ++++ library/core/src/fmt/mod.rs | 42 +++++++++++++------- 3 files changed, 36 insertions(+), 16 deletions(-) create mode 100644 library/core/src/fmt/fmt_trait_method_doc.md diff --git a/library/alloc/src/fmt.rs b/library/alloc/src/fmt.rs index b9918752540f3..d7dc6ae6694b5 100644 --- a/library/alloc/src/fmt.rs +++ b/library/alloc/src/fmt.rs @@ -403,7 +403,7 @@ //! is, a formatting implementation must and may only return an error if the //! passed-in [`Formatter`] returns an error. This is because, contrary to what //! the function signature might suggest, string formatting is an infallible -//! operation. This function only returns a result because writing to the +//! operation. This function only returns a [`Result`] because writing to the //! underlying stream might fail and it must provide a way to propagate the fact //! that an error has occurred back up the stack. //! diff --git a/library/core/src/fmt/fmt_trait_method_doc.md b/library/core/src/fmt/fmt_trait_method_doc.md new file mode 100644 index 0000000000000..493d929243d2d --- /dev/null +++ b/library/core/src/fmt/fmt_trait_method_doc.md @@ -0,0 +1,8 @@ +Formats the value using the given formatter. + +# Errors + +This function should return [`Err`] if, and only if, the provided [`Formatter`] returns [`Err`]. +String formatting is considered an infallible operation; this function only +returns a [`Result`] because writing to the underlying stream might fail and it must +provide a way to propagate the fact that an error has occurred back up the stack. diff --git a/library/core/src/fmt/mod.rs b/library/core/src/fmt/mod.rs index ce0643a3f5ef5..9b372eac52455 100644 --- a/library/core/src/fmt/mod.rs +++ b/library/core/src/fmt/mod.rs @@ -72,14 +72,24 @@ pub type Result = result::Result<(), Error>; /// The error type which is returned from formatting a message into a stream. /// /// This type does not support transmission of an error other than that an error -/// occurred. Any extra information must be arranged to be transmitted through -/// some other means. -/// -/// An important thing to remember is that the type `fmt::Error` should not be +/// occurred. This is because, despite the existence of this error, +/// string formatting is considered an infallible operation. +/// `fmt()` implementors should not return this `Error` unless they received it from their +/// [`Formatter`]. The only time your code should create a new instance of this +/// error is when implementing `fmt::Write`, in order to cancel the formatting operation when +/// writing to the underlying stream fails. +/// +/// Any extra information must be arranged to be transmitted through some other means, +/// such as storing it in a field to be consulted after the formatting operation has been +/// cancelled. (For example, this is how [`std::io::Write::write_fmt()`] propagates IO errors +/// during writing.) +/// +/// This type, `fmt::Error`, should not be /// confused with [`std::io::Error`] or [`std::error::Error`], which you may also /// have in scope. /// /// [`std::io::Error`]: ../../std/io/struct.Error.html +/// [`std::io::Write::write_fmt()`]: ../../std/io/trait.Write.html#method.write_fmt /// [`std::error::Error`]: ../../std/error/trait.Error.html /// /// # Examples @@ -118,8 +128,10 @@ pub trait Write { /// This function will return an instance of [`std::fmt::Error`][Error] on error. /// /// The purpose of that error is to abort the formatting operation when the underlying - /// destination encounters some error preventing it from accepting more text; it should - /// generally be propagated rather than handled, at least when implementing formatting traits. + /// destination encounters some error preventing it from accepting more text; + /// in particular, it does not communicate any information about *what* error occurred. + /// It should generally be propagated rather than handled, at least when implementing + /// formatting traits. /// /// # Examples /// @@ -586,7 +598,7 @@ impl Display for Arguments<'_> { #[rustc_diagnostic_item = "Debug"] #[rustc_trivial_field_reads] pub trait Debug { - /// Formats the value using the given formatter. + #[doc = include_str!("fmt_trait_method_doc.md")] /// /// # Examples /// @@ -703,7 +715,7 @@ pub use macros::Debug; #[rustc_diagnostic_item = "Display"] #[stable(feature = "rust1", since = "1.0.0")] pub trait Display { - /// Formats the value using the given formatter. + #[doc = include_str!("fmt_trait_method_doc.md")] /// /// # Examples /// @@ -777,7 +789,7 @@ pub trait Display { /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub trait Octal { - /// Formats the value using the given formatter. + #[doc = include_str!("fmt_trait_method_doc.md")] #[stable(feature = "rust1", since = "1.0.0")] fn fmt(&self, f: &mut Formatter<'_>) -> Result; } @@ -836,7 +848,7 @@ pub trait Octal { /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub trait Binary { - /// Formats the value using the given formatter. + #[doc = include_str!("fmt_trait_method_doc.md")] #[stable(feature = "rust1", since = "1.0.0")] fn fmt(&self, f: &mut Formatter<'_>) -> Result; } @@ -891,7 +903,7 @@ pub trait Binary { /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub trait LowerHex { - /// Formats the value using the given formatter. + #[doc = include_str!("fmt_trait_method_doc.md")] #[stable(feature = "rust1", since = "1.0.0")] fn fmt(&self, f: &mut Formatter<'_>) -> Result; } @@ -946,7 +958,7 @@ pub trait LowerHex { /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub trait UpperHex { - /// Formats the value using the given formatter. + #[doc = include_str!("fmt_trait_method_doc.md")] #[stable(feature = "rust1", since = "1.0.0")] fn fmt(&self, f: &mut Formatter<'_>) -> Result; } @@ -997,7 +1009,7 @@ pub trait UpperHex { #[stable(feature = "rust1", since = "1.0.0")] #[rustc_diagnostic_item = "Pointer"] pub trait Pointer { - /// Formats the value using the given formatter. + #[doc = include_str!("fmt_trait_method_doc.md")] #[stable(feature = "rust1", since = "1.0.0")] fn fmt(&self, f: &mut Formatter<'_>) -> Result; } @@ -1048,7 +1060,7 @@ pub trait Pointer { /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub trait LowerExp { - /// Formats the value using the given formatter. + #[doc = include_str!("fmt_trait_method_doc.md")] #[stable(feature = "rust1", since = "1.0.0")] fn fmt(&self, f: &mut Formatter<'_>) -> Result; } @@ -1099,7 +1111,7 @@ pub trait LowerExp { /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub trait UpperExp { - /// Formats the value using the given formatter. + #[doc = include_str!("fmt_trait_method_doc.md")] #[stable(feature = "rust1", since = "1.0.0")] fn fmt(&self, f: &mut Formatter<'_>) -> Result; } From 0a67bf1b8a30f1fd540a577602c699d650366355 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 9 May 2024 22:45:14 -0400 Subject: [PATCH 026/179] Make builtin_deref just return a Ty --- src/base.rs | 7 ++----- src/intrinsics/mod.rs | 6 +++--- src/intrinsics/simd.rs | 2 +- src/lib.rs | 2 +- src/num.rs | 10 +++------- src/unsize.rs | 2 +- src/value_and_place.rs | 2 +- src/vtable.rs | 2 +- 8 files changed, 13 insertions(+), 20 deletions(-) diff --git a/src/base.rs b/src/base.rs index e3d050df4cd1b..8874efadec9d9 100644 --- a/src/base.rs +++ b/src/base.rs @@ -670,11 +670,8 @@ fn codegen_stmt<'tcx>( let to_ty = fx.monomorphize(to_ty); fn is_fat_ptr<'tcx>(fx: &FunctionCx<'_, '_, 'tcx>, ty: Ty<'tcx>) -> bool { - ty.builtin_deref(true).is_some_and( - |ty::TypeAndMut { ty: pointee_ty, mutbl: _ }| { - has_ptr_meta(fx.tcx, pointee_ty) - }, - ) + ty.builtin_deref(true) + .is_some_and(|pointee_ty| has_ptr_meta(fx.tcx, pointee_ty)) } if is_fat_ptr(fx, from_ty) { diff --git a/src/intrinsics/mod.rs b/src/intrinsics/mod.rs index 79a90507fa2e1..cafdc051db5ac 100644 --- a/src/intrinsics/mod.rs +++ b/src/intrinsics/mod.rs @@ -586,7 +586,7 @@ fn codegen_regular_intrinsic_call<'tcx>( intrinsic_args!(fx, args => (base, offset); intrinsic); let offset = offset.load_scalar(fx); - let pointee_ty = base.layout().ty.builtin_deref(true).unwrap().ty; + let pointee_ty = base.layout().ty.builtin_deref(true).unwrap(); let pointee_size = fx.layout_of(pointee_ty).size.bytes(); let ptr_diff = if pointee_size != 1 { fx.bcx.ins().imul_imm(offset, pointee_size as i64) @@ -610,7 +610,7 @@ fn codegen_regular_intrinsic_call<'tcx>( let val = val.load_scalar(fx); let count = count.load_scalar(fx); - let pointee_ty = dst.layout().ty.builtin_deref(true).unwrap().ty; + let pointee_ty = dst.layout().ty.builtin_deref(true).unwrap(); let pointee_size = fx.layout_of(pointee_ty).size.bytes(); let count = if pointee_size != 1 { fx.bcx.ins().imul_imm(count, pointee_size as i64) @@ -715,7 +715,7 @@ fn codegen_regular_intrinsic_call<'tcx>( // Cranelift treats loads as volatile by default // FIXME correctly handle unaligned_volatile_load - let inner_layout = fx.layout_of(ptr.layout().ty.builtin_deref(true).unwrap().ty); + let inner_layout = fx.layout_of(ptr.layout().ty.builtin_deref(true).unwrap()); let val = CValue::by_ref(Pointer::new(ptr.load_scalar(fx)), inner_layout); ret.write_cvalue(fx, val); } diff --git a/src/intrinsics/simd.rs b/src/intrinsics/simd.rs index 67f9d83106294..452b5988dab4c 100644 --- a/src/intrinsics/simd.rs +++ b/src/intrinsics/simd.rs @@ -974,7 +974,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( intrinsic_args!(fx, args => (ptr, offset); intrinsic); let (lane_count, ptr_lane_ty) = ptr.layout().ty.simd_size_and_type(fx.tcx); - let pointee_ty = ptr_lane_ty.builtin_deref(true).unwrap().ty; + let pointee_ty = ptr_lane_ty.builtin_deref(true).unwrap(); let pointee_size = fx.layout_of(pointee_ty).size.bytes(); let (ret_lane_count, ret_lane_ty) = ret.layout().ty.simd_size_and_type(fx.tcx); let ret_lane_layout = fx.layout_of(ret_lane_ty); diff --git a/src/lib.rs b/src/lib.rs index c9f84b6999718..e72951b6f3447 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -95,7 +95,7 @@ mod prelude { pub(crate) use rustc_middle::mir::{self, *}; pub(crate) use rustc_middle::ty::layout::{LayoutOf, TyAndLayout}; pub(crate) use rustc_middle::ty::{ - self, FloatTy, Instance, InstanceDef, IntTy, ParamEnv, Ty, TyCtxt, TypeAndMut, UintTy, + self, FloatTy, Instance, InstanceDef, IntTy, ParamEnv, Ty, TyCtxt, UintTy, }; pub(crate) use rustc_span::Span; pub(crate) use rustc_target::abi::{Abi, FieldIdx, Scalar, Size, VariantIdx, FIRST_VARIANT}; diff --git a/src/num.rs b/src/num.rs index 714858084ec9d..4d96a26ea4fa8 100644 --- a/src/num.rs +++ b/src/num.rs @@ -388,12 +388,8 @@ pub(crate) fn codegen_ptr_binop<'tcx>( in_lhs: CValue<'tcx>, in_rhs: CValue<'tcx>, ) -> CValue<'tcx> { - let is_thin_ptr = in_lhs - .layout() - .ty - .builtin_deref(true) - .map(|TypeAndMut { ty, mutbl: _ }| !has_ptr_meta(fx.tcx, ty)) - .unwrap_or(true); + let is_thin_ptr = + in_lhs.layout().ty.builtin_deref(true).map(|ty| !has_ptr_meta(fx.tcx, ty)).unwrap_or(true); if is_thin_ptr { match bin_op { @@ -404,7 +400,7 @@ pub(crate) fn codegen_ptr_binop<'tcx>( codegen_compare_bin_op(fx, bin_op, false, lhs, rhs) } BinOp::Offset => { - let pointee_ty = in_lhs.layout().ty.builtin_deref(true).unwrap().ty; + let pointee_ty = in_lhs.layout().ty.builtin_deref(true).unwrap(); let (base, offset) = (in_lhs, in_rhs.load_scalar(fx)); let pointee_size = fx.layout_of(pointee_ty).size.bytes(); let ptr_diff = fx.bcx.ins().imul_imm(offset, pointee_size as i64); diff --git a/src/unsize.rs b/src/unsize.rs index f33bacb99a3fa..4acbc8a27edb9 100644 --- a/src/unsize.rs +++ b/src/unsize.rs @@ -127,7 +127,7 @@ pub(crate) fn coerce_unsized_into<'tcx>( let dst_ty = dst.layout().ty; let mut coerce_ptr = || { let (base, info) = - if fx.layout_of(src.layout().ty.builtin_deref(true).unwrap().ty).is_unsized() { + if fx.layout_of(src.layout().ty.builtin_deref(true).unwrap()).is_unsized() { let (old_base, old_info) = src.load_scalar_pair(fx); unsize_ptr(fx, old_base, src.layout(), dst.layout(), Some(old_info)) } else { diff --git a/src/value_and_place.rs b/src/value_and_place.rs index dded6df7771df..a11abd0c0e978 100644 --- a/src/value_and_place.rs +++ b/src/value_and_place.rs @@ -819,7 +819,7 @@ impl<'tcx> CPlace<'tcx> { } pub(crate) fn place_deref(self, fx: &mut FunctionCx<'_, '_, 'tcx>) -> CPlace<'tcx> { - let inner_layout = fx.layout_of(self.layout().ty.builtin_deref(true).unwrap().ty); + let inner_layout = fx.layout_of(self.layout().ty.builtin_deref(true).unwrap()); if has_ptr_meta(fx.tcx, inner_layout.ty) { let (addr, extra) = self.to_cvalue(fx).load_scalar_pair(fx); CPlace::for_ptr_with_extra(Pointer::new(addr), extra, inner_layout) diff --git a/src/vtable.rs b/src/vtable.rs index 04e24320f9131..14c607ccad7d7 100644 --- a/src/vtable.rs +++ b/src/vtable.rs @@ -59,7 +59,7 @@ pub(crate) fn get_ptr_and_method_ref<'tcx>( if let ty::Ref(_, ty, _) = arg.layout().ty.kind() { if ty.is_dyn_star() { - let inner_layout = fx.layout_of(arg.layout().ty.builtin_deref(true).unwrap().ty); + let inner_layout = fx.layout_of(arg.layout().ty.builtin_deref(true).unwrap()); let dyn_star = CPlace::for_ptr(Pointer::new(arg.load_scalar(fx)), inner_layout); let ptr = dyn_star.place_field(fx, FieldIdx::ZERO).to_ptr(); let vtable = From c9fb74e08eeadcaa67f60bb7b07120a1e6c5f412 Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Fri, 10 May 2024 16:06:38 +0300 Subject: [PATCH 027/179] check if `x test tests` missing any test directory Signed-off-by: onur-ozkan --- src/bootstrap/src/core/builder/tests.rs | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/bootstrap/src/core/builder/tests.rs b/src/bootstrap/src/core/builder/tests.rs index 9898d495c023d..9710365ef114d 100644 --- a/src/bootstrap/src/core/builder/tests.rs +++ b/src/bootstrap/src/core/builder/tests.rs @@ -128,6 +128,26 @@ fn validate_path_remap() { }); } +#[test] +fn check_missing_paths_for_x_test_tests() { + let build = Build::new(configure("test", &["A-A"], &["A-A"])); + + let (_, tests_remap_paths) = + PATH_REMAP.iter().find(|(target_path, _)| *target_path == "tests").unwrap(); + + let tests_dir = fs::read_dir(build.src.join("tests")).unwrap(); + for dir in tests_dir { + let path = dir.unwrap().path(); + + // Skip if not a test directory. + if path.ends_with("tests/auxiliary") || !path.is_dir() { + continue + } + + assert!(tests_remap_paths.iter().any(|item| path.ends_with(*item)), "{} is missing in PATH_REMAP tests list.", path.display()); + } +} + #[test] fn test_exclude() { let mut config = configure("test", &["A-A"], &["A-A"]); From 569e547f189ed0aae49ef1902f6a485b0aa4275f Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Fri, 10 May 2024 16:06:56 +0300 Subject: [PATCH 028/179] remap missing path `tests/crashes` to `tests` Signed-off-by: onur-ozkan --- src/bootstrap/src/core/builder.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/bootstrap/src/core/builder.rs b/src/bootstrap/src/core/builder.rs index 8d7e53d2440bc..1d5dc0dddc063 100644 --- a/src/bootstrap/src/core/builder.rs +++ b/src/bootstrap/src/core/builder.rs @@ -322,6 +322,7 @@ const PATH_REMAP: &[(&str, &[&str])] = &[ "tests/codegen-units", "tests/coverage", "tests/coverage-run-rustdoc", + "tests/crashes", "tests/debuginfo", "tests/incremental", "tests/mir-opt", From 0a0b40a9e001ce67f7bfbb7b050cd55223023d87 Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Fri, 10 May 2024 16:16:05 +0300 Subject: [PATCH 029/179] add "tidy-alphabetical" check on "tests" remap list Signed-off-by: onur-ozkan --- src/bootstrap/src/core/builder.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/bootstrap/src/core/builder.rs b/src/bootstrap/src/core/builder.rs index 1d5dc0dddc063..feffa89e8a579 100644 --- a/src/bootstrap/src/core/builder.rs +++ b/src/bootstrap/src/core/builder.rs @@ -317,6 +317,7 @@ const PATH_REMAP: &[(&str, &[&str])] = &[ ( "tests", &[ + // tidy-alphabetical-start "tests/assembly", "tests/codegen", "tests/codegen-units", @@ -338,6 +339,7 @@ const PATH_REMAP: &[(&str, &[&str])] = &[ "tests/rustdoc-ui", "tests/ui", "tests/ui-fulldeps", + // tidy-alphabetical-end ], ), ]; From 2bb25d3f4ac8796a50f45409f3ef461ce83295f3 Mon Sep 17 00:00:00 2001 From: Ben Kimock Date: Fri, 10 May 2024 12:27:49 -0400 Subject: [PATCH 030/179] Handle Deref expressions in invalid_reference_casting --- compiler/rustc_lint/src/reference_casting.rs | 6 ++++-- tests/ui/lint/reference_casting.rs | 7 +++++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_lint/src/reference_casting.rs b/compiler/rustc_lint/src/reference_casting.rs index b80e90c25a334..34153e3a220d3 100644 --- a/compiler/rustc_lint/src/reference_casting.rs +++ b/compiler/rustc_lint/src/reference_casting.rs @@ -202,8 +202,10 @@ fn is_cast_to_bigger_memory_layout<'tcx>( // if the current expr looks like this `&mut expr[index]` then just looking // at `expr[index]` won't give us the underlying allocation, so we just skip it - // the same logic applies field access like `&mut expr.field` - if let ExprKind::Index(..) | ExprKind::Field(..) = e_alloc.kind { + // the same logic applies field access `&mut expr.field` and reborrows `&mut *expr`. + if let ExprKind::Index(..) | ExprKind::Field(..) | ExprKind::Unary(UnOp::Deref, ..) = + e_alloc.kind + { return None; } diff --git a/tests/ui/lint/reference_casting.rs b/tests/ui/lint/reference_casting.rs index 87a682249b00f..87fa42f94775e 100644 --- a/tests/ui/lint/reference_casting.rs +++ b/tests/ui/lint/reference_casting.rs @@ -261,6 +261,13 @@ unsafe fn bigger_layout() { let ptr = r as *mut i32 as *mut Vec3; unsafe { *ptr = Vec3(0, 0, 0) } } + + unsafe fn deref(v: &mut Vec3) { + let r = &mut v.0; + let r = &mut *r; + let ptr = &mut *(r as *mut i32 as *mut Vec3); + unsafe { *ptr = Vec3(0, 0, 0) } + } } const RAW_PTR: *mut u8 = 1 as *mut u8; From 4f76f1069af505ce72535bda8d10e44dd81e65a5 Mon Sep 17 00:00:00 2001 From: Jules Bertholet Date: Tue, 30 Apr 2024 16:14:20 -0400 Subject: [PATCH 031/179] Match ergonomics 2024: let `&` patterns eat `&mut` --- compiler/rustc_hir_typeck/src/pat.rs | 184 +++++++++++++----- .../ref_pat_eat_one_layer_2024.rs | 6 + .../ref_pat_eat_one_layer_2024_fail.rs | 16 +- .../ref_pat_eat_one_layer_2024_fail.stderr | 68 +++++-- ...mismatch.rs => ref_pat_everywhere-fail.rs} | 6 +- tests/ui/match/ref_pat_everywhere-fail.stderr | 38 ++++ ..._pat_everywhere-mutability-mismatch.stderr | 44 ----- tests/ui/match/ref_pat_everywhere.rs | 6 + 8 files changed, 247 insertions(+), 121 deletions(-) rename tests/ui/match/{ref_pat_everywhere-mutability-mismatch.rs => ref_pat_everywhere-fail.rs} (63%) create mode 100644 tests/ui/match/ref_pat_everywhere-fail.stderr delete mode 100644 tests/ui/match/ref_pat_everywhere-mutability-mismatch.stderr diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index fe2deee378e2c..99653814d6fd6 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -78,7 +78,7 @@ struct TopInfo<'tcx> { #[derive(Copy, Clone)] struct PatInfo<'tcx, 'a> { binding_mode: ByRef, - max_ref_mutbl: Mutability, + max_ref_mutbl: MutblCap, top_info: TopInfo<'tcx>, decl_origin: Option>, @@ -124,6 +124,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> { } /// Mode for adjusting the expected type and binding mode. +#[derive(Clone, Copy, Debug, PartialEq, Eq)] enum AdjustMode { /// Peel off all immediate reference types. Peel, @@ -135,11 +136,44 @@ enum AdjustMode { /// and if the old biding mode was by-reference /// with mutability matching the pattern, /// mark the pattern as having consumed this reference. - ResetAndConsumeRef(Mutability), + /// + /// `Span` is that of the inside of the reference pattern + ResetAndConsumeRef(Mutability, Span), /// Pass on the input binding mode and expected type. Pass, } +/// `ref mut` patterns (explicit or match-ergonomics) +/// are not allowed behind an `&` reference. +/// +/// This includes explicit `ref mut` behind `&` patterns +/// that match against `&mut` references, +/// where the code would have compiled +/// had the pattern been written as `&mut`. +/// However, the borrow checker will not catch +/// this last case, so we need to throw an error ourselves. +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +enum MutblCap { + /// Mutability restricted to immutable; + /// contained span, if present, should be shown in diagnostics as the reason. + Not(Option), + /// No restriction on mutability + Mut, +} + +impl MutblCap { + fn cap_mutbl_to_not(self, span: Option) -> Self { + if self == MutblCap::Mut { MutblCap::Not(span) } else { self } + } + + fn as_mutbl(self) -> Mutability { + match self { + MutblCap::Not(_) => Mutability::Not, + MutblCap::Mut => Mutability::Mut, + } + } +} + impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// Type check the given top level pattern against the `expected` type. /// @@ -160,7 +194,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let info = TopInfo { expected, origin_expr, span }; let pat_info = PatInfo { binding_mode: ByRef::No, - max_ref_mutbl: Mutability::Mut, + max_ref_mutbl: MutblCap::Mut, top_info: info, decl_origin, current_depth: 0, @@ -201,8 +235,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { PatKind::Never => expected, PatKind::Lit(lt) => self.check_pat_lit(pat.span, lt, expected, ti), PatKind::Range(lhs, rhs, _) => self.check_pat_range(pat.span, lhs, rhs, expected, ti), - PatKind::Binding(ba, var_id, _, sub) => { - self.check_pat_ident(pat, ba, var_id, sub, expected, pat_info) + PatKind::Binding(ba, var_id, ident, sub) => { + self.check_pat_ident(pat, ba, var_id, ident, sub, expected, pat_info) } PatKind::TupleStruct(ref qpath, subpats, ddpos) => { self.check_pat_tuple_struct(pat, qpath, subpats, ddpos, expected, pat_info) @@ -294,20 +328,29 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expected: Ty<'tcx>, def_br: ByRef, adjust_mode: AdjustMode, - max_ref_mutbl: Mutability, - ) -> (Ty<'tcx>, ByRef, Mutability, bool) { - if let ByRef::Yes(mutbl) = def_br { - debug_assert!(mutbl <= max_ref_mutbl); + max_ref_mutbl: MutblCap, + ) -> (Ty<'tcx>, ByRef, MutblCap, bool) { + if let ByRef::Yes(Mutability::Mut) = def_br { + debug_assert!(max_ref_mutbl == MutblCap::Mut); } match adjust_mode { AdjustMode::Pass => (expected, def_br, max_ref_mutbl, false), - AdjustMode::Reset => (expected, ByRef::No, Mutability::Mut, false), - AdjustMode::ResetAndConsumeRef(ref_pat_mutbl) => { - let mutbls_match = def_br == ByRef::Yes(ref_pat_mutbl); + AdjustMode::Reset => (expected, ByRef::No, MutblCap::Mut, false), + AdjustMode::ResetAndConsumeRef(ref_pat_mutbl, inner_span) => { + // `&` pattern eats `&mut` + let mutbls_match = + if let ByRef::Yes(def_mut) = def_br { ref_pat_mutbl <= def_mut } else { false }; + if pat.span.at_least_rust_2024() && self.tcx.features().ref_pat_eat_one_layer_2024 { + let max_ref_mutbl = if ref_pat_mutbl == Mutability::Not { + max_ref_mutbl.cap_mutbl_to_not(Some(pat.span.until(inner_span))) + } else { + max_ref_mutbl + }; + if mutbls_match { debug!("consuming inherited reference"); - (expected, ByRef::No, cmp::min(max_ref_mutbl, ref_pat_mutbl), true) + (expected, ByRef::No, max_ref_mutbl, true) } else { let (new_ty, new_bm, max_ref_mutbl) = if ref_pat_mutbl == Mutability::Mut { self.peel_off_references( @@ -318,7 +361,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { max_ref_mutbl, ) } else { - (expected, def_br.cap_ref_mutability(Mutability::Not), Mutability::Not) + (expected, def_br.cap_ref_mutability(Mutability::Not), max_ref_mutbl) }; (new_ty, new_bm, max_ref_mutbl, false) } @@ -385,7 +428,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // ``` // // See issue #46688. - PatKind::Ref(_, mutbl) => AdjustMode::ResetAndConsumeRef(*mutbl), + PatKind::Ref(inner, mutbl) => AdjustMode::ResetAndConsumeRef(*mutbl, inner.span), // A `_` pattern works with any expected type, so there's no need to do anything. PatKind::Wild // A malformed pattern doesn't have an expected type, so let's just accept any type. @@ -411,8 +454,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expected: Ty<'tcx>, mut def_br: ByRef, max_peelable_mutability: Mutability, - mut max_ref_mutability: Mutability, - ) -> (Ty<'tcx>, ByRef, Mutability) { + mut max_ref_mutability: MutblCap, + ) -> (Ty<'tcx>, ByRef, MutblCap) { let mut expected = self.try_structurally_resolve_type(pat.span, expected); // Peel off as many `&` or `&mut` from the scrutinee type as possible. For example, // for `match &&&mut Some(5)` the loop runs three times, aborting when it reaches @@ -446,9 +489,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } if pat.span.at_least_rust_2024() && self.tcx.features().ref_pat_eat_one_layer_2024 { - def_br = def_br.cap_ref_mutability(max_ref_mutability); + def_br = def_br.cap_ref_mutability(max_ref_mutability.as_mutbl()); if def_br == ByRef::Yes(Mutability::Not) { - max_ref_mutability = Mutability::Not; + max_ref_mutability = max_ref_mutability.cap_mutbl_to_not(None); } } @@ -665,8 +708,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { fn check_pat_ident( &self, pat: &'tcx Pat<'tcx>, - ba: BindingMode, + explicit_ba: BindingMode, var_id: HirId, + ident: Ident, sub: Option<&'tcx Pat<'tcx>>, expected: Ty<'tcx>, pat_info: PatInfo<'tcx, '_>, @@ -674,7 +718,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let PatInfo { binding_mode: def_br, top_info: ti, .. } = pat_info; // Determine the binding mode... - let bm = match ba { + let bm = match explicit_ba { BindingMode(ByRef::No, Mutability::Mut) if !(pat.span.at_least_rust_2024() && self.tcx.features().mut_preserve_binding_mode_2024) @@ -690,8 +734,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { BindingMode(ByRef::No, Mutability::Mut) } BindingMode(ByRef::No, mutbl) => BindingMode(def_br, mutbl), - BindingMode(ByRef::Yes(_), _) => ba, + BindingMode(ByRef::Yes(_), _) => explicit_ba, }; + + if bm.0 == ByRef::Yes(Mutability::Mut) + && let MutblCap::Not(Some(and_pat_span)) = pat_info.max_ref_mutbl + { + let mut err = struct_span_code_err!( + self.tcx.dcx(), + ident.span, + E0596, + "cannot bind with `ref mut` behind an `&` pattern" + ); + err.span_help(and_pat_span, "change this `&` pattern to an `&mut`"); + err.emit(); + } + // ...and store it in a side table: self.typeck_results.borrow_mut().pat_binding_modes_mut().insert(pat.hir_id, bm); @@ -717,7 +775,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // If there are multiple arms, make sure they all agree on // what the type of the binding `x` ought to be. if var_id != pat.hir_id { - self.check_binding_alt_eq_ty(ba, pat.span, var_id, local_ty, ti); + self.check_binding_alt_eq_ty(explicit_ba, pat.span, var_id, local_ty, ti); } if let Some(p) = sub { @@ -2117,7 +2175,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } else { let tcx = self.tcx; let expected = self.shallow_resolve(expected); - let (ref_ty, inner_ty) = match self.check_dereferenceable(pat.span, expected, inner) { + let (ref_ty, inner_ty, pat_info) = match self + .check_dereferenceable(pat.span, expected, inner) + { Ok(()) => { // `demand::subtype` would be good enough, but using `eqtype` turns // out to be equally general. See (note_1) for details. @@ -2127,42 +2187,62 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // the bad interactions of the given hack detailed in (note_1). debug!("check_pat_ref: expected={:?}", expected); match *expected.kind() { - ty::Ref(_, r_ty, r_mutbl) if r_mutbl == mutbl => (expected, r_ty), + ty::Ref(_, r_ty, r_mutbl) if r_mutbl == mutbl => (expected, r_ty, pat_info), + + // `&` pattern eats `&mut` reference + ty::Ref(_, r_ty, Mutability::Mut) + if mutbl == Mutability::Not + && ((pat.span.at_least_rust_2024() + && self.tcx.features().ref_pat_eat_one_layer_2024) + || self.tcx.features().ref_pat_everywhere) => + { + ( + expected, + r_ty, + PatInfo { + max_ref_mutbl: pat_info + .max_ref_mutbl + .cap_mutbl_to_not(Some(pat.span.until(inner.span))), + ..pat_info + }, + ) + } + + _ if consumed_inherited_ref && self.tcx.features().ref_pat_everywhere => { + // We already matched against a match-ergonmics inserted reference, + // so we don't need to match against a reference from the original type. + // Save this infor for use in lowering later + self.typeck_results + .borrow_mut() + .skipped_ref_pats_mut() + .insert(pat.hir_id); + (expected, expected, pat_info) + } + _ => { - if consumed_inherited_ref && self.tcx.features().ref_pat_everywhere { - // We already matched against a match-ergonmics inserted reference, - // so we don't need to match against a reference from the original type. - // Save this infor for use in lowering later - self.typeck_results - .borrow_mut() - .skipped_ref_pats_mut() - .insert(pat.hir_id); - (expected, expected) - } else { - let inner_ty = self.next_ty_var(inner.span); - let ref_ty = self.new_ref_ty(pat.span, mutbl, inner_ty); - debug!("check_pat_ref: demanding {:?} = {:?}", expected, ref_ty); - let err = self.demand_eqtype_pat_diag( - pat.span, - expected, - ref_ty, - pat_info.top_info, - ); + let inner_ty = self.next_ty_var(inner.span); + let ref_ty = self.new_ref_ty(pat.span, mutbl, inner_ty); + debug!("check_pat_ref: demanding {:?} = {:?}", expected, ref_ty); + let err = self.demand_eqtype_pat_diag( + pat.span, + expected, + ref_ty, + pat_info.top_info, + ); - // Look for a case like `fn foo(&foo: u32)` and suggest - // `fn foo(foo: &u32)` - if let Some(mut err) = err { - self.borrow_pat_suggestion(&mut err, pat); - err.emit(); - } - (ref_ty, inner_ty) + // Look for a case like `fn foo(&foo: u32)` and suggest + // `fn foo(foo: &u32)` + if let Some(mut err) = err { + self.borrow_pat_suggestion(&mut err, pat); + err.emit(); } + (ref_ty, inner_ty, pat_info) } } } Err(guar) => { let err = Ty::new_error(tcx, guar); - (err, err) + (err, err, pat_info) } }; self.check_pat(inner, inner_ty, pat_info); diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024.rs b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024.rs index f1ac3e340e915..62e4f82a3ffbb 100644 --- a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024.rs +++ b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024.rs @@ -53,6 +53,12 @@ pub fn main() { if let Some(&Some(Some(&x))) = &Some(Some(&mut Some(0))) { let _: u32 = x; } + if let Some(&Some(&x)) = Some(&Some(&mut 0)) { + let _: u32 = x; + } + if let Some(&Some(x)) = &mut Some(Some(0)) { + let _: u32 = x; + } let &mut x = &&mut 0; let _: &u32 = x; diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.rs b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.rs index ec091bb17467d..61e6171945826 100644 --- a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.rs +++ b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.rs @@ -14,16 +14,24 @@ pub fn main() { let _: &mut u32 = x; //~^ ERROR: mismatched types } - if let Some(&Some(&_)) = Some(&Some(&mut 0)) { - //~^ ERROR: mismatched types - } if let Some(&Some(&mut _)) = &mut Some(&Some(0)) { //~^ ERROR: mismatched types } if let Some(&Some(Some((&mut _)))) = &Some(Some(&mut Some(0))) { //~^ ERROR: mismatched types } - + if let Some(&mut Some(x)) = &Some(Some(0)) { + //~^ ERROR: mismatched types + } + if let Some(&Some(ref mut x)) = &mut Some(Some(0)) { + //~^ ERROR: cannot bind with `ref mut` behind an `&` pattern + } + if let &Some(Some(ref mut x)) = &mut Some(Some(0)) { + //~^ ERROR: cannot bind with `ref mut` behind an `&` pattern + } + if let Some(&mut Some(x)) = &Some(Some(0)) { + //~^ ERROR: mismatched types + } let &mut _= &&0; //~^ ERROR: mismatched types diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.stderr b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.stderr index be71ee606c767..2aa2e2851ced8 100644 --- a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.stderr +++ b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.stderr @@ -34,17 +34,6 @@ LL | let _: &mut u32 = x; error[E0308]: mismatched types --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:17:23 | -LL | if let Some(&Some(&_)) = Some(&Some(&mut 0)) { - | ^^ ------------------- this expression has type `Option<&Option<&mut {integer}>>` - | | - | types differ in mutability - | - = note: expected mutable reference `&mut {integer}` - found reference `&_` - -error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:20:23 - | LL | if let Some(&Some(&mut _)) = &mut Some(&Some(0)) { | ^^^^^^ ------------------- this expression has type `&mut Option<&Option<{integer}>>` | | @@ -54,7 +43,7 @@ LL | if let Some(&Some(&mut _)) = &mut Some(&Some(0)) { found mutable reference `&mut _` error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:23:29 + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:20:29 | LL | if let Some(&Some(Some((&mut _)))) = &Some(Some(&mut Some(0))) { | ^^^^^^ ------------------------- this expression has type `&Option>>` @@ -65,7 +54,53 @@ LL | if let Some(&Some(Some((&mut _)))) = &Some(Some(&mut Some(0))) { found mutable reference `&mut _` error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:28:9 + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:23:17 + | +LL | if let Some(&mut Some(x)) = &Some(Some(0)) { + | ^^^^^^^^^^^^ -------------- this expression has type `&Option>` + | | + | expected `Option<{integer}>`, found `&mut _` + | + = note: expected enum `Option<{integer}>` + found mutable reference `&mut _` + +error[E0596]: cannot bind with `ref mut` behind an `&` pattern + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:26:31 + | +LL | if let Some(&Some(ref mut x)) = &mut Some(Some(0)) { + | ^ + | +help: change this `&` pattern to an `&mut` + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:26:17 + | +LL | if let Some(&Some(ref mut x)) = &mut Some(Some(0)) { + | ^ + +error[E0596]: cannot bind with `ref mut` behind an `&` pattern + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:29:31 + | +LL | if let &Some(Some(ref mut x)) = &mut Some(Some(0)) { + | ^ + | +help: change this `&` pattern to an `&mut` + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:29:12 + | +LL | if let &Some(Some(ref mut x)) = &mut Some(Some(0)) { + | ^ + +error[E0308]: mismatched types + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:32:17 + | +LL | if let Some(&mut Some(x)) = &Some(Some(0)) { + | ^^^^^^^^^^^^ -------------- this expression has type `&Option>` + | | + | expected `Option<{integer}>`, found `&mut _` + | + = note: expected enum `Option<{integer}>` + found mutable reference `&mut _` + +error[E0308]: mismatched types + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:36:9 | LL | let &mut _= &&0; | ^^^^^^ --- this expression has type `&&{integer}` @@ -76,7 +111,7 @@ LL | let &mut _= &&0; found mutable reference `&mut _` error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:31:9 + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:39:9 | LL | let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&0; | ^^^^^^ ----------------------------- this expression has type `&&&&&&&&&&&&&&&&&&&&&&&&&&&&{integer}` @@ -86,6 +121,7 @@ LL | let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&0; = note: expected type `{integer}` found mutable reference `&mut _` -error: aborting due to 8 previous errors +error: aborting due to 11 previous errors -For more information about this error, try `rustc --explain E0308`. +Some errors have detailed explanations: E0308, E0596. +For more information about an error, try `rustc --explain E0308`. diff --git a/tests/ui/match/ref_pat_everywhere-mutability-mismatch.rs b/tests/ui/match/ref_pat_everywhere-fail.rs similarity index 63% rename from tests/ui/match/ref_pat_everywhere-mutability-mismatch.rs rename to tests/ui/match/ref_pat_everywhere-fail.rs index 9dd7a7893ec71..d1b1c04730d34 100644 --- a/tests/ui/match/ref_pat_everywhere-mutability-mismatch.rs +++ b/tests/ui/match/ref_pat_everywhere-fail.rs @@ -5,11 +5,7 @@ pub fn main() { //~^ ERROR: mismatched types [E0308] let _: u32 = x; } - if let &Some(x) = &mut Some(0) { - //~^ ERROR: mismatched types [E0308] - let _: u32 = x; - } - if let Some(&x) = &mut Some(0) { + if let Some(&mut x) = Some(&0) { //~^ ERROR: mismatched types [E0308] let _: u32 = x; } diff --git a/tests/ui/match/ref_pat_everywhere-fail.stderr b/tests/ui/match/ref_pat_everywhere-fail.stderr new file mode 100644 index 0000000000000..25a01129f4a9d --- /dev/null +++ b/tests/ui/match/ref_pat_everywhere-fail.stderr @@ -0,0 +1,38 @@ +error[E0308]: mismatched types + --> $DIR/ref_pat_everywhere-fail.rs:4:17 + | +LL | if let Some(&x) = Some(0) { + | ^^ ------- this expression has type `Option<{integer}>` + | | + | expected integer, found `&_` + | + = note: expected type `{integer}` + found reference `&_` +help: consider removing `&` from the pattern + | +LL | if let Some(x) = Some(0) { + | ~ + +error[E0308]: mismatched types + --> $DIR/ref_pat_everywhere-fail.rs:8:17 + | +LL | if let Some(&mut x) = Some(&0) { + | ^^^^^^ -------- this expression has type `Option<&{integer}>` + | | + | types differ in mutability + | + = note: expected reference `&{integer}` + found mutable reference `&mut _` +note: to declare a mutable binding use: `mut x` + --> $DIR/ref_pat_everywhere-fail.rs:8:17 + | +LL | if let Some(&mut x) = Some(&0) { + | ^^^^^^ +help: consider removing `&mut` from the pattern + | +LL | if let Some(x) = Some(&0) { + | ~ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/match/ref_pat_everywhere-mutability-mismatch.stderr b/tests/ui/match/ref_pat_everywhere-mutability-mismatch.stderr deleted file mode 100644 index d512ea5f957da..0000000000000 --- a/tests/ui/match/ref_pat_everywhere-mutability-mismatch.stderr +++ /dev/null @@ -1,44 +0,0 @@ -error[E0308]: mismatched types - --> $DIR/ref_pat_everywhere-mutability-mismatch.rs:4:17 - | -LL | if let Some(&x) = Some(0) { - | ^^ ------- this expression has type `Option<{integer}>` - | | - | expected integer, found `&_` - | - = note: expected type `{integer}` - found reference `&_` -help: consider removing `&` from the pattern - | -LL | if let Some(x) = Some(0) { - | ~ - -error[E0308]: mismatched types - --> $DIR/ref_pat_everywhere-mutability-mismatch.rs:8:12 - | -LL | if let &Some(x) = &mut Some(0) { - | ^^^^^^^^ ------------ this expression has type `&mut Option<{integer}>` - | | - | types differ in mutability - | - = note: expected mutable reference `&mut Option<{integer}>` - found reference `&_` - -error[E0308]: mismatched types - --> $DIR/ref_pat_everywhere-mutability-mismatch.rs:12:17 - | -LL | if let Some(&x) = &mut Some(0) { - | ^^ ------------ this expression has type `&mut Option<{integer}>` - | | - | expected integer, found `&_` - | - = note: expected type `{integer}` - found reference `&_` -help: consider removing `&` from the pattern - | -LL | if let Some(x) = &mut Some(0) { - | ~ - -error: aborting due to 3 previous errors - -For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/match/ref_pat_everywhere.rs b/tests/ui/match/ref_pat_everywhere.rs index b3daca484092b..9a79c548475f6 100644 --- a/tests/ui/match/ref_pat_everywhere.rs +++ b/tests/ui/match/ref_pat_everywhere.rs @@ -15,4 +15,10 @@ pub fn main() { if let Some(Some(&x)) = &Some(&mut Some(0)) { let _: u32 = x; } + if let &Some(x) = &mut Some(0) { + let _: u32 = x; + } + if let Some(&x) = &mut Some(0) { + let _: u32 = x; + } } From ed96c655c6e147f5c2ce54e91f71a0874f9f836a Mon Sep 17 00:00:00 2001 From: Jules Bertholet Date: Sat, 4 May 2024 14:57:27 -0400 Subject: [PATCH 032/179] Various fixes: - Only show error when move-check would not be triggered - Add structured suggestion --- compiler/rustc_hir_typeck/src/pat.rs | 44 +++++++++++++------ .../ref_pat_eat_one_layer_2024_fail.rs | 12 +++-- .../ref_pat_eat_one_layer_2024_fail.stderr | 39 ++++++++-------- .../ref_pat_eat_one_layer_2024_fail2.rs | 3 ++ .../ref_pat_eat_one_layer_2024_fail2.stderr | 11 ++++- 5 files changed, 71 insertions(+), 38 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index 99653814d6fd6..f1eceed0ac8ce 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -163,7 +163,13 @@ enum MutblCap { impl MutblCap { fn cap_mutbl_to_not(self, span: Option) -> Self { - if self == MutblCap::Mut { MutblCap::Not(span) } else { self } + if let Some(s) = span + && self != MutblCap::Not(None) + { + MutblCap::Not(Some(s)) + } else { + MutblCap::Not(None) + } } fn as_mutbl(self) -> Mutability { @@ -744,9 +750,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.tcx.dcx(), ident.span, E0596, - "cannot bind with `ref mut` behind an `&` pattern" + "cannot borrow as mutable inside an `&` pattern" + ); + err.span_suggestion( + and_pat_span, + "replace this `&` with `&mut`", + "&mut ", + Applicability::MachineApplicable, ); - err.span_help(and_pat_span, "change this `&` pattern to an `&mut`"); err.emit(); } @@ -2187,7 +2198,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // the bad interactions of the given hack detailed in (note_1). debug!("check_pat_ref: expected={:?}", expected); match *expected.kind() { - ty::Ref(_, r_ty, r_mutbl) if r_mutbl == mutbl => (expected, r_ty, pat_info), + ty::Ref(_, r_ty, r_mutbl) if r_mutbl == mutbl => { + let pat_info = if r_mutbl == Mutability::Not + && ((pat.span.at_least_rust_2024() + && self.tcx.features().ref_pat_eat_one_layer_2024) + || self.tcx.features().ref_pat_everywhere) + { + PatInfo { + max_ref_mutbl: pat_info.max_ref_mutbl.cap_mutbl_to_not(None), + ..pat_info + } + } else { + pat_info + }; + (expected, r_ty, pat_info) + } // `&` pattern eats `&mut` reference ty::Ref(_, r_ty, Mutability::Mut) @@ -2196,16 +2221,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { && self.tcx.features().ref_pat_eat_one_layer_2024) || self.tcx.features().ref_pat_everywhere) => { - ( - expected, - r_ty, - PatInfo { - max_ref_mutbl: pat_info - .max_ref_mutbl - .cap_mutbl_to_not(Some(pat.span.until(inner.span))), - ..pat_info - }, - ) + (expected, r_ty, pat_info) } _ if consumed_inherited_ref && self.tcx.features().ref_pat_everywhere => { diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.rs b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.rs index 61e6171945826..376855406a6aa 100644 --- a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.rs +++ b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.rs @@ -24,18 +24,24 @@ pub fn main() { //~^ ERROR: mismatched types } if let Some(&Some(ref mut x)) = &mut Some(Some(0)) { - //~^ ERROR: cannot bind with `ref mut` behind an `&` pattern + //~^ ERROR: cannot borrow as mutable inside an `&` pattern } if let &Some(Some(ref mut x)) = &mut Some(Some(0)) { - //~^ ERROR: cannot bind with `ref mut` behind an `&` pattern + //~^ ERROR: cannot borrow as mutable inside an `&` pattern } if let Some(&mut Some(x)) = &Some(Some(0)) { //~^ ERROR: mismatched types } - let &mut _= &&0; + let &mut _ = &&0; //~^ ERROR: mismatched types let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&0; //~^ ERROR: mismatched types + + macro_rules! pat { + ($var:ident) => { ref mut $var }; + } + let &pat!(x) = &mut 0; + //~^ ERROR: cannot borrow as mutable inside an `&` pattern } diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.stderr b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.stderr index 2aa2e2851ced8..0512a31011dd0 100644 --- a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.stderr +++ b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.stderr @@ -64,29 +64,21 @@ LL | if let Some(&mut Some(x)) = &Some(Some(0)) { = note: expected enum `Option<{integer}>` found mutable reference `&mut _` -error[E0596]: cannot bind with `ref mut` behind an `&` pattern +error[E0596]: cannot borrow as mutable inside an `&` pattern --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:26:31 | LL | if let Some(&Some(ref mut x)) = &mut Some(Some(0)) { - | ^ - | -help: change this `&` pattern to an `&mut` - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:26:17 - | -LL | if let Some(&Some(ref mut x)) = &mut Some(Some(0)) { - | ^ + | - ^ + | | + | help: replace this `&` with `&mut`: `&mut` -error[E0596]: cannot bind with `ref mut` behind an `&` pattern +error[E0596]: cannot borrow as mutable inside an `&` pattern --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:29:31 | LL | if let &Some(Some(ref mut x)) = &mut Some(Some(0)) { - | ^ - | -help: change this `&` pattern to an `&mut` - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:29:12 - | -LL | if let &Some(Some(ref mut x)) = &mut Some(Some(0)) { - | ^ + | - ^ + | | + | help: replace this `&` with `&mut`: `&mut` error[E0308]: mismatched types --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:32:17 @@ -102,8 +94,8 @@ LL | if let Some(&mut Some(x)) = &Some(Some(0)) { error[E0308]: mismatched types --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:36:9 | -LL | let &mut _= &&0; - | ^^^^^^ --- this expression has type `&&{integer}` +LL | let &mut _ = &&0; + | ^^^^^^ --- this expression has type `&&{integer}` | | | expected integer, found `&mut _` | @@ -121,7 +113,16 @@ LL | let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&0; = note: expected type `{integer}` found mutable reference `&mut _` -error: aborting due to 11 previous errors +error[E0596]: cannot borrow as mutable inside an `&` pattern + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:45:15 + | +LL | ($var:ident) => { ref mut $var }; + | ------------ help: replace this `&` with `&mut`: `&mut` +LL | } +LL | let &pat!(x) = &mut 0; + | ^ + +error: aborting due to 12 previous errors Some errors have detailed explanations: E0308, E0596. For more information about an error, try `rustc --explain E0308`. diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail2.rs b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail2.rs index 364554884073a..3cdf47c1dbfe1 100644 --- a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail2.rs +++ b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail2.rs @@ -8,4 +8,7 @@ pub fn main() { //~^ ERROR: cannot move out of a shared reference [E0507] let _: &u32 = x; } + + let &ref mut x = &0; + //~^ cannot borrow data in a `&` reference as mutable [E0596] } diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail2.stderr b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail2.stderr index ccfb5c7a0c076..8b86fa65c4d8f 100644 --- a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail2.stderr +++ b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail2.stderr @@ -12,6 +12,13 @@ help: consider borrowing the pattern binding LL | if let Some(&Some(ref x)) = Some(&Some(&mut 0)) { | +++ -error: aborting due to 1 previous error +error[E0596]: cannot borrow data in a `&` reference as mutable + --> $DIR/ref_pat_eat_one_layer_2024_fail2.rs:12:10 + | +LL | let &ref mut x = &0; + | ^^^^^^^^^ cannot borrow as mutable + +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0507`. +Some errors have detailed explanations: E0507, E0596. +For more information about an error, try `rustc --explain E0507`. From 91bbbaa0f75c321d471df6eecdb46fd6c7739fff Mon Sep 17 00:00:00 2001 From: Jules Bertholet Date: Sat, 4 May 2024 15:20:06 -0400 Subject: [PATCH 033/179] Fix spans when macros are involved --- compiler/rustc_hir_typeck/src/pat.rs | 8 ++++---- .../ref_pat_eat_one_layer_2024_fail.stderr | 7 +++---- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index f1eceed0ac8ce..d8e21574cf463 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -137,7 +137,7 @@ enum AdjustMode { /// with mutability matching the pattern, /// mark the pattern as having consumed this reference. /// - /// `Span` is that of the inside of the reference pattern + /// `Span` is that of the `&` or `&mut` itself ResetAndConsumeRef(Mutability, Span), /// Pass on the input binding mode and expected type. Pass, @@ -342,14 +342,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { match adjust_mode { AdjustMode::Pass => (expected, def_br, max_ref_mutbl, false), AdjustMode::Reset => (expected, ByRef::No, MutblCap::Mut, false), - AdjustMode::ResetAndConsumeRef(ref_pat_mutbl, inner_span) => { + AdjustMode::ResetAndConsumeRef(ref_pat_mutbl, ref_span) => { // `&` pattern eats `&mut` let mutbls_match = if let ByRef::Yes(def_mut) = def_br { ref_pat_mutbl <= def_mut } else { false }; if pat.span.at_least_rust_2024() && self.tcx.features().ref_pat_eat_one_layer_2024 { let max_ref_mutbl = if ref_pat_mutbl == Mutability::Not { - max_ref_mutbl.cap_mutbl_to_not(Some(pat.span.until(inner_span))) + max_ref_mutbl.cap_mutbl_to_not(Some(ref_span)) } else { max_ref_mutbl }; @@ -434,7 +434,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // ``` // // See issue #46688. - PatKind::Ref(inner, mutbl) => AdjustMode::ResetAndConsumeRef(*mutbl, inner.span), + PatKind::Ref(inner, mutbl) => AdjustMode::ResetAndConsumeRef(*mutbl, pat.span.until(inner.span.find_ancestor_inside(pat.span).unwrap())), // A `_` pattern works with any expected type, so there's no need to do anything. PatKind::Wild // A malformed pattern doesn't have an expected type, so let's just accept any type. diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.stderr b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.stderr index 0512a31011dd0..d51b92230e809 100644 --- a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.stderr +++ b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.stderr @@ -116,11 +116,10 @@ LL | let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&0; error[E0596]: cannot borrow as mutable inside an `&` pattern --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:45:15 | -LL | ($var:ident) => { ref mut $var }; - | ------------ help: replace this `&` with `&mut`: `&mut` -LL | } LL | let &pat!(x) = &mut 0; - | ^ + | - ^ + | | + | help: replace this `&` with `&mut`: `&mut` error: aborting due to 12 previous errors From f57b970de8103f1d7cd6307ad18e9f07d21e0e84 Mon Sep 17 00:00:00 2001 From: Jules Bertholet Date: Sat, 4 May 2024 16:04:08 -0400 Subject: [PATCH 034/179] Comments and fixes --- compiler/rustc_hir_typeck/src/pat.rs | 37 ++++++++++------ .../ref_pat_eat_one_layer_2024_fail.rs | 12 ------ .../ref_pat_eat_one_layer_2024_fail.stderr | 35 +++------------ ...at_one_layer_2024_ref_mut_inside_and.fixed | 30 +++++++++++++ ...t_eat_one_layer_2024_ref_mut_inside_and.rs | 30 +++++++++++++ ...t_one_layer_2024_ref_mut_inside_and.stderr | 43 +++++++++++++++++++ 6 files changed, 132 insertions(+), 55 deletions(-) create mode 100644 tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_ref_mut_inside_and.fixed create mode 100644 tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_ref_mut_inside_and.rs create mode 100644 tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_ref_mut_inside_and.stderr diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index d8e21574cf463..170057d4adf92 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -137,8 +137,8 @@ enum AdjustMode { /// with mutability matching the pattern, /// mark the pattern as having consumed this reference. /// - /// `Span` is that of the `&` or `&mut` itself - ResetAndConsumeRef(Mutability, Span), + /// `Span` is that of the `&` or `&mut` itself. + ResetAndConsumeRef(Mutability, Option), /// Pass on the input binding mode and expected type. Pass, } @@ -154,15 +154,23 @@ enum AdjustMode { /// this last case, so we need to throw an error ourselves. #[derive(Clone, Copy, Debug, PartialEq, Eq)] enum MutblCap { - /// Mutability restricted to immutable; - /// contained span, if present, should be shown in diagnostics as the reason. - Not(Option), + /// Mutability restricted to immutable. + /// + /// The contained span, if present, points to an `&` pattern + /// that is the reason for the restriction, + /// and which will be reported in a diagnostic. + /// (Said diagnostic is shown only if + /// replacing the `&` pattern with `&mut` would allow the code to compile.) + /// + /// (Outer [`Option`] is for whether to show the diagnostic, + /// inner [`Option`] is for whether we have a span we can report) + Not(Option>), /// No restriction on mutability Mut, } impl MutblCap { - fn cap_mutbl_to_not(self, span: Option) -> Self { + fn cap_mutbl_to_not(self, span: Option>) -> Self { if let Some(s) = span && self != MutblCap::Not(None) { @@ -434,7 +442,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // ``` // // See issue #46688. - PatKind::Ref(inner, mutbl) => AdjustMode::ResetAndConsumeRef(*mutbl, pat.span.until(inner.span.find_ancestor_inside(pat.span).unwrap())), + PatKind::Ref(inner, mutbl) => AdjustMode::ResetAndConsumeRef(*mutbl, inner.span.find_ancestor_inside(pat.span).map(|end| pat.span.until(end))), // A `_` pattern works with any expected type, so there's no need to do anything. PatKind::Wild // A malformed pattern doesn't have an expected type, so let's just accept any type. @@ -752,12 +760,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { E0596, "cannot borrow as mutable inside an `&` pattern" ); - err.span_suggestion( - and_pat_span, - "replace this `&` with `&mut`", - "&mut ", - Applicability::MachineApplicable, - ); + + if let Some(span) = and_pat_span { + err.span_suggestion( + span, + "replace this `&` with `&mut`", + "&mut ", + Applicability::MachineApplicable, + ); + } err.emit(); } diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.rs b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.rs index 376855406a6aa..96b4ff77ddb4b 100644 --- a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.rs +++ b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.rs @@ -23,12 +23,6 @@ pub fn main() { if let Some(&mut Some(x)) = &Some(Some(0)) { //~^ ERROR: mismatched types } - if let Some(&Some(ref mut x)) = &mut Some(Some(0)) { - //~^ ERROR: cannot borrow as mutable inside an `&` pattern - } - if let &Some(Some(ref mut x)) = &mut Some(Some(0)) { - //~^ ERROR: cannot borrow as mutable inside an `&` pattern - } if let Some(&mut Some(x)) = &Some(Some(0)) { //~^ ERROR: mismatched types } @@ -38,10 +32,4 @@ pub fn main() { let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&0; //~^ ERROR: mismatched types - - macro_rules! pat { - ($var:ident) => { ref mut $var }; - } - let &pat!(x) = &mut 0; - //~^ ERROR: cannot borrow as mutable inside an `&` pattern } diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.stderr b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.stderr index d51b92230e809..e06a645fc0d33 100644 --- a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.stderr +++ b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.stderr @@ -64,24 +64,8 @@ LL | if let Some(&mut Some(x)) = &Some(Some(0)) { = note: expected enum `Option<{integer}>` found mutable reference `&mut _` -error[E0596]: cannot borrow as mutable inside an `&` pattern - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:26:31 - | -LL | if let Some(&Some(ref mut x)) = &mut Some(Some(0)) { - | - ^ - | | - | help: replace this `&` with `&mut`: `&mut` - -error[E0596]: cannot borrow as mutable inside an `&` pattern - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:29:31 - | -LL | if let &Some(Some(ref mut x)) = &mut Some(Some(0)) { - | - ^ - | | - | help: replace this `&` with `&mut`: `&mut` - error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:32:17 + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:26:17 | LL | if let Some(&mut Some(x)) = &Some(Some(0)) { | ^^^^^^^^^^^^ -------------- this expression has type `&Option>` @@ -92,7 +76,7 @@ LL | if let Some(&mut Some(x)) = &Some(Some(0)) { found mutable reference `&mut _` error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:36:9 + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:30:9 | LL | let &mut _ = &&0; | ^^^^^^ --- this expression has type `&&{integer}` @@ -103,7 +87,7 @@ LL | let &mut _ = &&0; found mutable reference `&mut _` error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:39:9 + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:33:9 | LL | let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&0; | ^^^^^^ ----------------------------- this expression has type `&&&&&&&&&&&&&&&&&&&&&&&&&&&&{integer}` @@ -113,15 +97,6 @@ LL | let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&0; = note: expected type `{integer}` found mutable reference `&mut _` -error[E0596]: cannot borrow as mutable inside an `&` pattern - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:45:15 - | -LL | let &pat!(x) = &mut 0; - | - ^ - | | - | help: replace this `&` with `&mut`: `&mut` - -error: aborting due to 12 previous errors +error: aborting due to 9 previous errors -Some errors have detailed explanations: E0308, E0596. -For more information about an error, try `rustc --explain E0308`. +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_ref_mut_inside_and.fixed b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_ref_mut_inside_and.fixed new file mode 100644 index 0000000000000..bc7a58a382d60 --- /dev/null +++ b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_ref_mut_inside_and.fixed @@ -0,0 +1,30 @@ +//@ edition: 2024 +//@ compile-flags: -Zunstable-options +//@ run-rustfix +#![allow(incomplete_features)] +#![feature(ref_pat_eat_one_layer_2024)] + +pub fn main() { + if let Some(&mut Some(ref mut x)) = &mut Some(Some(0)) { + //~^ ERROR: cannot borrow as mutable inside an `&` pattern + let _: &mut u8 = x; + } + + if let &mut Some(Some(ref mut x)) = &mut Some(Some(0)) { + //~^ ERROR: cannot borrow as mutable inside an `&` pattern + let _: &mut u8 = x; + } + + macro_rules! pat { + ($var:ident) => { ref mut $var }; + } + let &mut pat!(x) = &mut 0; + //~^ ERROR: cannot borrow as mutable inside an `&` pattern + let _: &mut u8 = x; + + let &mut (ref mut a, ref mut b) = &mut (true, false); + //~^ ERROR: cannot borrow as mutable inside an `&` pattern + //~| ERROR: cannot borrow as mutable inside an `&` pattern + let _: &mut bool = a; + let _: &mut bool = b; +} diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_ref_mut_inside_and.rs b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_ref_mut_inside_and.rs new file mode 100644 index 0000000000000..c6d72b0a9d777 --- /dev/null +++ b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_ref_mut_inside_and.rs @@ -0,0 +1,30 @@ +//@ edition: 2024 +//@ compile-flags: -Zunstable-options +//@ run-rustfix +#![allow(incomplete_features)] +#![feature(ref_pat_eat_one_layer_2024)] + +pub fn main() { + if let Some(&Some(ref mut x)) = &mut Some(Some(0)) { + //~^ ERROR: cannot borrow as mutable inside an `&` pattern + let _: &mut u8 = x; + } + + if let &Some(Some(ref mut x)) = &mut Some(Some(0)) { + //~^ ERROR: cannot borrow as mutable inside an `&` pattern + let _: &mut u8 = x; + } + + macro_rules! pat { + ($var:ident) => { ref mut $var }; + } + let &pat!(x) = &mut 0; + //~^ ERROR: cannot borrow as mutable inside an `&` pattern + let _: &mut u8 = x; + + let &(ref mut a, ref mut b) = &mut (true, false); + //~^ ERROR: cannot borrow as mutable inside an `&` pattern + //~| ERROR: cannot borrow as mutable inside an `&` pattern + let _: &mut bool = a; + let _: &mut bool = b; +} diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_ref_mut_inside_and.stderr b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_ref_mut_inside_and.stderr new file mode 100644 index 0000000000000..964e9f36596bd --- /dev/null +++ b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_ref_mut_inside_and.stderr @@ -0,0 +1,43 @@ +error[E0596]: cannot borrow as mutable inside an `&` pattern + --> $DIR/ref_pat_eat_one_layer_2024_ref_mut_inside_and.rs:8:31 + | +LL | if let Some(&Some(ref mut x)) = &mut Some(Some(0)) { + | - ^ + | | + | help: replace this `&` with `&mut`: `&mut` + +error[E0596]: cannot borrow as mutable inside an `&` pattern + --> $DIR/ref_pat_eat_one_layer_2024_ref_mut_inside_and.rs:13:31 + | +LL | if let &Some(Some(ref mut x)) = &mut Some(Some(0)) { + | - ^ + | | + | help: replace this `&` with `&mut`: `&mut` + +error[E0596]: cannot borrow as mutable inside an `&` pattern + --> $DIR/ref_pat_eat_one_layer_2024_ref_mut_inside_and.rs:21:15 + | +LL | let &pat!(x) = &mut 0; + | - ^ + | | + | help: replace this `&` with `&mut`: `&mut` + +error[E0596]: cannot borrow as mutable inside an `&` pattern + --> $DIR/ref_pat_eat_one_layer_2024_ref_mut_inside_and.rs:25:19 + | +LL | let &(ref mut a, ref mut b) = &mut (true, false); + | - ^ + | | + | help: replace this `&` with `&mut`: `&mut` + +error[E0596]: cannot borrow as mutable inside an `&` pattern + --> $DIR/ref_pat_eat_one_layer_2024_ref_mut_inside_and.rs:25:30 + | +LL | let &(ref mut a, ref mut b) = &mut (true, false); + | - ^ + | | + | help: replace this `&` with `&mut`: `&mut` + +error: aborting due to 5 previous errors + +For more information about this error, try `rustc --explain E0596`. From 0f03c2be580548b70d88a809199d840e7d5d5b22 Mon Sep 17 00:00:00 2001 From: Jules Bertholet Date: Sat, 4 May 2024 16:14:44 -0400 Subject: [PATCH 035/179] Rename `explicit_ba` --- compiler/rustc_hir_typeck/src/pat.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index 170057d4adf92..482c4ed3af3cb 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -722,7 +722,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { fn check_pat_ident( &self, pat: &'tcx Pat<'tcx>, - explicit_ba: BindingMode, + user_bind_annot: BindingMode, var_id: HirId, ident: Ident, sub: Option<&'tcx Pat<'tcx>>, @@ -732,7 +732,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let PatInfo { binding_mode: def_br, top_info: ti, .. } = pat_info; // Determine the binding mode... - let bm = match explicit_ba { + let bm = match user_bind_annot { BindingMode(ByRef::No, Mutability::Mut) if !(pat.span.at_least_rust_2024() && self.tcx.features().mut_preserve_binding_mode_2024) @@ -748,7 +748,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { BindingMode(ByRef::No, Mutability::Mut) } BindingMode(ByRef::No, mutbl) => BindingMode(def_br, mutbl), - BindingMode(ByRef::Yes(_), _) => explicit_ba, + BindingMode(ByRef::Yes(_), _) => user_bind_annot, }; if bm.0 == ByRef::Yes(Mutability::Mut) @@ -797,7 +797,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // If there are multiple arms, make sure they all agree on // what the type of the binding `x` ought to be. if var_id != pat.hir_id { - self.check_binding_alt_eq_ty(explicit_ba, pat.span, var_id, local_ty, ti); + self.check_binding_alt_eq_ty(user_bind_annot, pat.span, var_id, local_ty, ti); } if let Some(p) = sub { From d8a798b5e93e36a62d3c114f7439cb1e4299279d Mon Sep 17 00:00:00 2001 From: Jules Bertholet Date: Sun, 5 May 2024 11:35:49 -0400 Subject: [PATCH 036/179] No more `Option>` --- compiler/rustc_hir_typeck/src/pat.rs | 34 ++++++++++++---------------- 1 file changed, 15 insertions(+), 19 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index 482c4ed3af3cb..5a2fed13d2b2e 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -155,34 +155,33 @@ enum AdjustMode { #[derive(Clone, Copy, Debug, PartialEq, Eq)] enum MutblCap { /// Mutability restricted to immutable. + Not, + + /// Mutability restricted to immutable, but only because of the pattern + /// (not the scrutinee type). /// /// The contained span, if present, points to an `&` pattern /// that is the reason for the restriction, /// and which will be reported in a diagnostic. /// (Said diagnostic is shown only if /// replacing the `&` pattern with `&mut` would allow the code to compile.) - /// - /// (Outer [`Option`] is for whether to show the diagnostic, - /// inner [`Option`] is for whether we have a span we can report) - Not(Option>), + WeaklyNot(Option), + /// No restriction on mutability Mut, } impl MutblCap { - fn cap_mutbl_to_not(self, span: Option>) -> Self { - if let Some(s) = span - && self != MutblCap::Not(None) - { - MutblCap::Not(Some(s)) - } else { - MutblCap::Not(None) + fn cap_to_weakly_not(self, span: Option) -> Self { + match self { + MutblCap::Not => MutblCap::Not, + _ => MutblCap::WeaklyNot(span), } } fn as_mutbl(self) -> Mutability { match self { - MutblCap::Not(_) => Mutability::Not, + MutblCap::Not | MutblCap::WeaklyNot(_) => Mutability::Not, MutblCap::Mut => Mutability::Mut, } } @@ -357,7 +356,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if pat.span.at_least_rust_2024() && self.tcx.features().ref_pat_eat_one_layer_2024 { let max_ref_mutbl = if ref_pat_mutbl == Mutability::Not { - max_ref_mutbl.cap_mutbl_to_not(Some(ref_span)) + max_ref_mutbl.cap_to_weakly_not(ref_span) } else { max_ref_mutbl }; @@ -505,7 +504,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if pat.span.at_least_rust_2024() && self.tcx.features().ref_pat_eat_one_layer_2024 { def_br = def_br.cap_ref_mutability(max_ref_mutability.as_mutbl()); if def_br == ByRef::Yes(Mutability::Not) { - max_ref_mutability = max_ref_mutability.cap_mutbl_to_not(None); + max_ref_mutability = MutblCap::Not; } } @@ -752,7 +751,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }; if bm.0 == ByRef::Yes(Mutability::Mut) - && let MutblCap::Not(Some(and_pat_span)) = pat_info.max_ref_mutbl + && let MutblCap::WeaklyNot(and_pat_span) = pat_info.max_ref_mutbl { let mut err = struct_span_code_err!( self.tcx.dcx(), @@ -2215,10 +2214,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { && self.tcx.features().ref_pat_eat_one_layer_2024) || self.tcx.features().ref_pat_everywhere) { - PatInfo { - max_ref_mutbl: pat_info.max_ref_mutbl.cap_mutbl_to_not(None), - ..pat_info - } + PatInfo { max_ref_mutbl: MutblCap::Not, ..pat_info } } else { pat_info }; From bff287b4a5c3379db3ffb045fe9eb6eea2eed7d7 Mon Sep 17 00:00:00 2001 From: Jules Bertholet Date: Sun, 5 May 2024 12:05:18 -0400 Subject: [PATCH 037/179] Remove redundant comment --- compiler/rustc_hir_typeck/src/pat.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index 5a2fed13d2b2e..a4cee5aac8dd6 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -163,8 +163,6 @@ enum MutblCap { /// The contained span, if present, points to an `&` pattern /// that is the reason for the restriction, /// and which will be reported in a diagnostic. - /// (Said diagnostic is shown only if - /// replacing the `&` pattern with `&mut` would allow the code to compile.) WeaklyNot(Option), /// No restriction on mutability From 7951311c1bbcfc8f3487004f1df7e97a2ac6dc80 Mon Sep 17 00:00:00 2001 From: Jules Bertholet Date: Sun, 5 May 2024 23:57:52 -0400 Subject: [PATCH 038/179] Move all ref pat logic into `check_pat_ref` --- compiler/rustc_hir_typeck/src/pat.rs | 287 ++++++++++++--------------- 1 file changed, 132 insertions(+), 155 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index a4cee5aac8dd6..b18da758c1ca0 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -131,14 +131,6 @@ enum AdjustMode { /// Reset binding mode to the initial mode. /// Used for destructuring assignment, where we don't want any match ergonomics. Reset, - /// Produced by ref patterns. - /// Reset the binding mode to the initial mode, - /// and if the old biding mode was by-reference - /// with mutability matching the pattern, - /// mark the pattern as having consumed this reference. - /// - /// `Span` is that of the `&` or `&mut` itself. - ResetAndConsumeRef(Mutability, Option), /// Pass on the input binding mode and expected type. Pass, } @@ -170,6 +162,7 @@ enum MutblCap { } impl MutblCap { + #[must_use] fn cap_to_weakly_not(self, span: Option) -> Self { match self { MutblCap::Not => MutblCap::Not, @@ -177,6 +170,7 @@ impl MutblCap { } } + #[must_use] fn as_mutbl(self) -> Mutability { match self { MutblCap::Not | MutblCap::WeaklyNot(_) => Mutability::Not, @@ -214,14 +208,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } /// Type check the given `pat` against the `expected` type - /// with the provided `def_bm` (default binding mode). + /// with the provided `binding_mode` (default binding mode). /// /// Outside of this module, `check_pat_top` should always be used. /// Conversely, inside this module, `check_pat_top` should never be used. #[instrument(level = "debug", skip(self, pat_info))] fn check_pat(&self, pat: &'tcx Pat<'tcx>, expected: Ty<'tcx>, pat_info: PatInfo<'tcx, '_>) { - let PatInfo { binding_mode: def_bm, max_ref_mutbl, top_info: ti, current_depth, .. } = - pat_info; + let PatInfo { binding_mode, max_ref_mutbl, top_info: ti, current_depth, .. } = pat_info; let path_res = match &pat.kind { PatKind::Path(qpath) => Some( @@ -230,10 +223,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { _ => None, }; let adjust_mode = self.calc_adjust_mode(pat, path_res.map(|(res, ..)| res)); - let (expected, def_bm, max_ref_mutbl, ref_pattern_already_consumed) = - self.calc_default_binding_mode(pat, expected, def_bm, adjust_mode, max_ref_mutbl); + let (expected, binding_mode, max_ref_mutbl) = + self.calc_default_binding_mode(pat, expected, binding_mode, adjust_mode, max_ref_mutbl); let pat_info = PatInfo { - binding_mode: def_bm, + binding_mode, max_ref_mutbl, top_info: ti, decl_origin: pat_info.decl_origin, @@ -269,14 +262,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } PatKind::Box(inner) => self.check_pat_box(pat.span, inner, expected, pat_info), PatKind::Deref(inner) => self.check_pat_deref(pat.span, inner, expected, pat_info), - PatKind::Ref(inner, mutbl) => self.check_pat_ref( - pat, - inner, - mutbl, - expected, - pat_info, - ref_pattern_already_consumed, - ), + PatKind::Ref(inner, mutbl) => self.check_pat_ref(pat, inner, mutbl, expected, pat_info), PatKind::Slice(before, slice, after) => { self.check_pat_slice(pat.span, before, slice, after, expected, pat_info) } @@ -329,10 +315,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// Compute the new expected type and default binding mode from the old ones /// as well as the pattern form we are currently checking. - /// - /// Last entry is only relevant for ref patterns (`&` and `&mut`); - /// if `true`, then the ref pattern consumed a match ergonomics inserted reference - /// and so does no need to match against a reference in the scrutinee type. fn calc_default_binding_mode( &self, pat: &'tcx Pat<'tcx>, @@ -340,50 +322,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { def_br: ByRef, adjust_mode: AdjustMode, max_ref_mutbl: MutblCap, - ) -> (Ty<'tcx>, ByRef, MutblCap, bool) { + ) -> (Ty<'tcx>, ByRef, MutblCap) { if let ByRef::Yes(Mutability::Mut) = def_br { debug_assert!(max_ref_mutbl == MutblCap::Mut); } match adjust_mode { - AdjustMode::Pass => (expected, def_br, max_ref_mutbl, false), - AdjustMode::Reset => (expected, ByRef::No, MutblCap::Mut, false), - AdjustMode::ResetAndConsumeRef(ref_pat_mutbl, ref_span) => { - // `&` pattern eats `&mut` - let mutbls_match = - if let ByRef::Yes(def_mut) = def_br { ref_pat_mutbl <= def_mut } else { false }; - - if pat.span.at_least_rust_2024() && self.tcx.features().ref_pat_eat_one_layer_2024 { - let max_ref_mutbl = if ref_pat_mutbl == Mutability::Not { - max_ref_mutbl.cap_to_weakly_not(ref_span) - } else { - max_ref_mutbl - }; - - if mutbls_match { - debug!("consuming inherited reference"); - (expected, ByRef::No, max_ref_mutbl, true) - } else { - let (new_ty, new_bm, max_ref_mutbl) = if ref_pat_mutbl == Mutability::Mut { - self.peel_off_references( - pat, - expected, - def_br, - Mutability::Not, - max_ref_mutbl, - ) - } else { - (expected, def_br.cap_ref_mutability(Mutability::Not), max_ref_mutbl) - }; - (new_ty, new_bm, max_ref_mutbl, false) - } - } else { - (expected, ByRef::No, max_ref_mutbl, mutbls_match) - } - } + AdjustMode::Pass => (expected, def_br, max_ref_mutbl), + AdjustMode::Reset => (expected, ByRef::No, MutblCap::Mut), AdjustMode::Peel => { - let peeled = - self.peel_off_references(pat, expected, def_br, Mutability::Mut, max_ref_mutbl); - (peeled.0, peeled.1, peeled.2, false) + self.peel_off_references(pat, expected, def_br, Mutability::Mut, max_ref_mutbl) } } } @@ -429,17 +376,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // a reference type wherefore peeling doesn't give up any expressiveness. _ => AdjustMode::Peel, }, - // When encountering a `& mut? pat` pattern, reset to "by value". - // This is so that `x` and `y` here are by value, as they appear to be: - // - // ``` - // match &(&22, &44) { - // (&x, &y) => ... - // } - // ``` - // - // See issue #46688. - PatKind::Ref(inner, mutbl) => AdjustMode::ResetAndConsumeRef(*mutbl, inner.span.find_ancestor_inside(pat.span).map(|end| pat.span.until(end))), + // Ref patterns are complicated, we handle them in `check_pat_ref`. + PatKind::Ref(..) => AdjustMode::Pass, // A `_` pattern works with any expected type, so there's no need to do anything. PatKind::Wild // A malformed pattern doesn't have an expected type, so let's just accept any type. @@ -2179,96 +2117,135 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { &self, pat: &'tcx Pat<'tcx>, inner: &'tcx Pat<'tcx>, - mutbl: Mutability, - expected: Ty<'tcx>, - pat_info: PatInfo<'tcx, '_>, - consumed_inherited_ref: bool, + pat_mutbl: Mutability, + mut expected: Ty<'tcx>, + mut pat_info: PatInfo<'tcx, '_>, ) -> Ty<'tcx> { - if consumed_inherited_ref - && pat.span.at_least_rust_2024() - && self.tcx.features().ref_pat_eat_one_layer_2024 - { - self.typeck_results.borrow_mut().skipped_ref_pats_mut().insert(pat.hir_id); - self.check_pat(inner, expected, pat_info); - expected - } else { - let tcx = self.tcx; - let expected = self.shallow_resolve(expected); - let (ref_ty, inner_ty, pat_info) = match self - .check_dereferenceable(pat.span, expected, inner) + // FIXME: repace with `bool` once final decision on 1 vs 2 layers is made + #[derive(Clone, Copy, Debug, PartialEq, Eq)] + enum MatchErgonomicsMode { + EatOneLayer, + EatTwoLayers, + Legacy, + } + + let match_ergonomics_mode = + if pat.span.at_least_rust_2024() && self.tcx.features().ref_pat_eat_one_layer_2024 { + MatchErgonomicsMode::EatOneLayer + } else if self.tcx.features().ref_pat_everywhere { + MatchErgonomicsMode::EatTwoLayers + } else { + MatchErgonomicsMode::Legacy + }; + + let mut inherited_ref_mutbl_match = false; + if match_ergonomics_mode != MatchErgonomicsMode::Legacy { + if pat_mutbl == Mutability::Not { + pat_info.max_ref_mutbl = pat_info.max_ref_mutbl.cap_to_weakly_not( + inner.span.find_ancestor_inside(pat.span).map(|end| pat.span.until(end)), + ); + } + + if let ByRef::Yes(inh_mut) = pat_info.binding_mode { + inherited_ref_mutbl_match = pat_mutbl <= inh_mut; + } + + if inherited_ref_mutbl_match { + pat_info.binding_mode = ByRef::No; + if match_ergonomics_mode == MatchErgonomicsMode::EatOneLayer { + self.typeck_results.borrow_mut().skipped_ref_pats_mut().insert(pat.hir_id); + self.check_pat(inner, expected, pat_info); + return expected; + } + } else if match_ergonomics_mode == MatchErgonomicsMode::EatOneLayer + && pat_mutbl == Mutability::Mut { - Ok(()) => { - // `demand::subtype` would be good enough, but using `eqtype` turns - // out to be equally general. See (note_1) for details. - - // Take region, inner-type from expected type if we can, - // to avoid creating needless variables. This also helps with - // the bad interactions of the given hack detailed in (note_1). - debug!("check_pat_ref: expected={:?}", expected); - match *expected.kind() { - ty::Ref(_, r_ty, r_mutbl) if r_mutbl == mutbl => { - let pat_info = if r_mutbl == Mutability::Not - && ((pat.span.at_least_rust_2024() - && self.tcx.features().ref_pat_eat_one_layer_2024) - || self.tcx.features().ref_pat_everywhere) - { - PatInfo { max_ref_mutbl: MutblCap::Not, ..pat_info } - } else { - pat_info - }; - (expected, r_ty, pat_info) - } + // `&mut` patterns pell off `&` references + let (new_expected, new_bm, max_ref_mutbl) = self.peel_off_references( + pat, + expected, + pat_info.binding_mode, + Mutability::Not, + pat_info.max_ref_mutbl, + ); + expected = new_expected; + pat_info.binding_mode = new_bm; + pat_info.max_ref_mutbl = max_ref_mutbl; + } + } else { + // Reset binding mode on old editions + pat_info.binding_mode = ByRef::No; + pat_info.max_ref_mutbl = MutblCap::Mut + } - // `&` pattern eats `&mut` reference - ty::Ref(_, r_ty, Mutability::Mut) - if mutbl == Mutability::Not - && ((pat.span.at_least_rust_2024() - && self.tcx.features().ref_pat_eat_one_layer_2024) - || self.tcx.features().ref_pat_everywhere) => + let tcx = self.tcx; + expected = self.try_structurally_resolve_type(pat.span, expected); + let (ref_ty, inner_ty) = match self.check_dereferenceable(pat.span, expected, inner) { + Ok(()) => { + // `demand::subtype` would be good enough, but using `eqtype` turns + // out to be equally general. See (note_1) for details. + + // Take region, inner-type from expected type if we can, + // to avoid creating needless variables. This also helps with + // the bad interactions of the given hack detailed in (note_1). + debug!("check_pat_ref: expected={:?}", expected); + match *expected.kind() { + ty::Ref(_, r_ty, r_mutbl) if r_mutbl == pat_mutbl => { + if r_mutbl == Mutability::Not + && match_ergonomics_mode != MatchErgonomicsMode::Legacy { - (expected, r_ty, pat_info) + pat_info.max_ref_mutbl = MutblCap::Not; } - _ if consumed_inherited_ref && self.tcx.features().ref_pat_everywhere => { - // We already matched against a match-ergonmics inserted reference, - // so we don't need to match against a reference from the original type. - // Save this infor for use in lowering later - self.typeck_results - .borrow_mut() - .skipped_ref_pats_mut() - .insert(pat.hir_id); - (expected, expected, pat_info) - } + (expected, r_ty) + } - _ => { - let inner_ty = self.next_ty_var(inner.span); - let ref_ty = self.new_ref_ty(pat.span, mutbl, inner_ty); - debug!("check_pat_ref: demanding {:?} = {:?}", expected, ref_ty); - let err = self.demand_eqtype_pat_diag( - pat.span, - expected, - ref_ty, - pat_info.top_info, - ); + // `&` pattern eats `&mut` reference + ty::Ref(_, r_ty, Mutability::Mut) + if pat_mutbl == Mutability::Not + && match_ergonomics_mode != MatchErgonomicsMode::Legacy => + { + (expected, r_ty) + } - // Look for a case like `fn foo(&foo: u32)` and suggest - // `fn foo(foo: &u32)` - if let Some(mut err) = err { - self.borrow_pat_suggestion(&mut err, pat); - err.emit(); - } - (ref_ty, inner_ty, pat_info) + _ if inherited_ref_mutbl_match + && match_ergonomics_mode == MatchErgonomicsMode::EatTwoLayers => + { + // We already matched against a match-ergonmics inserted reference, + // so we don't need to match against a reference from the original type. + // Save this info for use in lowering later + self.typeck_results.borrow_mut().skipped_ref_pats_mut().insert(pat.hir_id); + (expected, expected) + } + + _ => { + let inner_ty = self.next_ty_var(inner.span); + let ref_ty = self.new_ref_ty(pat.span, pat_mutbl, inner_ty); + debug!("check_pat_ref: demanding {:?} = {:?}", expected, ref_ty); + let err = self.demand_eqtype_pat_diag( + pat.span, + expected, + ref_ty, + pat_info.top_info, + ); + + // Look for a case like `fn foo(&foo: u32)` and suggest + // `fn foo(foo: &u32)` + if let Some(mut err) = err { + self.borrow_pat_suggestion(&mut err, pat); + err.emit(); } + (ref_ty, inner_ty) } } - Err(guar) => { - let err = Ty::new_error(tcx, guar); - (err, err, pat_info) - } - }; - self.check_pat(inner, inner_ty, pat_info); - ref_ty - } + } + Err(guar) => { + let err = Ty::new_error(tcx, guar); + (err, err) + } + }; + self.check_pat(inner, inner_ty, pat_info); + ref_ty } /// Create a reference type with a fresh region variable. From 6d5c6f541f5dc9f3142c84bbc5203e57c0a4a18c Mon Sep 17 00:00:00 2001 From: Jules Bertholet Date: Fri, 10 May 2024 13:53:48 -0400 Subject: [PATCH 039/179] Add comment on `cap_to_weakly_not` Co-authored-by: Guillaume Boisseau --- compiler/rustc_hir_typeck/src/pat.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index b18da758c1ca0..7029f5433d8b0 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -2141,6 +2141,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let mut inherited_ref_mutbl_match = false; if match_ergonomics_mode != MatchErgonomicsMode::Legacy { if pat_mutbl == Mutability::Not { + // Prevent the inner pattern from binding with `ref mut`. pat_info.max_ref_mutbl = pat_info.max_ref_mutbl.cap_to_weakly_not( inner.span.find_ancestor_inside(pat.span).map(|end| pat.span.until(end)), ); From d6122f1924c20797a96ab83b520cbaf585a9d4b1 Mon Sep 17 00:00:00 2001 From: Zachary S Date: Fri, 10 May 2024 14:00:20 -0500 Subject: [PATCH 040/179] Relax allocator requirements on some Rc APIs. * Remove A: Clone bound from Rc::assume_init, Rc::downcast, and Rc::downcast_unchecked. * Make From> for Rc<[T]> allocator-aware. Internal changes: * Made Arc::internal_into_inner_with_allocator method into Arc::into_inner_with_allocator associated fn. * Add private Rc::into_inner_with_allocator (to match Arc), so other fns don't have to juggle ManuallyDrop. --- library/alloc/src/rc.rs | 47 ++++++++++++++++++--------------------- library/alloc/src/sync.rs | 14 ++++++------ 2 files changed, 29 insertions(+), 32 deletions(-) diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index c245b42c3e880..795b12d82bec8 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -365,6 +365,12 @@ impl Rc { unsafe { self.ptr.as_ref() } } + #[inline] + fn into_inner_with_allocator(this: Self) -> (NonNull>, A) { + let this = mem::ManuallyDrop::new(this); + (this.ptr, unsafe { ptr::read(&this.alloc) }) + } + #[inline] unsafe fn from_inner_in(ptr: NonNull>, alloc: A) -> Self { Self { ptr, phantom: PhantomData, alloc } @@ -1145,12 +1151,9 @@ impl Rc, A> { /// ``` #[unstable(feature = "new_uninit", issue = "63291")] #[inline] - pub unsafe fn assume_init(self) -> Rc - where - A: Clone, - { - let md_self = mem::ManuallyDrop::new(self); - unsafe { Rc::from_inner_in(md_self.ptr.cast(), md_self.alloc.clone()) } + pub unsafe fn assume_init(self) -> Rc { + let (ptr, alloc) = Rc::into_inner_with_allocator(self); + unsafe { Rc::from_inner_in(ptr.cast(), alloc) } } } @@ -1189,12 +1192,9 @@ impl Rc<[mem::MaybeUninit], A> { /// ``` #[unstable(feature = "new_uninit", issue = "63291")] #[inline] - pub unsafe fn assume_init(self) -> Rc<[T], A> - where - A: Clone, - { - let md_self = mem::ManuallyDrop::new(self); - unsafe { Rc::from_ptr_in(md_self.ptr.as_ptr() as _, md_self.alloc.clone()) } + pub unsafe fn assume_init(self) -> Rc<[T], A> { + let (ptr, alloc) = Rc::into_inner_with_allocator(self); + unsafe { Rc::from_ptr_in(ptr.as_ptr() as _, alloc) } } } @@ -1845,7 +1845,7 @@ impl Rc { } } -impl Rc { +impl Rc { /// Attempt to downcast the `Rc` to a concrete type. /// /// # Examples @@ -1869,10 +1869,8 @@ impl Rc { pub fn downcast(self) -> Result, Self> { if (*self).is::() { unsafe { - let ptr = self.ptr.cast::>(); - let alloc = self.alloc.clone(); - forget(self); - Ok(Rc::from_inner_in(ptr, alloc)) + let (ptr, alloc) = Rc::into_inner_with_allocator(self); + Ok(Rc::from_inner_in(ptr.cast(), alloc)) } } else { Err(self) @@ -1909,10 +1907,8 @@ impl Rc { #[unstable(feature = "downcast_unchecked", issue = "90850")] pub unsafe fn downcast_unchecked(self) -> Rc { unsafe { - let ptr = self.ptr.cast::>(); - let alloc = self.alloc.clone(); - mem::forget(self); - Rc::from_inner_in(ptr, alloc) + let (ptr, alloc) = Rc::into_inner_with_allocator(self); + Rc::from_inner_in(ptr.cast(), alloc) } } } @@ -2661,12 +2657,13 @@ impl From> for Rc<[u8]> { } #[stable(feature = "boxed_slice_try_from", since = "1.43.0")] -impl TryFrom> for Rc<[T; N]> { - type Error = Rc<[T]>; +impl TryFrom> for Rc<[T; N], A> { + type Error = Rc<[T], A>; - fn try_from(boxed_slice: Rc<[T]>) -> Result { + fn try_from(boxed_slice: Rc<[T], A>) -> Result { if boxed_slice.len() == N { - Ok(unsafe { Rc::from_raw(Rc::into_raw(boxed_slice) as *mut [T; N]) }) + let (ptr, alloc) = Rc::into_inner_with_allocator(boxed_slice); + Ok(unsafe { Rc::from_inner_in(ptr.cast(), alloc) }) } else { Err(boxed_slice) } diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index 297a273d274bf..2b8efdc400bd9 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -280,8 +280,8 @@ impl Arc { impl Arc { #[inline] - fn internal_into_inner_with_allocator(self) -> (NonNull>, A) { - let this = mem::ManuallyDrop::new(self); + fn into_inner_with_allocator(this: Self) -> (NonNull>, A) { + let this = mem::ManuallyDrop::new(this); (this.ptr, unsafe { ptr::read(&this.alloc) }) } @@ -1290,7 +1290,7 @@ impl Arc, A> { #[must_use = "`self` will be dropped if the result is not used"] #[inline] pub unsafe fn assume_init(self) -> Arc { - let (ptr, alloc) = self.internal_into_inner_with_allocator(); + let (ptr, alloc) = Arc::into_inner_with_allocator(self); unsafe { Arc::from_inner_in(ptr.cast(), alloc) } } } @@ -1332,7 +1332,7 @@ impl Arc<[mem::MaybeUninit], A> { #[must_use = "`self` will be dropped if the result is not used"] #[inline] pub unsafe fn assume_init(self) -> Arc<[T], A> { - let (ptr, alloc) = self.internal_into_inner_with_allocator(); + let (ptr, alloc) = Arc::into_inner_with_allocator(self); unsafe { Arc::from_ptr_in(ptr.as_ptr() as _, alloc) } } } @@ -2499,7 +2499,7 @@ impl Arc { { if (*self).is::() { unsafe { - let (ptr, alloc) = self.internal_into_inner_with_allocator(); + let (ptr, alloc) = Arc::into_inner_with_allocator(self); Ok(Arc::from_inner_in(ptr.cast(), alloc)) } } else { @@ -2540,7 +2540,7 @@ impl Arc { T: Any + Send + Sync, { unsafe { - let (ptr, alloc) = self.internal_into_inner_with_allocator(); + let (ptr, alloc) = Arc::into_inner_with_allocator(self); Arc::from_inner_in(ptr.cast(), alloc) } } @@ -3506,7 +3506,7 @@ impl TryFrom> for Arc<[T; N], A> { fn try_from(boxed_slice: Arc<[T], A>) -> Result { if boxed_slice.len() == N { - let (ptr, alloc) = boxed_slice.internal_into_inner_with_allocator(); + let (ptr, alloc) = Arc::into_inner_with_allocator(boxed_slice); Ok(unsafe { Arc::from_inner_in(ptr.cast(), alloc) }) } else { Err(boxed_slice) From 8d8eb505b060c32df3ca4d4d431962870f73e7fe Mon Sep 17 00:00:00 2001 From: Zachary S Date: Fri, 10 May 2024 14:26:38 -0500 Subject: [PATCH 041/179] Relax A: Clone requirement on Rc/Arc::unwrap_or_clone. --- library/alloc/src/rc.rs | 2 ++ library/alloc/src/sync.rs | 2 ++ 2 files changed, 4 insertions(+) diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index 795b12d82bec8..45b205356758f 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -1809,7 +1809,9 @@ impl Rc { // reference to the allocation. unsafe { &mut this.ptr.as_mut().value } } +} +impl Rc { /// If we have the only reference to `T` then unwrap it. Otherwise, clone `T` and return the /// clone. /// diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index 2b8efdc400bd9..a35c99849b343 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -2227,7 +2227,9 @@ impl Arc { // either unique to begin with, or became one upon cloning the contents. unsafe { Self::get_mut_unchecked(this) } } +} +impl Arc { /// If we have the only reference to `T` then unwrap it. Otherwise, clone `T` and return the /// clone. /// From 781d73747890e6bca47962721453564cdbcb27a7 Mon Sep 17 00:00:00 2001 From: Infinixius <68125679+Infinixius@users.noreply.github.com> Date: Fri, 10 May 2024 23:13:32 +0000 Subject: [PATCH 042/179] Fix typo in ManuallyDrop's documentation --- library/core/src/mem/manually_drop.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/mem/manually_drop.rs b/library/core/src/mem/manually_drop.rs index 955efb9b0f98d..e0c3b9f3b51da 100644 --- a/library/core/src/mem/manually_drop.rs +++ b/library/core/src/mem/manually_drop.rs @@ -1,7 +1,7 @@ use crate::ops::{Deref, DerefMut, DerefPure}; use crate::ptr; -/// A wrapper to inhibit compiler from automatically calling `T`’s destructor. +/// A wrapper to inhibit the compiler from automatically calling `T`’s destructor. /// This wrapper is 0-cost. /// /// `ManuallyDrop` is guaranteed to have the same layout and bit validity as From e6f961c7626611a38c47d8f569acb13f51594110 Mon Sep 17 00:00:00 2001 From: Ben Kimock Date: Fri, 10 May 2024 20:28:50 -0400 Subject: [PATCH 043/179] Add @saethlin to some triagebot groups --- triagebot.toml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/triagebot.toml b/triagebot.toml index dd6a03faaaffd..3dbc60279efdb 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -933,11 +933,13 @@ arena = [ mir = [ "@davidtwco", "@oli-obk", - "@matthewjasper" + "@matthewjasper", + "@saethlin", ] mir-opt = [ "@oli-obk", "@wesleywiser", + "@saethlin", ] types = [ "@compiler-errors", @@ -1003,6 +1005,7 @@ project-exploit-mitigations = [ "/compiler/rustc_lexer" = ["compiler", "lexer"] "/compiler/rustc_llvm" = ["@cuviper"] "/compiler/rustc_codegen_llvm/src/debuginfo" = ["compiler", "debuginfo"] +"/compiler/rustc_codegen_ssa" = ["compiler", "@saethlin"] "/compiler/rustc_middle/src/mir" = ["compiler", "mir"] "/compiler/rustc_middle/src/traits" = ["compiler", "types"] "/compiler/rustc_middle/src/ty" = ["compiler", "types"] From fb619ec208b898bad1505c97ee79408b2c60926b Mon Sep 17 00:00:00 2001 From: Gurinder Singh Date: Sat, 11 May 2024 08:24:26 +0530 Subject: [PATCH 044/179] FIx ICE while casting a type with error --- compiler/rustc_hir_typeck/src/cast.rs | 5 +- .../cast/ice-cast-type-with-error-124848.rs | 18 ++++++ .../ice-cast-type-with-error-124848.stderr | 63 +++++++++++++++++++ 3 files changed, 85 insertions(+), 1 deletion(-) create mode 100644 tests/ui/cast/ice-cast-type-with-error-124848.rs create mode 100644 tests/ui/cast/ice-cast-type-with-error-124848.stderr diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs index 92f74281ab982..cecb9a61098a8 100644 --- a/compiler/rustc_hir_typeck/src/cast.rs +++ b/compiler/rustc_hir_typeck/src/cast.rs @@ -140,7 +140,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { | ty::Never | ty::Dynamic(_, _, ty::DynStar) | ty::Error(_) => { - self.dcx().span_bug(span, format!("`{t:?}` should be sized but is not?")); + let guar = self + .dcx() + .span_delayed_bug(span, format!("`{t:?}` should be sized but is not?")); + return Err(guar); } }) } diff --git a/tests/ui/cast/ice-cast-type-with-error-124848.rs b/tests/ui/cast/ice-cast-type-with-error-124848.rs new file mode 100644 index 0000000000000..9b3732b02db43 --- /dev/null +++ b/tests/ui/cast/ice-cast-type-with-error-124848.rs @@ -0,0 +1,18 @@ +// Regression test for ICE #124848 +// Tests that there is no ICE when a cast +// involves a type with error + +use std::cell::Cell; + +struct MyType<'a>(Cell>>, Pin); +//~^ ERROR use of undeclared lifetime name `'unpinned` +//~| ERROR cannot find type `Pin` in this scope + +fn main() { + let mut unpinned = MyType(Cell::new(None)); + //~^ ERROR his struct takes 2 arguments but 1 argument was supplied + let bad_addr = &unpinned as *const Cell>> as usize; + //~^ ERROR use of undeclared lifetime name `'a` + //~| ERROR use of undeclared lifetime name `'a` + //~| ERROR casting `&MyType<'_>` as `*const Cell>>` is invalid +} diff --git a/tests/ui/cast/ice-cast-type-with-error-124848.stderr b/tests/ui/cast/ice-cast-type-with-error-124848.stderr new file mode 100644 index 0000000000000..2d86bf76d1102 --- /dev/null +++ b/tests/ui/cast/ice-cast-type-with-error-124848.stderr @@ -0,0 +1,63 @@ +error[E0261]: use of undeclared lifetime name `'unpinned` + --> $DIR/ice-cast-type-with-error-124848.rs:7:32 + | +LL | struct MyType<'a>(Cell>>, Pin); + | - ^^^^^^^^^ undeclared lifetime + | | + | help: consider introducing lifetime `'unpinned` here: `'unpinned,` + +error[E0261]: use of undeclared lifetime name `'a` + --> $DIR/ice-cast-type-with-error-124848.rs:14:53 + | +LL | fn main() { + | - help: consider introducing lifetime `'a` here: `<'a>` +... +LL | let bad_addr = &unpinned as *const Cell>> as usize; + | ^^ undeclared lifetime + +error[E0261]: use of undeclared lifetime name `'a` + --> $DIR/ice-cast-type-with-error-124848.rs:14:67 + | +LL | fn main() { + | - help: consider introducing lifetime `'a` here: `<'a>` +... +LL | let bad_addr = &unpinned as *const Cell>> as usize; + | ^^ undeclared lifetime + +error[E0412]: cannot find type `Pin` in this scope + --> $DIR/ice-cast-type-with-error-124848.rs:7:60 + | +LL | struct MyType<'a>(Cell>>, Pin); + | ^^^ not found in this scope + | +help: consider importing this struct + | +LL + use std::pin::Pin; + | + +error[E0061]: this struct takes 2 arguments but 1 argument was supplied + --> $DIR/ice-cast-type-with-error-124848.rs:12:24 + | +LL | let mut unpinned = MyType(Cell::new(None)); + | ^^^^^^----------------- an argument is missing + | +note: tuple struct defined here + --> $DIR/ice-cast-type-with-error-124848.rs:7:8 + | +LL | struct MyType<'a>(Cell>>, Pin); + | ^^^^^^ +help: provide the argument + | +LL | let mut unpinned = MyType(Cell::new(None), /* value */); + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +error[E0606]: casting `&MyType<'_>` as `*const Cell>>` is invalid + --> $DIR/ice-cast-type-with-error-124848.rs:14:20 + | +LL | let bad_addr = &unpinned as *const Cell>> as usize; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 6 previous errors + +Some errors have detailed explanations: E0061, E0261, E0412, E0606. +For more information about an error, try `rustc --explain E0061`. From 9be16ebe89122d4d9f169bfe6358779e1b917c77 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Fri, 12 Apr 2024 19:11:21 -0700 Subject: [PATCH 045/179] Refactoring after the `PlaceValue` addition I added `PlaceValue` in 123775, but kept that one line-by-line simple because it touched so many places. This goes through to add more helpers & docs, and change some `PlaceRef` to `PlaceValue` where the type didn't need to be included. No behaviour changes. --- compiler/rustc_codegen_ssa/src/base.rs | 2 +- compiler/rustc_codegen_ssa/src/mir/block.rs | 15 ++-- .../rustc_codegen_ssa/src/mir/intrinsic.rs | 15 ++-- compiler/rustc_codegen_ssa/src/mir/operand.rs | 47 +++++++--- compiler/rustc_codegen_ssa/src/mir/place.rs | 87 +++++++++++-------- compiler/rustc_codegen_ssa/src/mir/rvalue.rs | 52 +++-------- .../rustc_codegen_ssa/src/traits/builder.rs | 61 +++++++------ 7 files changed, 152 insertions(+), 127 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index 358c24bfb823c..877e5b75912ea 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -283,7 +283,7 @@ pub fn coerce_unsized_into<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( } if src_f.layout.ty == dst_f.layout.ty { - bx.typed_place_copy(dst_f, src_f); + bx.typed_place_copy(dst_f.val, src_f.val, src_f.layout); } else { coerce_unsized_into(bx, src_f, dst_f); } diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index d36972d0d8662..ba6aad51316cb 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -1454,9 +1454,9 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { Some(pointee_align) => cmp::max(pointee_align, arg.layout.align.abi), None => arg.layout.align.abi, }; - let scratch = PlaceRef::alloca_aligned(bx, arg.layout, required_align); - op.val.store(bx, scratch); - (scratch.val.llval, scratch.val.align, true) + let scratch = PlaceValue::alloca(bx, arg.layout.size, required_align); + op.val.store(bx, scratch.with_type(arg.layout)); + (scratch.llval, scratch.align, true) } PassMode::Cast { .. } => { let scratch = PlaceRef::alloca(bx, arg.layout); @@ -1475,10 +1475,9 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { // For `foo(packed.large_field)`, and types with <4 byte alignment on x86, // alignment requirements may be higher than the type's alignment, so copy // to a higher-aligned alloca. - let scratch = PlaceRef::alloca_aligned(bx, arg.layout, required_align); - let op_place = PlaceRef { val: op_place_val, layout: op.layout }; - bx.typed_place_copy(scratch, op_place); - (scratch.val.llval, scratch.val.align, true) + let scratch = PlaceValue::alloca(bx, arg.layout.size, required_align); + bx.typed_place_copy(scratch, op_place_val, op.layout); + (scratch.llval, scratch.align, true) } else { (op_place_val.llval, op_place_val.align, true) } @@ -1567,7 +1566,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { if place_val.llextra.is_some() { bug!("closure arguments must be sized"); } - let tuple_ptr = PlaceRef { val: place_val, layout: tuple.layout }; + let tuple_ptr = place_val.with_type(tuple.layout); for i in 0..tuple.layout.fields.count() { let field_ptr = tuple_ptr.project_field(bx, i); let field = bx.load_operand(field_ptr); diff --git a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs index 2e008460798f8..f88deaa7abca6 100644 --- a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs +++ b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs @@ -1,4 +1,4 @@ -use super::operand::{OperandRef, OperandValue}; +use super::operand::OperandRef; use super::place::PlaceRef; use super::FunctionCx; use crate::errors; @@ -93,9 +93,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { // into the (unoptimized) direct swapping implementation, so we disable it. || bx.sess().target.arch == "spirv" { - let x_place = PlaceRef::new_sized(args[0].immediate(), pointee_layout); - let y_place = PlaceRef::new_sized(args[1].immediate(), pointee_layout); - bx.typed_place_swap(x_place, y_place); + let align = pointee_layout.align.abi; + let x_place = args[0].val.deref(align); + let y_place = args[1].val.deref(align); + bx.typed_place_swap(x_place, y_place, pointee_layout); return Ok(()); } } @@ -113,15 +114,13 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { sym::va_end => bx.va_end(args[0].immediate()), sym::size_of_val => { let tp_ty = fn_args.type_at(0); - let meta = - if let OperandValue::Pair(_, meta) = args[0].val { Some(meta) } else { None }; + let (_, meta) = args[0].val.pointer_parts(); let (llsize, _) = size_of_val::size_and_align_of_dst(bx, tp_ty, meta); llsize } sym::min_align_of_val => { let tp_ty = fn_args.type_at(0); - let meta = - if let OperandValue::Pair(_, meta) = args[0].val { Some(meta) } else { None }; + let (_, meta) = args[0].val.pointer_parts(); let (_, llalign) = size_of_val::size_and_align_of_dst(bx, tp_ty, meta); llalign } diff --git a/compiler/rustc_codegen_ssa/src/mir/operand.rs b/compiler/rustc_codegen_ssa/src/mir/operand.rs index 0479dd11ed08a..e1c584e8ed5f1 100644 --- a/compiler/rustc_codegen_ssa/src/mir/operand.rs +++ b/compiler/rustc_codegen_ssa/src/mir/operand.rs @@ -61,7 +61,7 @@ pub enum OperandValue { ZeroSized, } -impl OperandValue { +impl OperandValue { /// If this is ZeroSized/Immediate/Pair, return an array of the 0/1/2 values. /// If this is Ref, return the place. #[inline] @@ -86,6 +86,30 @@ impl OperandValue { }; OperandValue::Pair(a, b) } + + /// Treat this value as a pointer and return the data pointer and + /// optional metadata as backend values. + /// + /// If you're making a place, use [`Self::deref`] instead. + pub fn pointer_parts(self) -> (V, Option) { + match self { + OperandValue::Immediate(llptr) => (llptr, None), + OperandValue::Pair(llptr, llextra) => (llptr, Some(llextra)), + _ => bug!("OperandValue cannot be a pointer: {self:?}"), + } + } + + /// Treat this value as a pointer and return the place to which it points. + /// + /// The pointer immediate doesn't inherently know its alignment, + /// so you need to pass it in. If you want to get it from a type's ABI + /// alignment, then maybe you want [`OperandRef::deref`] instead. + /// + /// This is the inverse of [`PlaceValue::address`]. + pub fn deref(self, align: Align) -> PlaceValue { + let (llval, llextra) = self.pointer_parts(); + PlaceValue { llval, llextra, align } + } } /// An `OperandRef` is an "SSA" reference to a Rust value, along with @@ -235,6 +259,15 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> { } } + /// Asserts that this operand is a pointer (or reference) and returns + /// the place to which it points. (This requires no code to be emitted + /// as we represent places using the pointer to the place.) + /// + /// This uses [`Ty::builtin_deref`] to include the type of the place and + /// assumes the place is aligned to the pointee's usual ABI alignment. + /// + /// If you don't need the type, see [`OperandValue::pointer_parts`] + /// or [`OperandValue::deref`]. pub fn deref>(self, cx: &Cx) -> PlaceRef<'tcx, V> { if self.layout.ty.is_box() { // Derefer should have removed all Box derefs @@ -247,15 +280,8 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> { .builtin_deref(true) .unwrap_or_else(|| bug!("deref of non-pointer {:?}", self)); - let (llptr, llextra) = match self.val { - OperandValue::Immediate(llptr) => (llptr, None), - OperandValue::Pair(llptr, llextra) => (llptr, Some(llextra)), - OperandValue::Ref(..) => bug!("Deref of by-Ref operand {:?}", self), - OperandValue::ZeroSized => bug!("Deref of ZST operand {:?}", self), - }; let layout = cx.layout_of(projected_ty); - let val = PlaceValue { llval: llptr, llextra, align: layout.align.abi }; - PlaceRef { val, layout } + self.val.deref(layout.align.abi).with_type(layout) } /// If this operand is a `Pair`, we return an aggregate with the two values. @@ -448,8 +474,7 @@ impl<'a, 'tcx, V: CodegenObject> OperandValue { if val.llextra.is_some() { bug!("cannot directly store unsized values"); } - let source_place = PlaceRef { val, layout: dest.layout }; - bx.typed_place_copy_with_flags(dest, source_place, flags); + bx.typed_place_copy_with_flags(dest.val, val, dest.layout, flags); } OperandValue::Immediate(s) => { let val = bx.from_immediate(s); diff --git a/compiler/rustc_codegen_ssa/src/mir/place.rs b/compiler/rustc_codegen_ssa/src/mir/place.rs index 870a105c61d6f..971ac2defdc0d 100644 --- a/compiler/rustc_codegen_ssa/src/mir/place.rs +++ b/compiler/rustc_codegen_ssa/src/mir/place.rs @@ -10,12 +10,15 @@ use rustc_middle::mir; use rustc_middle::mir::tcx::PlaceTy; use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf, TyAndLayout}; use rustc_middle::ty::{self, Ty}; -use rustc_target::abi::{Align, FieldsShape, Int, Pointer, TagEncoding}; +use rustc_target::abi::{Align, FieldsShape, Int, Pointer, Size, TagEncoding}; use rustc_target::abi::{VariantIdx, Variants}; /// The location and extra runtime properties of the place. /// /// Typically found in a [`PlaceRef`] or an [`OperandValue::Ref`]. +/// +/// As a location in memory, this has no specific type. If you want to +/// load or store it using a typed operation, use [`Self::with_type`]. #[derive(Copy, Clone, Debug)] pub struct PlaceValue { /// A pointer to the contents of the place. @@ -35,6 +38,41 @@ impl PlaceValue { pub fn new_sized(llval: V, align: Align) -> PlaceValue { PlaceValue { llval, llextra: None, align } } + + /// Allocates a stack slot in the function for a value + /// of the specified size and alignment. + /// + /// The allocation itself is untyped. + pub fn alloca<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx, Value = V>>( + bx: &mut Bx, + size: Size, + align: Align, + ) -> PlaceValue { + let llval = bx.alloca(size, align); + PlaceValue::new_sized(llval, align) + } + + /// Creates a `PlaceRef` to this location with the given type. + pub fn with_type<'tcx>(self, layout: TyAndLayout<'tcx>) -> PlaceRef<'tcx, V> { + debug_assert!( + layout.is_unsized() || layout.abi.is_uninhabited() || self.llextra.is_none(), + "Had pointer metadata {:?} for sized type {layout:?}", + self.llextra, + ); + PlaceRef { val: self, layout } + } + + /// Gets the pointer to this place as an [`OperandValue::Immediate`] + /// or, for those needing metadata, an [`OperandValue::Pair`]. + /// + /// This is the inverse of [`OperandValue::deref`]. + pub fn address(self) -> OperandValue { + if let Some(llextra) = self.llextra { + OperandValue::Pair(self.llval, llextra) + } else { + OperandValue::Immediate(self.llval) + } + } } #[derive(Copy, Clone, Debug)] @@ -52,9 +90,7 @@ pub struct PlaceRef<'tcx, V> { impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> { pub fn new_sized(llval: V, layout: TyAndLayout<'tcx>) -> PlaceRef<'tcx, V> { - assert!(layout.is_sized()); - let val = PlaceValue::new_sized(llval, layout.align.abi); - PlaceRef { val, layout } + PlaceRef::new_sized_aligned(llval, layout, layout.align.abi) } pub fn new_sized_aligned( @@ -63,8 +99,7 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> { align: Align, ) -> PlaceRef<'tcx, V> { assert!(layout.is_sized()); - let val = PlaceValue::new_sized(llval, align); - PlaceRef { val, layout } + PlaceValue::new_sized(llval, align).with_type(layout) } // FIXME(eddyb) pass something else for the name so no work is done @@ -72,18 +107,9 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> { pub fn alloca>( bx: &mut Bx, layout: TyAndLayout<'tcx>, - ) -> Self { - Self::alloca_aligned(bx, layout, layout.align.abi) - } - - pub fn alloca_aligned>( - bx: &mut Bx, - layout: TyAndLayout<'tcx>, - align: Align, ) -> Self { assert!(layout.is_sized(), "tried to statically allocate unsized place"); - let tmp = bx.alloca(layout.size, align); - Self::new_sized_aligned(tmp, layout, align) + PlaceValue::alloca(bx, layout.size, layout.align.abi).with_type(layout) } /// Returns a place for an indirect reference to an unsized place. @@ -132,18 +158,12 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> { } else { bx.inbounds_ptradd(self.val.llval, bx.const_usize(offset.bytes())) }; - PlaceRef { - val: PlaceValue { + let val = PlaceValue { llval, - llextra: if bx.cx().type_has_metadata(field.ty) { - self.val.llextra - } else { - None - }, + llextra: if bx.cx().type_has_metadata(field.ty) { self.val.llextra } else { None }, align: effective_field_align, - }, - layout: field, - } + }; + val.with_type(field) }; // Simple cases, which don't need DST adjustment: @@ -198,7 +218,7 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> { let ptr = bx.inbounds_ptradd(self.val.llval, offset); let val = PlaceValue { llval: ptr, llextra: self.val.llextra, align: effective_field_align }; - PlaceRef { val, layout: field } + val.with_type(field) } /// Obtain the actual discriminant of a value. @@ -387,18 +407,13 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> { layout.size }; - PlaceRef { - val: PlaceValue { - llval: bx.inbounds_gep( + let llval = bx.inbounds_gep( bx.cx().backend_type(self.layout), self.val.llval, &[bx.cx().const_usize(0), llindex], - ), - llextra: None, - align: self.val.align.restrict_for_offset(offset), - }, - layout, - } + ); + let align = self.val.align.restrict_for_offset(offset); + PlaceValue::new_sized(llval, align).with_type(layout) } pub fn project_downcast>( diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs index 2976ca14c924a..e47a8198736f2 100644 --- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs +++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs @@ -74,8 +74,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { if val.llextra.is_some() { bug!("unsized coercion on an unsized rvalue"); } - let source = PlaceRef { val, layout: operand.layout }; - base::coerce_unsized_into(bx, source, dest); + base::coerce_unsized_into(bx, val.with_type(operand.layout), dest); } OperandValue::ZeroSized => { bug!("unsized coercion on a ZST rvalue"); @@ -184,10 +183,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { OperandValue::Immediate(..) | OperandValue::Pair(..) => { // When we have immediate(s), the alignment of the source is irrelevant, // so we can store them using the destination's alignment. - src.val.store( - bx, - PlaceRef::new_sized_aligned(dst.val.llval, src.layout, dst.val.align), - ); + src.val.store(bx, dst.val.with_type(src.layout)); } } } @@ -225,8 +221,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { OperandValue::Ref(source_place_val) => { debug_assert_eq!(source_place_val.llextra, None); debug_assert!(matches!(operand_kind, OperandValueKind::Ref)); - let fake_place = PlaceRef { val: source_place_val, layout: cast }; - Some(bx.load_operand(fake_place).val) + Some(bx.load_operand(source_place_val.with_type(cast)).val) } OperandValue::ZeroSized => { let OperandValueKind::ZeroSized = operand_kind else { @@ -452,23 +447,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } mir::CastKind::PointerCoercion(PointerCoercion::Unsize) => { assert!(bx.cx().is_backend_scalar_pair(cast)); - let (lldata, llextra) = match operand.val { - OperandValue::Pair(lldata, llextra) => { - // unsize from a fat pointer -- this is a - // "trait-object-to-supertrait" coercion. - (lldata, Some(llextra)) - } - OperandValue::Immediate(lldata) => { - // "standard" unsize - (lldata, None) - } - OperandValue::Ref(..) => { - bug!("by-ref operand {:?} in `codegen_rvalue_operand`", operand); - } - OperandValue::ZeroSized => { - bug!("zero-sized operand {:?} in `codegen_rvalue_operand`", operand); - } - }; + let (lldata, llextra) = operand.val.pointer_parts(); let (lldata, llextra) = base::unsize_ptr(bx, lldata, operand.layout.ty, cast.ty, llextra); OperandValue::Pair(lldata, llextra) @@ -489,12 +468,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } } mir::CastKind::DynStar => { - let (lldata, llextra) = match operand.val { - OperandValue::Ref(..) => todo!(), - OperandValue::Immediate(v) => (v, None), - OperandValue::Pair(v, l) => (v, Some(l)), - OperandValue::ZeroSized => bug!("ZST -- which is not PointerLike -- in DynStar"), - }; + let (lldata, llextra) = operand.val.pointer_parts(); let (lldata, llextra) = base::cast_to_dyn_star(bx, lldata, operand.layout, cast.ty, llextra); OperandValue::Pair(lldata, llextra) @@ -812,16 +786,18 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { mk_ptr_ty: impl FnOnce(TyCtxt<'tcx>, Ty<'tcx>) -> Ty<'tcx>, ) -> OperandRef<'tcx, Bx::Value> { let cg_place = self.codegen_place(bx, place.as_ref()); + let val = cg_place.val.address(); let ty = cg_place.layout.ty; - - // Note: places are indirect, so storing the `llval` into the - // destination effectively creates a reference. - let val = if !bx.cx().type_has_metadata(ty) { - OperandValue::Immediate(cg_place.val.llval) + debug_assert!( + if bx.cx().type_has_metadata(ty) { + matches!(val, OperandValue::Pair(..)) } else { - OperandValue::Pair(cg_place.val.llval, cg_place.val.llextra.unwrap()) - }; + matches!(val, OperandValue::Immediate(..)) + }, + "Address of place was unexpectedly {val:?} for pointee type {ty:?}", + ); + OperandRef { val, layout: self.cx.layout_of(mk_ptr_ty(self.cx.tcx(), ty)) } } diff --git a/compiler/rustc_codegen_ssa/src/traits/builder.rs b/compiler/rustc_codegen_ssa/src/traits/builder.rs index 51b22bfaf2558..fdeccb9070082 100644 --- a/compiler/rustc_codegen_ssa/src/traits/builder.rs +++ b/compiler/rustc_codegen_ssa/src/traits/builder.rs @@ -186,6 +186,15 @@ pub trait BuilderMethods<'a, 'tcx>: align: Align, flags: MemFlags, ) -> Self::Value; + fn store_to_place_with_flags( + &mut self, + val: Self::Value, + place: PlaceValue, + flags: MemFlags, + ) -> Self::Value { + debug_assert_eq!(place.llextra, None); + self.store_with_flags(val, place.llval, place.align, flags) + } fn atomic_store( &mut self, val: Self::Value, @@ -286,35 +295,36 @@ pub trait BuilderMethods<'a, 'tcx>: /// (For example, typed load-stores with alias metadata.) fn typed_place_copy( &mut self, - dst: PlaceRef<'tcx, Self::Value>, - src: PlaceRef<'tcx, Self::Value>, + dst: PlaceValue, + src: PlaceValue, + layout: TyAndLayout<'tcx>, ) { - self.typed_place_copy_with_flags(dst, src, MemFlags::empty()); + self.typed_place_copy_with_flags(dst, src, layout, MemFlags::empty()); } fn typed_place_copy_with_flags( &mut self, - dst: PlaceRef<'tcx, Self::Value>, - src: PlaceRef<'tcx, Self::Value>, + dst: PlaceValue, + src: PlaceValue, + layout: TyAndLayout<'tcx>, flags: MemFlags, ) { - debug_assert!(src.val.llextra.is_none(), "cannot directly copy from unsized values"); - debug_assert!(dst.val.llextra.is_none(), "cannot directly copy into unsized values"); - debug_assert_eq!(dst.layout.size, src.layout.size); + debug_assert!(layout.is_sized(), "cannot typed-copy an unsigned type"); + debug_assert!(src.llextra.is_none(), "cannot directly copy from unsized values"); + debug_assert!(dst.llextra.is_none(), "cannot directly copy into unsized values"); if flags.contains(MemFlags::NONTEMPORAL) { // HACK(nox): This is inefficient but there is no nontemporal memcpy. - let ty = self.backend_type(dst.layout); - let val = self.load_from_place(ty, src.val); - self.store_with_flags(val, dst.val.llval, dst.val.align, flags); - } else if self.sess().opts.optimize == OptLevel::No && self.is_backend_immediate(dst.layout) - { + let ty = self.backend_type(layout); + let val = self.load_from_place(ty, src); + self.store_to_place_with_flags(val, dst, flags); + } else if self.sess().opts.optimize == OptLevel::No && self.is_backend_immediate(layout) { // If we're not optimizing, the aliasing information from `memcpy` // isn't useful, so just load-store the value for smaller code. - let temp = self.load_operand(src); - temp.val.store_with_flags(self, dst, flags); - } else if !dst.layout.is_zst() { - let bytes = self.const_usize(dst.layout.size.bytes()); - self.memcpy(dst.val.llval, dst.val.align, src.val.llval, src.val.align, bytes, flags); + let temp = self.load_operand(src.with_type(layout)); + temp.val.store_with_flags(self, dst.with_type(layout), flags); + } else if !layout.is_zst() { + let bytes = self.const_usize(layout.size.bytes()); + self.memcpy(dst.llval, dst.align, src.llval, src.align, bytes, flags); } } @@ -327,18 +337,19 @@ pub trait BuilderMethods<'a, 'tcx>: /// cases (in non-debug), preferring the fallback body instead. fn typed_place_swap( &mut self, - left: PlaceRef<'tcx, Self::Value>, - right: PlaceRef<'tcx, Self::Value>, + left: PlaceValue, + right: PlaceValue, + layout: TyAndLayout<'tcx>, ) { - let mut temp = self.load_operand(left); + let mut temp = self.load_operand(left.with_type(layout)); if let OperandValue::Ref(..) = temp.val { // The SSA value isn't stand-alone, so we need to copy it elsewhere - let alloca = PlaceRef::alloca(self, left.layout); - self.typed_place_copy(alloca, left); + let alloca = PlaceRef::alloca(self, layout); + self.typed_place_copy(alloca.val, left, layout); temp = self.load_operand(alloca); } - self.typed_place_copy(left, right); - temp.val.store(self, right); + self.typed_place_copy(left, right, layout); + temp.val.store(self, right.with_type(layout)); } fn select( From 9fb49faf4012ed677b9cb41f5d9618c8ce2585a8 Mon Sep 17 00:00:00 2001 From: okaneco <47607823+okaneco@users.noreply.github.com> Date: Wed, 7 Feb 2024 11:19:01 -0500 Subject: [PATCH 046/179] Stabilize `byte_slice_trim_ascii` for `&[u8]`/`&str` Remove feature from documentation examples Add rustc_const_stable attribute to stabilized functions Update intra-doc link for `u8::is_ascii_whitespace` on `&[u8]` functions --- library/core/src/slice/ascii.rs | 21 +++++++++------------ library/core/src/str/mod.rs | 15 ++++++--------- 2 files changed, 15 insertions(+), 21 deletions(-) diff --git a/library/core/src/slice/ascii.rs b/library/core/src/slice/ascii.rs index 5c4f0bf9b2b49..8ad045275adec 100644 --- a/library/core/src/slice/ascii.rs +++ b/library/core/src/slice/ascii.rs @@ -114,18 +114,17 @@ impl [u8] { /// Returns a byte slice with leading ASCII whitespace bytes removed. /// /// 'Whitespace' refers to the definition used by - /// `u8::is_ascii_whitespace`. + /// [`u8::is_ascii_whitespace`]. /// /// # Examples /// /// ``` - /// #![feature(byte_slice_trim_ascii)] - /// /// assert_eq!(b" \t hello world\n".trim_ascii_start(), b"hello world\n"); /// assert_eq!(b" ".trim_ascii_start(), b""); /// assert_eq!(b"".trim_ascii_start(), b""); /// ``` - #[unstable(feature = "byte_slice_trim_ascii", issue = "94035")] + #[stable(feature = "byte_slice_trim_ascii", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "byte_slice_trim_ascii", since = "CURRENT_RUSTC_VERSION")] #[inline] pub const fn trim_ascii_start(&self) -> &[u8] { let mut bytes = self; @@ -144,18 +143,17 @@ impl [u8] { /// Returns a byte slice with trailing ASCII whitespace bytes removed. /// /// 'Whitespace' refers to the definition used by - /// `u8::is_ascii_whitespace`. + /// [`u8::is_ascii_whitespace`]. /// /// # Examples /// /// ``` - /// #![feature(byte_slice_trim_ascii)] - /// /// assert_eq!(b"\r hello world\n ".trim_ascii_end(), b"\r hello world"); /// assert_eq!(b" ".trim_ascii_end(), b""); /// assert_eq!(b"".trim_ascii_end(), b""); /// ``` - #[unstable(feature = "byte_slice_trim_ascii", issue = "94035")] + #[stable(feature = "byte_slice_trim_ascii", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "byte_slice_trim_ascii", since = "CURRENT_RUSTC_VERSION")] #[inline] pub const fn trim_ascii_end(&self) -> &[u8] { let mut bytes = self; @@ -175,18 +173,17 @@ impl [u8] { /// removed. /// /// 'Whitespace' refers to the definition used by - /// `u8::is_ascii_whitespace`. + /// [`u8::is_ascii_whitespace`]. /// /// # Examples /// /// ``` - /// #![feature(byte_slice_trim_ascii)] - /// /// assert_eq!(b"\r hello world\n ".trim_ascii(), b"hello world"); /// assert_eq!(b" ".trim_ascii(), b""); /// assert_eq!(b"".trim_ascii(), b""); /// ``` - #[unstable(feature = "byte_slice_trim_ascii", issue = "94035")] + #[stable(feature = "byte_slice_trim_ascii", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "byte_slice_trim_ascii", since = "CURRENT_RUSTC_VERSION")] #[inline] pub const fn trim_ascii(&self) -> &[u8] { self.trim_ascii_start().trim_ascii_end() diff --git a/library/core/src/str/mod.rs b/library/core/src/str/mod.rs index b6f65907d3c30..669cdc92e3586 100644 --- a/library/core/src/str/mod.rs +++ b/library/core/src/str/mod.rs @@ -2531,15 +2531,14 @@ impl str { /// # Examples /// /// ``` - /// #![feature(byte_slice_trim_ascii)] - /// /// assert_eq!(" \t \u{3000}hello world\n".trim_ascii_start(), "\u{3000}hello world\n"); /// assert_eq!(" ".trim_ascii_start(), ""); /// assert_eq!("".trim_ascii_start(), ""); /// ``` - #[unstable(feature = "byte_slice_trim_ascii", issue = "94035")] #[must_use = "this returns the trimmed string as a new slice, \ without modifying the original"] + #[stable(feature = "byte_slice_trim_ascii", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "byte_slice_trim_ascii", since = "CURRENT_RUSTC_VERSION")] #[inline] pub const fn trim_ascii_start(&self) -> &str { // SAFETY: Removing ASCII characters from a `&str` does not invalidate @@ -2557,15 +2556,14 @@ impl str { /// # Examples /// /// ``` - /// #![feature(byte_slice_trim_ascii)] - /// /// assert_eq!("\r hello world\u{3000}\n ".trim_ascii_end(), "\r hello world\u{3000}"); /// assert_eq!(" ".trim_ascii_end(), ""); /// assert_eq!("".trim_ascii_end(), ""); /// ``` - #[unstable(feature = "byte_slice_trim_ascii", issue = "94035")] #[must_use = "this returns the trimmed string as a new slice, \ without modifying the original"] + #[stable(feature = "byte_slice_trim_ascii", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "byte_slice_trim_ascii", since = "CURRENT_RUSTC_VERSION")] #[inline] pub const fn trim_ascii_end(&self) -> &str { // SAFETY: Removing ASCII characters from a `&str` does not invalidate @@ -2584,15 +2582,14 @@ impl str { /// # Examples /// /// ``` - /// #![feature(byte_slice_trim_ascii)] - /// /// assert_eq!("\r hello world\n ".trim_ascii(), "hello world"); /// assert_eq!(" ".trim_ascii(), ""); /// assert_eq!("".trim_ascii(), ""); /// ``` - #[unstable(feature = "byte_slice_trim_ascii", issue = "94035")] #[must_use = "this returns the trimmed string as a new slice, \ without modifying the original"] + #[stable(feature = "byte_slice_trim_ascii", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "byte_slice_trim_ascii", since = "CURRENT_RUSTC_VERSION")] #[inline] pub const fn trim_ascii(&self) -> &str { // SAFETY: Removing ASCII characters from a `&str` does not invalidate From e444017b4942bf0137b8679d8e8811a8cc604cb4 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 10 May 2024 11:04:53 -0400 Subject: [PATCH 047/179] Consolidate obligation cause codes for where clauses --- .../rustc_borrowck/src/region_infer/mod.rs | 5 +-- .../src/transform/check_consts/check.rs | 4 +- .../src/check/compare_impl_item.rs | 11 ++---- .../rustc_hir_analysis/src/check/wfcheck.rs | 2 +- .../src/impl_wf_check/min_specialization.rs | 2 +- .../rustc_hir_typeck/src/fn_ctxt/_impl.rs | 6 +-- .../src/fn_ctxt/adjust_fulfillment_errors.rs | 5 +-- .../rustc_hir_typeck/src/fn_ctxt/checks.rs | 5 +-- .../rustc_hir_typeck/src/method/confirm.rs | 16 +++----- compiler/rustc_hir_typeck/src/method/probe.rs | 20 +++------- .../rustc_hir_typeck/src/method/suggest.rs | 6 +-- .../src/infer/error_reporting/mod.rs | 5 ++- .../mismatched_static_lifetime.rs | 7 +++- .../nice_region_error/placeholder_error.rs | 7 ++-- .../nice_region_error/static_impl_trait.rs | 2 +- .../src/infer/error_reporting/note.rs | 11 +++--- .../src/infer/outlives/obligations.rs | 8 +++- compiler/rustc_middle/src/traits/mod.rs | 25 +++++------- .../src/traits/error_reporting/suggestions.rs | 38 ++++++++++--------- .../error_reporting/type_err_ctxt_ext.rs | 26 ++++++------- .../src/traits/project.rs | 14 +------ .../rustc_trait_selection/src/traits/wf.rs | 6 +-- .../trait-bounds/issue-59311.stderr | 26 ++++++++++--- .../trait-bounds/trivial-does-not-hold.rs | 11 ++++++ .../trait-bounds/trivial-does-not-hold.stderr | 10 +++++ 25 files changed, 138 insertions(+), 140 deletions(-) create mode 100644 tests/ui/higher-ranked/trait-bounds/trivial-does-not-hold.rs create mode 100644 tests/ui/higher-ranked/trait-bounds/trivial-does-not-hold.stderr diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs index e58723c2ec954..167ca7ba04570 100644 --- a/compiler/rustc_borrowck/src/region_infer/mod.rs +++ b/compiler/rustc_borrowck/src/region_infer/mod.rs @@ -2059,10 +2059,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { // We currently do not store the `DefId` in the `ConstraintCategory` // for performances reasons. The error reporting code used by NLL only // uses the span, so this doesn't cause any problems at the moment. - Some(ObligationCauseCode::SpannedWhereClause( - CRATE_DEF_ID.to_def_id(), - predicate_span, - )) + Some(ObligationCauseCode::WhereClause(CRATE_DEF_ID.to_def_id(), predicate_span)) } else { None } diff --git a/compiler/rustc_const_eval/src/transform/check_consts/check.rs b/compiler/rustc_const_eval/src/transform/check_consts/check.rs index d43dc467c0f0f..46cc9f69373f5 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs @@ -11,7 +11,7 @@ use rustc_middle::mir::*; use rustc_middle::ty::{self, adjustment::PointerCoercion, Ty, TyCtxt}; use rustc_middle::ty::{Instance, InstanceDef, TypeVisitableExt}; use rustc_mir_dataflow::Analysis; -use rustc_span::{sym, Span, Symbol}; +use rustc_span::{sym, Span, Symbol, DUMMY_SP}; use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _; use rustc_trait_selection::traits::{self, ObligationCauseCode, ObligationCtxt}; use rustc_type_ir::visit::{TypeSuperVisitable, TypeVisitor}; @@ -738,7 +738,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { let cause = ObligationCause::new( terminator.source_info.span, self.body.source.def_id().expect_local(), - ObligationCauseCode::WhereClause(callee), + ObligationCauseCode::WhereClause(callee, DUMMY_SP), ); let normalized_predicates = ocx.normalize(&cause, param_env, predicates); ocx.register_obligations(traits::predicates_for_generics( diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index b2b82670d8b03..db223f9d80f39 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -819,7 +819,7 @@ impl<'tcx> TypeFolder> for ImplTraitInTraitCollector<'_, 'tcx> { ObligationCause::new( self.span, self.body_id, - ObligationCauseCode::SpannedWhereClause(proj.def_id, pred_span), + ObligationCauseCode::WhereClause(proj.def_id, pred_span), ), self.param_env, pred, @@ -2011,11 +2011,7 @@ pub(super) fn check_type_bounds<'tcx>( }, ); let mk_cause = |span: Span| { - let code = if span.is_dummy() { - ObligationCauseCode::WhereClause(trait_ty.def_id) - } else { - ObligationCauseCode::SpannedWhereClause(trait_ty.def_id, span) - }; + let code = ObligationCauseCode::WhereClause(trait_ty.def_id, span); ObligationCause::new(impl_ty_span, impl_ty_def_id, code) }; @@ -2251,8 +2247,7 @@ fn try_report_async_mismatch<'tcx>( }; for error in errors { - if let ObligationCauseCode::SpannedWhereClause(def_id, _) = - *error.root_obligation.cause.code() + if let ObligationCauseCode::WhereClause(def_id, _) = *error.root_obligation.cause.code() && def_id == async_future_def_id && let Some(proj) = error.root_obligation.predicate.to_opt_poly_projection_pred() && let Some(proj) = proj.no_bound_vars() diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 0578317f91459..e50af9605fd0d 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -1550,7 +1550,7 @@ fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, span: Span, def_id let cause = traits::ObligationCause::new( sp, wfcx.body_def_id, - ObligationCauseCode::WhereClause(def_id.to_def_id()), + ObligationCauseCode::WhereClause(def_id.to_def_id(), DUMMY_SP), ); traits::Obligation::new(tcx, cause, wfcx.param_env, pred) }); diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs index de697b04ebf77..6dd59a62a7a46 100644 --- a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs +++ b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs @@ -212,7 +212,7 @@ fn get_impl_args( traits::ObligationCause::new( impl1_span, impl1_def_id, - traits::ObligationCauseCode::SpannedWhereClause(impl2_node.def_id(), span), + traits::ObligationCauseCode::WhereClause(impl2_node.def_id(), span), ) }, ); diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 881f726e1da80..b32cab6d3f71f 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -1409,11 +1409,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { hir_id: HirId, ) { self.add_required_obligations_with_code(span, def_id, args, |idx, span| { - if span.is_dummy() { - ObligationCauseCode::WhereClauseInExpr(def_id, hir_id, idx) - } else { - ObligationCauseCode::SpannedWhereClauseInExpr(def_id, span, hir_id, idx) - } + ObligationCauseCode::WhereClauseInExpr(def_id, span, hir_id, idx) }) } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs index 26996397659ec..c3525f175da8e 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs @@ -14,8 +14,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { &self, error: &mut traits::FulfillmentError<'tcx>, ) -> bool { - let (ObligationCauseCode::WhereClauseInExpr(def_id, hir_id, idx) - | ObligationCauseCode::SpannedWhereClauseInExpr(def_id, _, hir_id, idx)) = + let ObligationCauseCode::WhereClauseInExpr(def_id, _, hir_id, idx) = *error.obligation.cause.code().peel_derives() else { return false; @@ -512,7 +511,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expr: &'tcx hir::Expr<'tcx>, ) -> Result<&'tcx hir::Expr<'tcx>, &'tcx hir::Expr<'tcx>> { match obligation_cause_code { - traits::ObligationCauseCode::SpannedWhereClauseInExpr(_, _, _, _) => { + traits::ObligationCauseCode::WhereClauseInExpr(_, _, _, _) => { // This is the "root"; we assume that the `expr` is already pointing here. // Therefore, we return `Ok` so that this `expr` can be refined further. Ok(expr) diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index 4bf82355b622a..5fa715dc7618b 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -2013,8 +2013,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { for (span, code) in errors_causecode { self.dcx().try_steal_modify_and_emit_err(span, StashKey::MaybeForgetReturn, |err| { if let Some(fn_sig) = self.body_fn_sig() - && let ObligationCauseCode::SpannedWhereClauseInExpr(_, _, binding_hir_id, ..) = - code + && let ObligationCauseCode::WhereClauseInExpr(_, _, binding_hir_id, ..) = code && !fn_sig.output().is_unit() { let mut block_num = 0; @@ -2103,7 +2102,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // // This is because due to normalization, we often register duplicate // obligations with misc obligations that are basically impossible to - // line back up with a useful SpannedWhereClauseInExpr. + // line back up with a useful WhereClauseInExpr. for error in not_adjusted { for (span, predicate, cause) in &remap_cause { if *predicate == error.obligation.predicate diff --git a/compiler/rustc_hir_typeck/src/method/confirm.rs b/compiler/rustc_hir_typeck/src/method/confirm.rs index 56c296fc1c00e..007ec7ff378ab 100644 --- a/compiler/rustc_hir_typeck/src/method/confirm.rs +++ b/compiler/rustc_hir_typeck/src/method/confirm.rs @@ -564,16 +564,12 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { // `self.add_required_obligations(self.span, def_id, &all_args);` for obligation in traits::predicates_for_generics( |idx, span| { - let code = if span.is_dummy() { - ObligationCauseCode::WhereClauseInExpr(def_id, self.call_expr.hir_id, idx) - } else { - ObligationCauseCode::SpannedWhereClauseInExpr( - def_id, - span, - self.call_expr.hir_id, - idx, - ) - }; + let code = ObligationCauseCode::WhereClauseInExpr( + def_id, + span, + self.call_expr.hir_id, + idx, + ); traits::ObligationCause::new(self.span, self.body_id, code) }, self.param_env, diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index 434bd9574986e..e9446b862fa0d 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -1401,20 +1401,12 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { // Convert the bounds into obligations. ocx.register_obligations(traits::predicates_for_generics( |idx, span| { - let code = if span.is_dummy() { - ObligationCauseCode::WhereClauseInExpr( - impl_def_id, - self.scope_expr_id, - idx, - ) - } else { - ObligationCauseCode::SpannedWhereClauseInExpr( - impl_def_id, - span, - self.scope_expr_id, - idx, - ) - }; + let code = ObligationCauseCode::WhereClauseInExpr( + impl_def_id, + span, + self.scope_expr_id, + idx, + ); ObligationCause::new(self.span, self.body_id, code) }, self.param_env, diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index d1891a032e102..0483bd0357675 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -832,9 +832,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { (data.impl_or_alias_def_id, data.span) } Some( - ObligationCauseCode::SpannedWhereClauseInExpr(def_id, span, _, _) - | ObligationCauseCode::SpannedWhereClause(def_id, span), - ) => (*def_id, *span), + ObligationCauseCode::WhereClauseInExpr(def_id, span, _, _) + | ObligationCauseCode::WhereClause(def_id, span), + ) if !span.is_dummy() => (*def_id, *span), _ => continue, }; diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 46310941113d4..3488517a4ef9b 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -883,9 +883,10 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { err.help("...or use `match` instead of `let...else`"); } _ => { - if let ObligationCauseCode::SpannedWhereClause(_, span) - | ObligationCauseCode::SpannedWhereClauseInExpr(_, span, ..) = + if let ObligationCauseCode::WhereClause(_, span) + | ObligationCauseCode::WhereClauseInExpr(_, span, ..) = cause.code().peel_derives() + && !span.is_dummy() && let TypeError::RegionsPlaceholderMismatch = terr { err.span_note(*span, "the lifetime requirement is introduced here"); diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mismatched_static_lifetime.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mismatched_static_lifetime.rs index b6c38739e9af5..fdfce7f8f73c7 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mismatched_static_lifetime.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mismatched_static_lifetime.rs @@ -38,11 +38,14 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { let ObligationCauseCode::MatchImpl(parent, impl_def_id) = code else { return None; }; - let (ObligationCauseCode::SpannedWhereClause(_, binding_span) - | ObligationCauseCode::SpannedWhereClauseInExpr(_, binding_span, ..)) = *parent.code() + let (ObligationCauseCode::WhereClause(_, binding_span) + | ObligationCauseCode::WhereClauseInExpr(_, binding_span, ..)) = *parent.code() else { return None; }; + if binding_span.is_dummy() { + return None; + } // FIXME: we should point at the lifetime let multi_span: MultiSpan = vec![binding_span].into(); diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs index dbd165c093aaf..31d45133eb0bc 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs @@ -10,7 +10,7 @@ use crate::traits::{ObligationCause, ObligationCauseCode}; use rustc_data_structures::intern::Interned; use rustc_errors::{Diag, IntoDiagArg}; use rustc_hir::def::Namespace; -use rustc_hir::def_id::DefId; +use rustc_hir::def_id::{DefId, CRATE_DEF_ID}; use rustc_middle::ty::error::ExpectedFound; use rustc_middle::ty::print::{FmtPrinter, Print, PrintTraitRefExt as _, RegionHighlightMode}; use rustc_middle::ty::GenericArgsRef; @@ -240,8 +240,9 @@ impl<'tcx> NiceRegionError<'_, 'tcx> { let span = cause.span(); let (leading_ellipsis, satisfy_span, where_span, dup_span, def_id) = - if let ObligationCauseCode::WhereClause(def_id) - | ObligationCauseCode::WhereClauseInExpr(def_id, ..) = *cause.code() + if let ObligationCauseCode::WhereClause(def_id, span) + | ObligationCauseCode::WhereClauseInExpr(def_id, span, ..) = *cause.code() + && def_id != CRATE_DEF_ID.to_def_id() { ( true, diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs index e5950a7c9350e..8a1e3a7ac71b7 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs @@ -214,7 +214,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { _ => cause.code(), } && let ( - &ObligationCauseCode::WhereClause(item_def_id) + &ObligationCauseCode::WhereClause(item_def_id, _) | &ObligationCauseCode::WhereClauseInExpr(item_def_id, ..), None, ) = (code, override_error_code) diff --git a/compiler/rustc_infer/src/infer/error_reporting/note.rs b/compiler/rustc_infer/src/infer/error_reporting/note.rs index ecbe65fe9261e..00dd20a2cc270 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/note.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/note.rs @@ -357,21 +357,22 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { infer::Subtype(box ref trace) if matches!( &trace.cause.code().peel_derives(), - ObligationCauseCode::SpannedWhereClause(..) - | ObligationCauseCode::SpannedWhereClauseInExpr(..) + ObligationCauseCode::WhereClause(..) + | ObligationCauseCode::WhereClauseInExpr(..) ) => { // Hack to get around the borrow checker because trace.cause has an `Rc`. - if let ObligationCauseCode::SpannedWhereClause(_, span) - | ObligationCauseCode::SpannedWhereClauseInExpr(_, span, ..) = + if let ObligationCauseCode::WhereClause(_, span) + | ObligationCauseCode::WhereClauseInExpr(_, span, ..) = &trace.cause.code().peel_derives() + && !span.is_dummy() { let span = *span; self.report_concrete_failure(placeholder_origin, sub, sup) .with_span_note(span, "the lifetime requirement is introduced here") } else { unreachable!( - "control flow ensures we have a `BindingObligation` or `SpannedWhereClauseInExpr` here..." + "control flow ensures we have a `BindingObligation` or `WhereClauseInExpr` here..." ) } } diff --git a/compiler/rustc_infer/src/infer/outlives/obligations.rs b/compiler/rustc_infer/src/infer/outlives/obligations.rs index 94f8a2664f9cd..e0d23d7629f99 100644 --- a/compiler/rustc_infer/src/infer/outlives/obligations.rs +++ b/compiler/rustc_infer/src/infer/outlives/obligations.rs @@ -103,8 +103,12 @@ impl<'tcx> InferCtxt<'tcx> { cause.span, sup_type, match cause.code().peel_derives() { - ObligationCauseCode::SpannedWhereClause(_, span) - | ObligationCauseCode::SpannedWhereClauseInExpr(_, span, ..) => Some(*span), + ObligationCauseCode::WhereClause(_, span) + | ObligationCauseCode::WhereClauseInExpr(_, span, ..) + if !span.is_dummy() => + { + Some(*span) + } _ => None, }, ) diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs index 6c33a29ea8122..fb796bf87a1dd 100644 --- a/compiler/rustc_middle/src/traits/mod.rs +++ b/compiler/rustc_middle/src/traits/mod.rs @@ -247,22 +247,15 @@ pub enum ObligationCauseCode<'tcx> { /// A tuple is WF only if its middle elements are `Sized`. TupleElem, - /// Must satisfy all of the where-clause predicates of the - /// given item. - WhereClause(DefId), - - /// Like `WhereClause`, but carries the span of the - /// predicate when it can be identified. - SpannedWhereClause(DefId, Span), - - /// Like `WhereClause`, but carries the `HirId` of the - /// expression that caused the obligation, and the `usize` - /// indicates exactly which predicate it is in the list of - /// instantiated predicates. - WhereClauseInExpr(DefId, HirId, usize), - - /// Combines `SpannedWhereClause` and `WhereClauseInExpr`. - SpannedWhereClauseInExpr(DefId, Span, HirId, usize), + /// Represents a clause that comes from a specific item. + /// The span corresponds to the clause. + WhereClause(DefId, Span), + + /// Like `WhereClause`, but also identifies the expression + /// which requires the `where` clause to be proven, and also + /// identifies the index of the predicate in the `predicates_of` + /// list of the item. + WhereClauseInExpr(DefId, Span, HirId, usize), /// A type like `&'a T` is WF only if `T: 'a`. ReferenceOutlivesReferent(Ty<'tcx>), diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index 597effcbbf0e7..51a4e910d621e 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -1205,8 +1205,13 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { let code = match obligation.cause.code() { ObligationCauseCode::FunctionArg { parent_code, .. } => parent_code, - c @ ObligationCauseCode::WhereClause(_) - | c @ ObligationCauseCode::WhereClauseInExpr(..) => c, + // FIXME(compiler-errors): This is kind of a mess, but required for obligations + // that come from a path expr to affect the *call* expr. + c @ ObligationCauseCode::WhereClauseInExpr(_, _, hir_id, _) + if self.tcx.hir().span(*hir_id).lo() == span.lo() => + { + c + } c if matches!( span.ctxt().outer_expn_data().kind, ExpnKind::Desugaring(DesugaringKind::ForLoop) @@ -1262,8 +1267,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { let mut_ref_self_ty_satisfies_pred = mk_result(trait_pred_and_mut_ref); let (ref_inner_ty_satisfies_pred, ref_inner_ty_mut) = - if let ObligationCauseCode::WhereClause(_) - | ObligationCauseCode::WhereClauseInExpr(..) = obligation.cause.code() + if let ObligationCauseCode::WhereClauseInExpr(..) = obligation.cause.code() && let ty::Ref(_, ty, mutability) = old_pred.self_ty().skip_binder().kind() { ( @@ -1403,10 +1407,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { if let ObligationCauseCode::ImplDerived(cause) = &*code { try_borrowing(cause.derived.parent_trait_pred, &[]) - } else if let ObligationCauseCode::SpannedWhereClause(_, _) - | ObligationCauseCode::WhereClause(_) - | ObligationCauseCode::WhereClauseInExpr(..) - | ObligationCauseCode::SpannedWhereClauseInExpr(..) = code + } else if let ObligationCauseCode::WhereClause(..) + | ObligationCauseCode::WhereClauseInExpr(..) = code { try_borrowing(poly_trait_pred, &never_suggest_borrow) } else { @@ -2102,10 +2104,10 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { cause: &ObligationCauseCode<'tcx>, err: &mut Diag<'tcx>, ) { - // First, look for an `SpannedWhereClauseInExpr`, which means we can get + // First, look for an `WhereClauseInExpr`, which means we can get // the uninstantiated predicate list of the called function. And check // that the predicate that we failed to satisfy is a `Fn`-like trait. - if let ObligationCauseCode::SpannedWhereClauseInExpr(def_id, _, _, idx) = cause + if let ObligationCauseCode::WhereClauseInExpr(def_id, _, _, idx) = cause && let predicates = self.tcx.predicates_of(def_id).instantiate_identity(self.tcx) && let Some(pred) = predicates.predicates.get(*idx) && let ty::ClauseKind::Trait(trait_pred) = pred.kind().skip_binder() @@ -2746,12 +2748,10 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { ObligationCauseCode::TupleElem => { err.note("only the last element of a tuple may have a dynamically sized type"); } - ObligationCauseCode::WhereClause(_) | ObligationCauseCode::WhereClauseInExpr(..) => { - // We hold the `DefId` of the item introducing the obligation, but displaying it - // doesn't add user usable information. It always point at an associated item. - } - ObligationCauseCode::SpannedWhereClause(item_def_id, span) - | ObligationCauseCode::SpannedWhereClauseInExpr(item_def_id, span, ..) => { + ObligationCauseCode::WhereClause(item_def_id, span) + | ObligationCauseCode::WhereClauseInExpr(item_def_id, span, ..) + if !span.is_dummy() => + { let item_name = tcx.def_path_str(item_def_id); let short_item_name = with_forced_trimmed_paths!(tcx.def_path_str(item_def_id)); let mut multispan = MultiSpan::from(span); @@ -2882,6 +2882,10 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { err.help(help); } } + ObligationCauseCode::WhereClause(..) | ObligationCauseCode::WhereClauseInExpr(..) => { + // We hold the `DefId` of the item introducing the obligation, but displaying it + // doesn't add user usable information. It always point at an associated item. + } ObligationCauseCode::Coercion { source, target } => { let source = tcx.short_ty_string(self.resolve_vars_if_possible(source), &mut long_ty_file); @@ -3802,7 +3806,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { // to an associated type (as seen from `trait_pred`) in the predicate. Like in // trait_pred `S: Sum<::Item>` and predicate `i32: Sum<&()>` let mut type_diffs = vec![]; - if let ObligationCauseCode::SpannedWhereClauseInExpr(def_id, _, _, idx) = parent_code + if let ObligationCauseCode::WhereClauseInExpr(def_id, _, _, idx) = parent_code && let Some(node_args) = typeck_results.node_args_opt(call_hir_id) && let where_clauses = self.tcx.predicates_of(def_id).instantiate(self.tcx, node_args) diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs index cdde12af8ea18..92fe50883d0fd 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs @@ -1535,9 +1535,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { *err, ); let code = error.obligation.cause.code().peel_derives().peel_match_impls(); - if let ObligationCauseCode::SpannedWhereClause(..) - | ObligationCauseCode::WhereClause(..) - | ObligationCauseCode::SpannedWhereClauseInExpr(..) + if let ObligationCauseCode::WhereClause(..) | ObligationCauseCode::WhereClauseInExpr(..) = code { self.note_obligation_cause_code( @@ -1612,11 +1610,9 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { let is_normalized_term_expected = !matches!( obligation.cause.code().peel_derives(), - ObligationCauseCode::WhereClause(_) - | ObligationCauseCode::SpannedWhereClause(_, _) - | ObligationCauseCode::WhereClauseInExpr(..) - | ObligationCauseCode::SpannedWhereClauseInExpr(..) - | ObligationCauseCode::Coercion { .. } + |ObligationCauseCode::WhereClause(..)| ObligationCauseCode::WhereClauseInExpr( + .. + ) | ObligationCauseCode::Coercion { .. } ); let (expected, actual) = if is_normalized_term_expected { @@ -2447,7 +2443,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { } } - if let ObligationCauseCode::WhereClause(def_id) + if let ObligationCauseCode::WhereClause(def_id, _) | ObligationCauseCode::WhereClauseInExpr(def_id, ..) = *obligation.cause.code() { self.suggest_fully_qualified_path(&mut err, def_id, span, trait_ref.def_id()); @@ -2883,12 +2879,15 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { else { return; }; - let (ObligationCauseCode::SpannedWhereClause(item_def_id, span) - | ObligationCauseCode::SpannedWhereClauseInExpr(item_def_id, span, ..)) = + let (ObligationCauseCode::WhereClause(item_def_id, span) + | ObligationCauseCode::WhereClauseInExpr(item_def_id, span, ..)) = *obligation.cause.code().peel_derives() else { return; }; + if span.is_dummy() { + return; + } debug!(?pred, ?item_def_id, ?span); let (Some(node), true) = ( @@ -3181,10 +3180,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { ObligationCauseCode::RustCall => { err.primary_message("functions with the \"rust-call\" ABI must take a single non-self tuple argument"); } - ObligationCauseCode::SpannedWhereClause(def_id, _) - | ObligationCauseCode::WhereClause(def_id) - if self.tcx.is_fn_trait(*def_id) => - { + ObligationCauseCode::WhereClause(def_id, _) if self.tcx.is_fn_trait(*def_id) => { err.code(E0059); err.primary_message(format!( "type parameter to bare `{}` trait must be a tuple", diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index 1e78484f30541..f092f42dacf9a 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -573,11 +573,7 @@ pub fn normalize_inherent_projection<'a, 'b, 'tcx>( // cause code, inherent projections will be printed with identity instantiation in // diagnostics which is not ideal. // Consider creating separate cause codes for this specific situation. - if span.is_dummy() { - ObligationCauseCode::WhereClause(alias_ty.def_id) - } else { - ObligationCauseCode::SpannedWhereClause(alias_ty.def_id, span) - }, + ObligationCauseCode::WhereClause(alias_ty.def_id, span), ); obligations.push(Obligation::with_depth( @@ -2130,17 +2126,11 @@ fn assoc_ty_own_obligations<'cx, 'tcx>( | ObligationCauseCode::AscribeUserTypeProvePredicate(..) ) { obligation.cause.clone() - } else if span.is_dummy() { - ObligationCause::new( - obligation.cause.span, - obligation.cause.body_id, - ObligationCauseCode::WhereClause(obligation.predicate.def_id), - ) } else { ObligationCause::new( obligation.cause.span, obligation.cause.body_id, - ObligationCauseCode::SpannedWhereClause(obligation.predicate.def_id, span), + ObligationCauseCode::WhereClause(obligation.predicate.def_id, span), ) }; nested.push(Obligation::with_depth( diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index 2c2b84d4a8753..562a82cc73d65 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -568,11 +568,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { iter::zip(predicates, origins.into_iter().rev()) .map(|((pred, span), origin_def_id)| { - let code = if span.is_dummy() { - ObligationCauseCode::WhereClause(origin_def_id) - } else { - ObligationCauseCode::SpannedWhereClause(origin_def_id, span) - }; + let code = ObligationCauseCode::WhereClause(origin_def_id, span); let cause = self.cause(code); traits::Obligation::with_depth( self.tcx(), diff --git a/tests/ui/higher-ranked/trait-bounds/issue-59311.stderr b/tests/ui/higher-ranked/trait-bounds/issue-59311.stderr index f8bed86ccf599..a26c617dc931d 100644 --- a/tests/ui/higher-ranked/trait-bounds/issue-59311.stderr +++ b/tests/ui/higher-ranked/trait-bounds/issue-59311.stderr @@ -1,19 +1,33 @@ error: implementation of `Trait` is not general enough --> $DIR/issue-59311.rs:17:5 | -LL | v.t(|| {}); - | ^^^^^^^^^^ implementation of `Trait` is not general enough +LL | / pub fn crash(v: &V) +LL | | where +LL | | for<'a> &'a V: Trait + 'static, + | |____________________-----__________- due to a where-clause on `crash`... + | | + | doesn't satisfy where-clause +LL | { +LL | v.t(|| {}); + | ^^^^^^^^^^ | - = note: `Trait` would have to be implemented for the type `&'a V` + = note: ...`Trait` would have to be implemented for the type `&'a V` = note: ...but `Trait` is actually implemented for the type `&'0 V`, for some specific lifetime `'0` error: implementation of `Trait` is not general enough --> $DIR/issue-59311.rs:17:5 | -LL | v.t(|| {}); - | ^^^^^^^^^^ implementation of `Trait` is not general enough +LL | / pub fn crash(v: &V) +LL | | where +LL | | for<'a> &'a V: Trait + 'static, + | |____________________-----__________- due to a where-clause on `crash`... + | | + | doesn't satisfy where-clause +LL | { +LL | v.t(|| {}); + | ^^^^^^^^^^ | - = note: `Trait` would have to be implemented for the type `&'a V` + = note: ...`Trait` would have to be implemented for the type `&'a V` = note: ...but `Trait` is actually implemented for the type `&'0 V`, for some specific lifetime `'0` = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` diff --git a/tests/ui/higher-ranked/trait-bounds/trivial-does-not-hold.rs b/tests/ui/higher-ranked/trait-bounds/trivial-does-not-hold.rs new file mode 100644 index 0000000000000..fa76686cc8b61 --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/trivial-does-not-hold.rs @@ -0,0 +1,11 @@ +// Minimized test from #59311. + +pub fn crash() +where + for<'a> &'a (): 'static, +{ + || {}; + //~^ ERROR higher-ranked lifetime error +} + +fn main() {} diff --git a/tests/ui/higher-ranked/trait-bounds/trivial-does-not-hold.stderr b/tests/ui/higher-ranked/trait-bounds/trivial-does-not-hold.stderr new file mode 100644 index 0000000000000..9e0d7e4b7be09 --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/trivial-does-not-hold.stderr @@ -0,0 +1,10 @@ +error: higher-ranked lifetime error + --> $DIR/trivial-does-not-hold.rs:7:5 + | +LL | || {}; + | ^^^^^ + | + = note: could not prove `for<'a> &'a (): 'b` + +error: aborting due to 1 previous error + From d97ed2d349a2a1c993343b70d8d28cb9abfb0f2e Mon Sep 17 00:00:00 2001 From: klensy Date: Sat, 11 May 2024 13:09:21 +0300 Subject: [PATCH 048/179] fix few typo in filecheck annotations --- tests/codegen/option-niche-eq.rs | 12 ++++++------ tests/codegen/sanitizer/no-sanitize-inlining.rs | 2 +- tests/codegen/simd/issue-120720-reduce-nan.rs | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/codegen/option-niche-eq.rs b/tests/codegen/option-niche-eq.rs index 7b955332fd3b5..25ea5dd595c31 100644 --- a/tests/codegen/option-niche-eq.rs +++ b/tests/codegen/option-niche-eq.rs @@ -7,7 +7,7 @@ use core::cmp::Ordering; use core::ptr::NonNull; use core::num::NonZero; -// CHECK-lABEL: @non_zero_eq +// CHECK-LABEL: @non_zero_eq #[no_mangle] pub fn non_zero_eq(l: Option>, r: Option>) -> bool { // CHECK: start: @@ -16,7 +16,7 @@ pub fn non_zero_eq(l: Option>, r: Option>) -> bool { l == r } -// CHECK-lABEL: @non_zero_signed_eq +// CHECK-LABEL: @non_zero_signed_eq #[no_mangle] pub fn non_zero_signed_eq(l: Option>, r: Option>) -> bool { // CHECK: start: @@ -25,7 +25,7 @@ pub fn non_zero_signed_eq(l: Option>, r: Option>) -> b l == r } -// CHECK-lABEL: @non_null_eq +// CHECK-LABEL: @non_null_eq #[no_mangle] pub fn non_null_eq(l: Option>, r: Option>) -> bool { // CHECK: start: @@ -34,7 +34,7 @@ pub fn non_null_eq(l: Option>, r: Option>) -> bool { l == r } -// CHECK-lABEL: @ordering_eq +// CHECK-LABEL: @ordering_eq #[no_mangle] pub fn ordering_eq(l: Option, r: Option) -> bool { // CHECK: start: @@ -54,7 +54,7 @@ pub enum EnumWithNiche { G, } -// CHECK-lABEL: @niche_eq +// CHECK-LABEL: @niche_eq #[no_mangle] pub fn niche_eq(l: Option, r: Option) -> bool { // CHECK: start: @@ -64,7 +64,7 @@ pub fn niche_eq(l: Option, r: Option) -> bool { } // FIXME: This should work too -// // FIXME-CHECK-lABEL: @bool_eq +// // FIXME-CHECK-LABEL: @bool_eq // #[no_mangle] // pub fn bool_eq(l: Option, r: Option) -> bool { // // FIXME-CHECK: start: diff --git a/tests/codegen/sanitizer/no-sanitize-inlining.rs b/tests/codegen/sanitizer/no-sanitize-inlining.rs index 623bfa608ca39..d5e47884f8584 100644 --- a/tests/codegen/sanitizer/no-sanitize-inlining.rs +++ b/tests/codegen/sanitizer/no-sanitize-inlining.rs @@ -16,7 +16,7 @@ // ASAN: } // // LSAN-LABEL: define void @test -// LSAN-NO: call +// LSAN-NOT: call // LSAN: } #[no_mangle] pub fn test(n: &mut u32) { diff --git a/tests/codegen/simd/issue-120720-reduce-nan.rs b/tests/codegen/simd/issue-120720-reduce-nan.rs index 2c6098c04891f..0372582bf7f38 100644 --- a/tests/codegen/simd/issue-120720-reduce-nan.rs +++ b/tests/codegen/simd/issue-120720-reduce-nan.rs @@ -8,7 +8,7 @@ #![feature(stdarch_x86_avx512, avx512_target_feature)] use std::arch::x86_64::*; -// CHECK-label: @demo( +// CHECK-LABEL: @demo( #[no_mangle] #[target_feature(enable = "avx512f")] // Function-level target feature mismatches inhibit inlining pub unsafe fn demo() -> bool { From 8167a353195322dad135a22a81a9fccf73878d6a Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 10 May 2024 10:59:47 +0200 Subject: [PATCH 049/179] Migrate `run-make/rustdoc-shared-flags` to rmake --- .../tidy/src/allowed_run_make_makefiles.txt | 1 - tests/run-make/rustdoc-shared-flags/Makefile | 18 ------------------ tests/run-make/rustdoc-shared-flags/rmake.rs | 14 ++++++++++++++ 3 files changed, 14 insertions(+), 19 deletions(-) delete mode 100644 tests/run-make/rustdoc-shared-flags/Makefile create mode 100644 tests/run-make/rustdoc-shared-flags/rmake.rs diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index e87950b36d9df..74592424337ad 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -252,7 +252,6 @@ run-make/rustdoc-scrape-examples-ordering/Makefile run-make/rustdoc-scrape-examples-remap/Makefile run-make/rustdoc-scrape-examples-test/Makefile run-make/rustdoc-scrape-examples-whitespace/Makefile -run-make/rustdoc-shared-flags/Makefile run-make/rustdoc-target-spec-json-path/Makefile run-make/rustdoc-themes/Makefile run-make/rustdoc-verify-output-files/Makefile diff --git a/tests/run-make/rustdoc-shared-flags/Makefile b/tests/run-make/rustdoc-shared-flags/Makefile deleted file mode 100644 index a2a7d7b3634a9..0000000000000 --- a/tests/run-make/rustdoc-shared-flags/Makefile +++ /dev/null @@ -1,18 +0,0 @@ -include ../tools.mk - -all: z_help c_help list_passes - -c_help: - $(RUSTC) -C help > $(TMPDIR)/rustc.c_help.txt - $(RUSTDOC) -C help > $(TMPDIR)/rustdoc.c_help.txt - $(DIFF) $(TMPDIR)/rustc.c_help.txt $(TMPDIR)/rustdoc.c_help.txt - -z_help: - $(RUSTC) -Z help > $(TMPDIR)/rustc.z_help.txt - $(RUSTDOC) -Z help > $(TMPDIR)/rustdoc.z_help.txt - $(DIFF) $(TMPDIR)/rustc.z_help.txt $(TMPDIR)/rustdoc.z_help.txt - -list_passes: - $(RUSTC) -C passes=list > $(TMPDIR)/rustc.passes.txt - $(RUSTDOC) -C passes=list > $(TMPDIR)/rustdoc.passes.txt - $(DIFF) $(TMPDIR)/rustc.passes.txt $(TMPDIR)/rustdoc.passes.txt diff --git a/tests/run-make/rustdoc-shared-flags/rmake.rs b/tests/run-make/rustdoc-shared-flags/rmake.rs new file mode 100644 index 0000000000000..2db613f781764 --- /dev/null +++ b/tests/run-make/rustdoc-shared-flags/rmake.rs @@ -0,0 +1,14 @@ +use run_make_support::{rustc, rustdoc, Diff}; + +fn compare_outputs(args: &[&str]) { + let rustc_output = String::from_utf8(rustc().args(args).command_output().stdout).unwrap(); + let rustdoc_output = String::from_utf8(rustdoc().args(args).command_output().stdout).unwrap(); + + Diff::new().expected_text("rustc", rustc_output).actual_text("rustdoc", rustdoc_output).run(); +} + +fn main() { + compare_outputs(&["-C", "help"]); + compare_outputs(&["-Z", "help"]); + compare_outputs(&["-C", "passes=list"]); +} From ebf574fb97e8a771972ba5866bf395ecce3d14be Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Sat, 11 May 2024 12:57:29 +0200 Subject: [PATCH 050/179] Add test for #122775 --- ...tic-lifetime-through-closure-issue-122775.rs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 tests/ui/type-alias-impl-trait/static-lifetime-through-closure-issue-122775.rs diff --git a/tests/ui/type-alias-impl-trait/static-lifetime-through-closure-issue-122775.rs b/tests/ui/type-alias-impl-trait/static-lifetime-through-closure-issue-122775.rs new file mode 100644 index 0000000000000..1bb0acf9b754e --- /dev/null +++ b/tests/ui/type-alias-impl-trait/static-lifetime-through-closure-issue-122775.rs @@ -0,0 +1,17 @@ +//@ check-pass + +#![feature(type_alias_impl_trait)] + +fn spawn(future: F) -> impl Sized +where + F: FnOnce() -> T, +{ + future +} + +fn spawn_task(sender: &'static ()) -> impl Sized { + type Tait = impl Sized + 'static; + spawn::(move || sender) +} + +fn main() {} From e89a2cc8957c1e3f3f8ba7190d7c993a15955999 Mon Sep 17 00:00:00 2001 From: Urgau Date: Thu, 9 May 2024 19:58:10 +0200 Subject: [PATCH 051/179] Always hide private fields in aliased type --- src/librustdoc/passes/mod.rs | 5 ++ .../passes/strip_aliased_non_local.rs | 57 +++++++++++++++++++ tests/rustdoc-ui/issues/issue-91713.stdout | 2 + tests/rustdoc/private-non-local-fields-2.rs | 11 ++++ tests/rustdoc/private-non-local-fields.rs | 9 +++ 5 files changed, 84 insertions(+) create mode 100644 src/librustdoc/passes/strip_aliased_non_local.rs create mode 100644 tests/rustdoc/private-non-local-fields-2.rs create mode 100644 tests/rustdoc/private-non-local-fields.rs diff --git a/src/librustdoc/passes/mod.rs b/src/librustdoc/passes/mod.rs index 4eeaaa2bb70a9..3a71dd82db88b 100644 --- a/src/librustdoc/passes/mod.rs +++ b/src/librustdoc/passes/mod.rs @@ -8,6 +8,9 @@ use crate::core::DocContext; mod stripper; pub(crate) use stripper::*; +mod strip_aliased_non_local; +pub(crate) use self::strip_aliased_non_local::STRIP_ALIASED_NON_LOCAL; + mod strip_hidden; pub(crate) use self::strip_hidden::STRIP_HIDDEN; @@ -71,6 +74,7 @@ pub(crate) enum Condition { pub(crate) const PASSES: &[Pass] = &[ CHECK_CUSTOM_CODE_CLASSES, CHECK_DOC_TEST_VISIBILITY, + STRIP_ALIASED_NON_LOCAL, STRIP_HIDDEN, STRIP_PRIVATE, STRIP_PRIV_IMPORTS, @@ -86,6 +90,7 @@ pub(crate) const DEFAULT_PASSES: &[ConditionalPass] = &[ ConditionalPass::always(CHECK_CUSTOM_CODE_CLASSES), ConditionalPass::always(COLLECT_TRAIT_IMPLS), ConditionalPass::always(CHECK_DOC_TEST_VISIBILITY), + ConditionalPass::always(STRIP_ALIASED_NON_LOCAL), ConditionalPass::new(STRIP_HIDDEN, WhenNotDocumentHidden), ConditionalPass::new(STRIP_PRIVATE, WhenNotDocumentPrivate), ConditionalPass::new(STRIP_PRIV_IMPORTS, WhenDocumentPrivate), diff --git a/src/librustdoc/passes/strip_aliased_non_local.rs b/src/librustdoc/passes/strip_aliased_non_local.rs new file mode 100644 index 0000000000000..848cbd5ed99fc --- /dev/null +++ b/src/librustdoc/passes/strip_aliased_non_local.rs @@ -0,0 +1,57 @@ +use rustc_middle::ty::TyCtxt; +use rustc_middle::ty::Visibility; + +use crate::clean; +use crate::clean::Item; +use crate::core::DocContext; +use crate::fold::{strip_item, DocFolder}; +use crate::passes::Pass; + +pub(crate) const STRIP_ALIASED_NON_LOCAL: Pass = Pass { + name: "strip-aliased-non-local", + run: strip_aliased_non_local, + description: "strips all non-local private aliased items from the output", +}; + +fn strip_aliased_non_local(krate: clean::Crate, cx: &mut DocContext<'_>) -> clean::Crate { + let mut stripper = AliasedNonLocalStripper { tcx: cx.tcx }; + stripper.fold_crate(krate) +} + +struct AliasedNonLocalStripper<'tcx> { + tcx: TyCtxt<'tcx>, +} + +impl<'tcx> DocFolder for AliasedNonLocalStripper<'tcx> { + fn fold_item(&mut self, i: Item) -> Option { + Some(match *i.kind { + clean::TypeAliasItem(..) => { + let mut stripper = NonLocalStripper { tcx: self.tcx }; + // don't call `fold_item` as that could strip the type-alias it-self + // which we don't want to strip out + stripper.fold_item_recur(i) + } + _ => self.fold_item_recur(i), + }) + } +} + +struct NonLocalStripper<'tcx> { + tcx: TyCtxt<'tcx>, +} + +impl<'tcx> DocFolder for NonLocalStripper<'tcx> { + fn fold_item(&mut self, i: Item) -> Option { + // If not local, we want to respect the original visibility of + // the field and not the one given by the user for the currrent crate. + // + // FIXME(#125009): Not-local should probably consider same Cargo workspace + if !i.def_id().map_or(true, |did| did.is_local()) { + if i.visibility(self.tcx) != Some(Visibility::Public) || i.is_doc_hidden() { + return Some(strip_item(i)); + } + } + + Some(self.fold_item_recur(i)) + } +} diff --git a/tests/rustdoc-ui/issues/issue-91713.stdout b/tests/rustdoc-ui/issues/issue-91713.stdout index bbea7e5c212ef..cc3c8385d9a8e 100644 --- a/tests/rustdoc-ui/issues/issue-91713.stdout +++ b/tests/rustdoc-ui/issues/issue-91713.stdout @@ -1,6 +1,7 @@ Available passes for running rustdoc: check-custom-code-classes - check for custom code classes without the feature-gate enabled check_doc_test_visibility - run various visibility-related lints on doctests +strip-aliased-non-local - strips all non-local private aliased items from the output strip-hidden - strips all `#[doc(hidden)]` items from the output strip-private - strips all private items from a crate which cannot be seen externally, implies strip-priv-imports strip-priv-imports - strips all private import statements (`use`, `extern crate`) from a crate @@ -14,6 +15,7 @@ Default passes for rustdoc: check-custom-code-classes collect-trait-impls check_doc_test_visibility +strip-aliased-non-local strip-hidden (when not --document-hidden-items) strip-private (when not --document-private-items) strip-priv-imports (when --document-private-items) diff --git a/tests/rustdoc/private-non-local-fields-2.rs b/tests/rustdoc/private-non-local-fields-2.rs new file mode 100644 index 0000000000000..615b957f697e8 --- /dev/null +++ b/tests/rustdoc/private-non-local-fields-2.rs @@ -0,0 +1,11 @@ +//! This test makes sure that with never show the inner fields in the +//! aliased type view of type alias. + +//@ compile-flags: -Z unstable-options --document-private-items + +#![crate_name = "foo"] + +use std::collections::BTreeMap; + +// @has 'foo/type.FooBar.html' '//*[@class="rust item-decl"]/code' 'struct FooBar { /* private fields */ }' +pub type FooBar = BTreeMap; diff --git a/tests/rustdoc/private-non-local-fields.rs b/tests/rustdoc/private-non-local-fields.rs new file mode 100644 index 0000000000000..7922ce074dd1b --- /dev/null +++ b/tests/rustdoc/private-non-local-fields.rs @@ -0,0 +1,9 @@ +//! This test makes sure that with never show the inner fields in the +//! aliased type view of type alias. + +#![crate_name = "foo"] + +use std::collections::BTreeMap; + +// @has 'foo/type.FooBar.html' '//*[@class="rust item-decl"]/code' 'struct FooBar { /* private fields */ }' +pub type FooBar = BTreeMap; From e00f27b7be9084e548f7197325c2f343e8ad27b9 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 11 May 2024 14:23:37 +0200 Subject: [PATCH 052/179] io::Write::write_fmt: panic if the formatter fails when the stream does not fail --- library/alloc/src/fmt.rs | 4 +++- library/std/src/io/mod.rs | 6 +++++- tests/ui/write-fmt-errors.rs | 29 ++++++++++++++++++----------- 3 files changed, 26 insertions(+), 13 deletions(-) diff --git a/library/alloc/src/fmt.rs b/library/alloc/src/fmt.rs index b9918752540f3..34f87bbf9e4e3 100644 --- a/library/alloc/src/fmt.rs +++ b/library/alloc/src/fmt.rs @@ -630,7 +630,9 @@ pub fn format(args: Arguments<'_>) -> string::String { fn format_inner(args: Arguments<'_>) -> string::String { let capacity = args.estimated_capacity(); let mut output = string::String::with_capacity(capacity); - output.write_fmt(args).expect("a formatting trait implementation returned an error"); + output + .write_fmt(args) + .expect("a formatting trait implementation returned an error when the underlying stream did not"); output } diff --git a/library/std/src/io/mod.rs b/library/std/src/io/mod.rs index af055152cbe7f..5c6e7b7bd50f0 100644 --- a/library/std/src/io/mod.rs +++ b/library/std/src/io/mod.rs @@ -1839,7 +1839,11 @@ pub trait Write { if output.error.is_err() { output.error } else { - Err(error::const_io_error!(ErrorKind::Uncategorized, "formatter error")) + // This shouldn't happen: the underlying stream did not error, but somehow + // the formatter still errored? + panic!( + "a formatting trait implementation returned an error when the underlying stream did not" + ); } } } diff --git a/tests/ui/write-fmt-errors.rs b/tests/ui/write-fmt-errors.rs index f194e25b5567c..1dafb9a784b3a 100644 --- a/tests/ui/write-fmt-errors.rs +++ b/tests/ui/write-fmt-errors.rs @@ -1,9 +1,11 @@ //@ run-pass +//@ needs-unwind #![feature(io_error_uncategorized)] use std::fmt; use std::io::{self, Error, Write, sink}; +use std::panic::catch_unwind; struct ErrorDisplay; @@ -15,7 +17,6 @@ impl fmt::Display for ErrorDisplay { struct ErrorWriter; -const FORMAT_ERROR: io::ErrorKind = io::ErrorKind::Uncategorized; const WRITER_ERROR: io::ErrorKind = io::ErrorKind::NotConnected; impl Write for ErrorWriter { @@ -27,22 +28,28 @@ impl Write for ErrorWriter { } fn main() { - // Test that the error from the formatter is propagated. - let res = write!(sink(), "{} {} {}", 1, ErrorDisplay, "bar"); - assert!(res.is_err(), "formatter error did not propagate"); - assert_eq!(res.unwrap_err().kind(), FORMAT_ERROR); - // Test that an underlying error is propagated let res = write!(ErrorWriter, "abc"); assert!(res.is_err(), "writer error did not propagate"); - // Writer error + // Test that the error from the formatter is detected. + let res = catch_unwind(|| write!(sink(), "{} {} {}", 1, ErrorDisplay, "bar")); + let err = res.expect_err("formatter error did not lead to panic").downcast::<&str>().unwrap(); + assert!( + err.contains("formatting trait implementation returned an error"), + "unexpected panic: {}", err + ); + + // Writer error when there's some string before the first `{}` let res = write!(ErrorWriter, "abc {}", ErrorDisplay); assert!(res.is_err(), "writer error did not propagate"); assert_eq!(res.unwrap_err().kind(), WRITER_ERROR); - // Formatter error - let res = write!(ErrorWriter, "{} abc", ErrorDisplay); - assert!(res.is_err(), "formatter error did not propagate"); - assert_eq!(res.unwrap_err().kind(), FORMAT_ERROR); + // Formatter error when the `{}` comes first + let res = catch_unwind(|| write!(ErrorWriter, "{} abc", ErrorDisplay)); + let err = res.expect_err("formatter error did not lead to panic").downcast::<&str>().unwrap(); + assert!( + err.contains("formatting trait implementation returned an error"), + "unexpected panic: {}", err + ); } From 250d0832a1c9497ed101260ee9e20b5bf3e18f60 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sat, 11 May 2024 13:50:16 +0000 Subject: [PATCH 053/179] Rustup to rustc 1.80.0-nightly (6e1d94708 2024-05-10) --- patches/stdlib-lock.toml | 4 ++-- rust-toolchain | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/patches/stdlib-lock.toml b/patches/stdlib-lock.toml index a72fa2c62a96c..c8c7b45bc9a6f 100644 --- a/patches/stdlib-lock.toml +++ b/patches/stdlib-lock.toml @@ -42,9 +42,9 @@ checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" [[package]] name = "cc" -version = "1.0.90" +version = "1.0.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cd6604a82acf3039f1144f54b8eb34e91ffba622051189e71b781822d5ee1f5" +checksum = "099a5357d84c4c61eb35fc8eafa9a79a902c2f76911e5747ced4e032edd8d9b4" [[package]] name = "cfg-if" diff --git a/rust-toolchain b/rust-toolchain index 0bf9e1702c88e..18f88fab9c8da 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2024-05-03" +channel = "nightly-2024-05-11" components = ["rust-src", "rustc-dev", "llvm-tools"] From 8fe6e74047491657239b04e29266422a1fceaacd Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sat, 11 May 2024 14:01:29 +0000 Subject: [PATCH 054/179] Fix rustc tests --- scripts/test_rustc_tests.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/scripts/test_rustc_tests.sh b/scripts/test_rustc_tests.sh index 2176f9d5ff314..689cda21643cb 100755 --- a/scripts/test_rustc_tests.sh +++ b/scripts/test_rustc_tests.sh @@ -122,7 +122,6 @@ rm -r tests/run-make/panic-abort-eh_frame # .eh_frame emitted with panic=abort # bugs in the test suite # ====================== rm tests/ui/process/nofile-limit.rs # TODO some AArch64 linking issue -rm tests/ui/attributes/unix_sigpipe/unix_sigpipe-inherit.rs # TODO some symbol not being found, but works fine when manually invoked rm tests/ui/stdio-is-blocking.rs # really slow with unoptimized libstd @@ -154,7 +153,7 @@ index 9607ff02f96..b7d97caf9a2 100644 let mut cmd = setup_common(); - let target_rpath_dir = env::var_os("TARGET_RPATH_DIR").unwrap(); - cmd.arg(format!("-L{}", target_rpath_dir.to_string_lossy())); - Self { cmd } + Self { cmd, stdin: None } } EOF From f437815d919e4636997b7d0a75e7bd7120406372 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sat, 11 May 2024 14:11:53 +0000 Subject: [PATCH 055/179] Compile for x86_64 on macOS even with an arm64 host We don't support arm64 on macOS yet. --- .github/workflows/abi-cafe.yml | 4 ++++ .github/workflows/main.yml | 8 ++++++++ 2 files changed, 12 insertions(+) diff --git a/.github/workflows/abi-cafe.yml b/.github/workflows/abi-cafe.yml index 36ed44f9feccc..b7063f35a3e80 100644 --- a/.github/workflows/abi-cafe.yml +++ b/.github/workflows/abi-cafe.yml @@ -51,6 +51,10 @@ jobs: if: matrix.env.TARGET_TRIPLE == 'x86_64-pc-windows-gnu' run: rustup set default-host x86_64-pc-windows-gnu + - name: Use x86_64 compiler on macOS + if: matrix.os == 'macos-latest' && matrix.env.TARGET_TRIPLE == 'x86_64-apple-darwin' + run: rustup set default-host x86_64-apple-darwin + - name: Select XCode version if: matrix.os == 'macos-latest' run: sudo xcode-select -s /Applications/Xcode_14.3.1.app diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 4ab50ab74fe8e..1f5a6513f63b1 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -98,6 +98,10 @@ jobs: if: matrix.os == 'windows-latest' && matrix.env.TARGET_TRIPLE == 'x86_64-pc-windows-gnu' run: rustup set default-host x86_64-pc-windows-gnu + - name: Use x86_64 compiler on macOS + if: matrix.os == 'macos-latest' && matrix.env.TARGET_TRIPLE == 'x86_64-apple-darwin' + run: rustup set default-host x86_64-apple-darwin + - name: Install toolchain and emulator if: matrix.apt_deps != null run: | @@ -234,6 +238,10 @@ jobs: if: matrix.os == 'windows-latest' && matrix.env.TARGET_TRIPLE == 'x86_64-pc-windows-gnu' run: rustup set default-host x86_64-pc-windows-gnu + - name: Use x86_64 compiler on macOS + if: matrix.os == 'macos-latest' && matrix.env.TARGET_TRIPLE == 'x86_64-apple-darwin' + run: rustup set default-host x86_64-apple-darwin + - name: Install MinGW toolchain if: matrix.os == 'ubuntu-latest' && matrix.env.TARGET_TRIPLE == 'x86_64-pc-windows-gnu' run: | From e068e004d7a3311a44f676b975c7ce4213eda3b2 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Sat, 4 May 2024 15:46:17 -0400 Subject: [PATCH 056/179] Add windows_i686_gnullvm to the list --- src/tools/tidy/src/deps.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs index 1d24c59b356f2..1b73b67b75575 100644 --- a/src/tools/tidy/src/deps.rs +++ b/src/tools/tidy/src/deps.rs @@ -395,6 +395,7 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[ "windows_aarch64_gnullvm", "windows_aarch64_msvc", "windows_i686_gnu", + "windows_i686_gnullvm", "windows_i686_msvc", "windows_x86_64_gnu", "windows_x86_64_gnullvm", From 3aa16f0d2f0430082c7f2907076bcf8563cff308 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Sat, 11 May 2024 10:24:30 -0400 Subject: [PATCH 057/179] Pin libc back to 0.2.153 --- library/std/Cargo.toml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml index 52729ba1f8456..1720fe84fa7c1 100644 --- a/library/std/Cargo.toml +++ b/library/std/Cargo.toml @@ -31,10 +31,11 @@ miniz_oxide = { version = "0.7.0", optional = true, default-features = false } addr2line = { version = "0.21.0", optional = true, default-features = false } [target.'cfg(not(all(windows, target_env = "msvc")))'.dependencies] -libc = { version = "0.2.153", default-features = false, features = ['rustc-dep-of-std'], public = true } +libc = { version = "=0.2.153", default-features = false, features = ['rustc-dep-of-std'], public = true } +# Pin libc (pending https://github.com/rust-lang/rust/pull/124560) [target.'cfg(all(windows, target_env = "msvc"))'.dependencies] -libc = { version = "0.2.153", default-features = false } +libc = { version = "=0.2.153", default-features = false } [target.'cfg(all(not(target_os = "aix"), not(all(windows, target_env = "msvc", not(target_vendor = "uwp")))))'.dependencies] object = { version = "0.32.0", default-features = false, optional = true, features = ['read_core', 'elf', 'macho', 'pe', 'unaligned', 'archive'] } From 12200c912a33972aea5a715f335f51ab70a949fc Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Sat, 11 May 2024 10:27:17 -0400 Subject: [PATCH 058/179] Update Cargo.lock --- Cargo.lock | 434 +++++++++++++++++++++++++++-------------------------- 1 file changed, 221 insertions(+), 213 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a562bdbafa83a..f49bcf7c865cd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -68,9 +68,9 @@ dependencies = [ [[package]] name = "allocator-api2" -version = "0.2.16" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" +checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" [[package]] name = "ammonia" @@ -141,56 +141,57 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.13" +version = "0.6.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d96bd03f33fe50a863e394ee9718a706f988b9079b20c3784fb726e7678b62fb" +checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b" dependencies = [ "anstyle", "anstyle-parse", "anstyle-query", "anstyle-wincon", "colorchoice", + "is_terminal_polyfill", "utf8parse", ] [[package]] name = "anstyle" -version = "1.0.6" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc" +checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b" [[package]] name = "anstyle-lossy" -version = "1.1.0" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9a0444767dbd4aea9355cb47a370eb184dbfe918875e127eff52cb9d1638181" +checksum = "6fcff6599f06e21b0165c85052ccd6e67dc388ddd1c516a9dc5f55dc8cacf004" dependencies = [ "anstyle", ] [[package]] name = "anstyle-parse" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" +checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" +checksum = "a64c907d4e79225ac72e2a354c9ce84d50ebb4586dee56c82b3ee73004f537f5" dependencies = [ "windows-sys 0.52.0", ] [[package]] name = "anstyle-svg" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b6ddad447b448d6d5db36b31cbd3ff27c7af071619501998eeceab01968287a" +checksum = "bbbf0bf947d663010f0b4132f28ca08da9151f3b9035fa7578a38de521c1d1aa" dependencies = [ "anstream", "anstyle", @@ -201,9 +202,9 @@ dependencies = [ [[package]] name = "anstyle-wincon" -version = "3.0.2" +version = "3.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" +checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19" dependencies = [ "anstyle", "windows-sys 0.52.0", @@ -211,9 +212,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.81" +version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0952808a6c2afd1aa8947271f3a60f1a6763c7b912d210184c5149b5cf147247" +checksum = "25bdb32cbbdce2b519a9cd7df3a678443100e265d5e25ca763b7572a5104f5f3" dependencies = [ "backtrace", ] @@ -256,7 +257,7 @@ dependencies = [ "proc-macro2", "quote", "serde", - "syn 2.0.58", + "syn 2.0.62", ] [[package]] @@ -276,9 +277,9 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.2.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "backtrace" @@ -389,18 +390,15 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.15.4" +version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ff69b9dd49fd426c69a0db9fc04dd934cdb6645ff000864d98f7e2af8830eaa" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" [[package]] name = "bytecount" -version = "0.6.7" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1e5f035d16fc623ae5f74981db80a439803888314e3a555fd6f04acd51a3205" -dependencies = [ - "packed_simd", -] +checksum = "5ce89b21cab1437276d2650d57e971f9d548a2d9037cc231abdc0562b97498ce" [[package]] name = "byteorder" @@ -509,7 +507,7 @@ dependencies = [ "iana-time-zone", "num-traits", "serde", - "windows-targets 0.52.4", + "windows-targets 0.52.5", ] [[package]] @@ -579,9 +577,9 @@ dependencies = [ [[package]] name = "clap_complete" -version = "4.5.1" +version = "4.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "885e4d7d5af40bfb99ae6f9433e292feac98d452dcb3ec3d25dfe7552b77da8c" +checksum = "dd79504325bf38b10165b02e89b4347300f855f273c4cb30c4a3209e6583275e" dependencies = [ "clap", ] @@ -595,7 +593,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.62", ] [[package]] @@ -622,7 +620,7 @@ dependencies = [ "regex", "rustc_tools_util", "serde", - "syn 2.0.58", + "syn 2.0.62", "tempfile", "termize", "tokio", @@ -716,23 +714,23 @@ dependencies = [ [[package]] name = "color-print" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a858372ff14bab9b1b30ea504f2a4bc534582aee3e42ba2d41d2a7baba63d5d" +checksum = "1ee543c60ff3888934877a5671f45494dd27ed4ba25c6670b9a7576b7ed7a8c0" dependencies = [ "color-print-proc-macro", ] [[package]] name = "color-print-proc-macro" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57e37866456a721d0a404439a1adae37a31be4e0055590d053dfe6981e05003f" +checksum = "77ff1a80c5f3cb1ca7c06ffdd71b6a6dd6d8f896c42141fbd43f50ed28dcdb93" dependencies = [ "nom", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.62", ] [[package]] @@ -749,9 +747,9 @@ dependencies = [ [[package]] name = "colorchoice" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" +checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422" [[package]] name = "colored" @@ -978,7 +976,7 @@ dependencies = [ "proc-macro2", "quote", "strsim 0.10.0", - "syn 2.0.58", + "syn 2.0.62", ] [[package]] @@ -989,7 +987,7 @@ checksum = "a668eda54683121533a393014d8692171709ff57a7d61f187b6e782719f8933f" dependencies = [ "darling_core", "quote", - "syn 2.0.58", + "syn 2.0.62", ] [[package]] @@ -1004,7 +1002,7 @@ version = "0.1.80" dependencies = [ "itertools 0.12.1", "quote", - "syn 2.0.58", + "syn 2.0.62", ] [[package]] @@ -1045,7 +1043,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.62", ] [[package]] @@ -1055,7 +1053,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "206868b8242f27cecce124c19fd88157fbd0dd334df2587f36417bafbc85097b" dependencies = [ "derive_builder_core", - "syn 2.0.58", + "syn 2.0.62", ] [[package]] @@ -1078,7 +1076,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.62", ] [[package]] @@ -1167,14 +1165,14 @@ checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.62", ] [[package]] name = "dissimilar" -version = "1.0.7" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86e3bdc80eee6e16b2b6b0f87fbc98c04bee3455e35174c0de1a125d0688c632" +checksum = "59f8e79d1fbf76bdfbde321e902714bf6c49df88a7dda6fc682fc2979226962d" [[package]] name = "dlmalloc" @@ -1191,9 +1189,9 @@ dependencies = [ [[package]] name = "either" -version = "1.10.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a" +checksum = "a47c1c47d2f5964e29c61246e81db715514cd532db6b5116a25ea3c03d6780a2" [[package]] name = "elasticlunr-rs" @@ -1233,9 +1231,9 @@ checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" [[package]] name = "encoding_rs" -version = "0.8.33" +version = "0.8.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" +checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59" dependencies = [ "cfg-if", ] @@ -1271,9 +1269,9 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" +checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" dependencies = [ "libc", "windows-sys 0.52.0", @@ -1314,9 +1312,9 @@ checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649" [[package]] name = "fastrand" -version = "2.0.2" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "658bd65b1cf4c852a3cc96f18a8ce7b5640f6b703f905c7d74532294c2a63984" +checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" [[package]] name = "field-offset" @@ -1336,15 +1334,15 @@ checksum = "1ee447700ac8aa0b2f2bd7bc4462ad686ba06baa6727ac149a2d6277f0d240fd" dependencies = [ "cfg-if", "libc", - "redox_syscall", + "redox_syscall 0.4.1", "windows-sys 0.52.0", ] [[package]] name = "flate2" -version = "1.0.28" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e" +checksum = "5f54427cfd1c7829e2a139fcefea601bf088ebca651d2bf53ebc600eac295dae" dependencies = [ "crc32fast", "miniz_oxide", @@ -1352,9 +1350,9 @@ dependencies = [ [[package]] name = "fluent-bundle" -version = "0.15.2" +version = "0.15.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e242c601dec9711505f6d5bbff5bedd4b61b2469f2e8bb8e57ee7c9747a87ffd" +checksum = "7fe0a21ee80050c678013f82edf4b705fe2f26f1f9877593d13198612503f493" dependencies = [ "fluent-langneg", "fluent-syntax", @@ -1377,9 +1375,9 @@ dependencies = [ [[package]] name = "fluent-syntax" -version = "0.11.0" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0abed97648395c902868fee9026de96483933faa54ea3b40d652f7dfe61ca78" +checksum = "2a530c4694a6a8d528794ee9bbd8ba0122e779629ac908d15ad5a7ae7763a33d" dependencies = [ "thiserror", ] @@ -1505,7 +1503,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.62", ] [[package]] @@ -1577,9 +1575,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.13" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a06fddc2749e0528d2813f95e050e87e52c8cbbae56223b9babf73b3e53b0cc6" +checksum = "94b22e06ecb0110981051723910cbf0b5f5e09a2062dd7663334ee79a9d1286c" dependencies = [ "cfg-if", "libc", @@ -1663,9 +1661,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.14.3" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" dependencies = [ "ahash", "allocator-api2", @@ -1943,7 +1941,7 @@ checksum = "d2abdd3a62551e8337af119c5899e600ca0c88ec8f23a46c60ba216c803dcf1a" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.62", ] [[package]] @@ -2055,9 +2053,9 @@ dependencies = [ [[package]] name = "intl-memoizer" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c310433e4a310918d6ed9243542a6b83ec1183df95dff8f23f87bb88a264a66f" +checksum = "fe22e020fce238ae18a6d5d8c502ee76a52a6e880d99477657e6acc30ec57bda" dependencies = [ "type-map", "unic-langid", @@ -2078,6 +2076,12 @@ version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" +[[package]] +name = "is_terminal_polyfill" +version = "1.70.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800" + [[package]] name = "itertools" version = "0.11.0" @@ -2114,9 +2118,9 @@ dependencies = [ [[package]] name = "jobserver" -version = "0.1.28" +version = "0.1.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab46a6e9526ddef3ae7f787c06f0f2600639ba80ea3eade3d8e670a2230f51d6" +checksum = "d2b099aaa34a9751c5bf0878add70444e1ed2dd73f347be99003d4577277de6e" dependencies = [ "libc", ] @@ -2219,7 +2223,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c2a198fb6b0eada2a8df47933734e6d35d350665a33a3593d7164fa52c75c19" dependencies = [ "cfg-if", - "windows-targets 0.52.4", + "windows-targets 0.52.5", ] [[package]] @@ -2296,9 +2300,9 @@ dependencies = [ [[package]] name = "lock_api" -version = "0.4.11" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" dependencies = [ "autocfg", "scopeguard", @@ -2384,7 +2388,7 @@ dependencies = [ "memchr", "once_cell", "opener", - "pulldown-cmark 0.10.2", + "pulldown-cmark 0.10.3", "regex", "serde", "serde_json", @@ -2615,12 +2619,11 @@ checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" [[package]] name = "num-traits" -version = "0.2.18" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", - "libm", ] [[package]] @@ -2717,7 +2720,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.62", ] [[package]] @@ -2782,16 +2785,6 @@ version = "3.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f" -[[package]] -name = "packed_simd" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f9f08af0c877571712e2e3e686ad79efad9657dbf0f7c3c8ba943ff6c38932d" -dependencies = [ - "cfg-if", - "num-traits", -] - [[package]] name = "pad" version = "0.1.6" @@ -2837,9 +2830,9 @@ dependencies = [ [[package]] name = "parking_lot" -version = "0.12.1" +version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +checksum = "7e4af0ca4f6caed20e900d564c242b8e5d4903fdacf31d3daf527b66fe6f42fb" dependencies = [ "lock_api", "parking_lot_core", @@ -2847,15 +2840,15 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.9" +version = "0.9.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" dependencies = [ "cfg-if", "libc", - "redox_syscall", + "redox_syscall 0.5.1", "smallvec", - "windows-targets 0.48.5", + "windows-targets 0.52.5", ] [[package]] @@ -2890,9 +2883,9 @@ dependencies = [ [[package]] name = "pest" -version = "2.7.9" +version = "2.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "311fb059dee1a7b802f036316d790138c613a4e8b180c822e3925a662e9f0c95" +checksum = "560131c633294438da9f7c4b08189194b20946c8274c6b9e38881a7874dc8ee8" dependencies = [ "memchr", "thiserror", @@ -2901,9 +2894,9 @@ dependencies = [ [[package]] name = "pest_derive" -version = "2.7.9" +version = "2.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f73541b156d32197eecda1a4014d7f868fd2bcb3c550d5386087cfba442bf69c" +checksum = "26293c9193fbca7b1a3bf9b79dc1e388e927e6cacaa78b4a3ab705a1d3d41459" dependencies = [ "pest", "pest_generator", @@ -2911,22 +2904,22 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.7.9" +version = "2.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c35eeed0a3fab112f75165fdc026b3913f4183133f19b49be773ac9ea966e8bd" +checksum = "3ec22af7d3fb470a85dd2ca96b7c577a1eb4ef6f1683a9fe9a8c16e136c04687" dependencies = [ "pest", "pest_meta", "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.62", ] [[package]] name = "pest_meta" -version = "2.7.9" +version = "2.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2adbf29bb9776f28caece835398781ab24435585fe0d4dc1374a61db5accedca" +checksum = "d7a240022f37c361ec1878d646fc5b7d7c4d28d5946e1a80ad5a7a4f4ca0bdcd" dependencies = [ "once_cell", "pest", @@ -3080,9 +3073,9 @@ checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" [[package]] name = "proc-macro2" -version = "1.0.79" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] @@ -3126,9 +3119,9 @@ dependencies = [ [[package]] name = "pulldown-cmark" -version = "0.10.2" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f0530d13d87d1f549b66a3e8d0c688952abe5994e204ed62615baaf25dc029c" +checksum = "76979bea66e7875e7509c4ec5300112b316af87fa7a252ca91c448b32dfe3993" dependencies = [ "bitflags 2.5.0", "memchr", @@ -3138,9 +3131,9 @@ dependencies = [ [[package]] name = "pulldown-cmark-escape" -version = "0.10.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5d8f9aa0e3cbcfaf8bf00300004ee3b72f74770f9cbac93f6928771f613276b" +checksum = "bd348ff538bc9caeda7ee8cad2d1d48236a1f443c1fa3913c6a02fe0043b1dd3" [[package]] name = "punycode" @@ -3156,9 +3149,9 @@ checksum = "07589615d719a60c8dd8a4622e7946465dfef20d1a428f969e3443e7386d5f45" [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -3261,6 +3254,15 @@ dependencies = [ "bitflags 1.3.2", ] +[[package]] +name = "redox_syscall" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "469052894dcb553421e483e4209ee581a45100d31b4018de03e5a7ad86374a7e" +dependencies = [ + "bitflags 2.5.0", +] + [[package]] name = "redox_users" version = "0.4.5" @@ -3436,9 +3438,9 @@ dependencies = [ [[package]] name = "rustc-demangle" -version = "0.1.23" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" dependencies = [ "compiler_builtins", "rustc-std-workspace-core", @@ -3999,7 +4001,7 @@ dependencies = [ "fluent-syntax", "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.62", "unic-langid", ] @@ -4133,7 +4135,7 @@ version = "0.0.0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.62", "synstructure", ] @@ -4280,7 +4282,7 @@ version = "0.0.0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.62", "synstructure", ] @@ -4932,7 +4934,7 @@ dependencies = [ "proc-macro2", "quote", "serde", - "syn 2.0.58", + "syn 2.0.62", ] [[package]] @@ -4967,9 +4969,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.32" +version = "0.38.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65e04861e65f21776e67888bfbea442b3642beaa0138fdb1dd7a84a52dffdb89" +checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" dependencies = [ "bitflags 2.5.0", "errno", @@ -4989,9 +4991,9 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.15" +version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80af6f9131f277a45a3fba6ce8e2258037bb0477a67e610d3c1fe046ab31de47" +checksum = "092474d1a01ea8278f69e6a358998405fae5b8b963ddaeb2b0b04a128bf1dfb0" [[package]] name = "ruzstd" @@ -5017,9 +5019,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.17" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" [[package]] name = "same-file" @@ -5053,11 +5055,11 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "security-framework" -version = "2.10.0" +version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "770452e37cad93e0a50d5abc3990d2bc351c36d0328f86cefec2f2fb206eaef6" +checksum = "c627723fd09706bacdb5cf41499e95098555af3c3c29d014dc3c458ef6be11c0" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.5.0", "core-foundation", "core-foundation-sys", "libc", @@ -5066,9 +5068,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.10.0" +version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41f3cc463c0ef97e11c3461a9d3787412d30e8e7eb907c79180c4a57bf7c04ef" +checksum = "317936bbbd05227752583946b9e66d7ce3b489f84e11a94a510b4437fef407d7" dependencies = [ "core-foundation-sys", "libc", @@ -5080,49 +5082,49 @@ version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e14e4d63b804dc0c7ec4a1e52bcb63f02c7ac94476755aa579edac21e01f915d" dependencies = [ - "self_cell 1.0.3", + "self_cell 1.0.4", ] [[package]] name = "self_cell" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58bf37232d3bb9a2c4e641ca2a11d83b5062066f88df7fed36c28772046d65ba" +checksum = "d369a96f978623eb3dc28807c4852d6cc617fed53da5d3c400feff1ef34a714a" [[package]] name = "semver" -version = "1.0.22" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca" +checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" dependencies = [ "serde", ] [[package]] name = "serde" -version = "1.0.197" +version = "1.0.201" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" +checksum = "780f1cebed1629e4753a1a38a3c72d30b97ec044f0aef68cb26650a3c5cf363c" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.197" +version = "1.0.201" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" +checksum = "c5e405930b9796f1c00bee880d03fc7e0bb4b9a11afc776885ffe84320da2865" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.62", ] [[package]] name = "serde_json" -version = "1.0.115" +version = "1.0.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12dc5c46daa8e9fdf4f5e71b6cf9a53f2487da0e86e55808e2d35539666497dd" +checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3" dependencies = [ "indexmap", "itoa", @@ -5229,9 +5231,9 @@ checksum = "1b6b67fb9a61334225b5b790716f609cd58395f895b3fe8b328786812a40bc3b" [[package]] name = "socket2" -version = "0.5.6" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05ffd9c0a93b7543e062e759284fcf5f5e3b098501104bfbdde4d404db792871" +checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" dependencies = [ "libc", "windows-sys 0.52.0", @@ -5427,9 +5429,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.58" +version = "2.0.62" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44cfb93f38070beee36b3fef7d4f5a16f27751d94b187b666a5cc5e9b0d30687" +checksum = "9f660c3bfcefb88c538776b6685a0c472e3128b51e74d48793dc2a488196e8eb" dependencies = [ "proc-macro2", "quote", @@ -5450,14 +5452,14 @@ checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.62", ] [[package]] name = "sysinfo" -version = "0.30.8" +version = "0.30.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b1a378e48fb3ce3a5cf04359c456c9c98ff689bcf1c1bc6e6a31f247686f275" +checksum = "732ffa00f53e6b2af46208fba5718d9662a421049204e156328b66791ffa15ae" dependencies = [ "cfg-if", "core-foundation-sys", @@ -5601,22 +5603,22 @@ checksum = "a38c90d48152c236a3ab59271da4f4ae63d678c5d7ad6b7714d7cb9760be5e4b" [[package]] name = "thiserror" -version = "1.0.58" +version = "1.0.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03468839009160513471e86a034bb2c5c0e4baae3b43f79ffc55c4a5427b3297" +checksum = "579e9083ca58dd9dcf91a9923bb9054071b9ebbd800b342194c9feb0ee89fc18" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.58" +version = "1.0.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7" +checksum = "e2470041c06ec3ac1ab38d0356a6119054dedaea53e12fbefc0de730a1c08524" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.62", ] [[package]] @@ -5751,16 +5753,15 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.10" +version = "0.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" +checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1" dependencies = [ "bytes", "futures-core", "futures-sink", "pin-project-lite", "tokio", - "tracing", ] [[package]] @@ -5838,7 +5839,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.62", ] [[package]] @@ -5922,9 +5923,9 @@ dependencies = [ [[package]] name = "type-map" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6d3364c5e96cb2ad1603037ab253ddd34d7fb72a58bdddf4b7350760fc69a46" +checksum = "deb68604048ff8fa93347f02441e4487594adc20bb8a084f9e564d2b827a0a9f" dependencies = [ "rustc-hash", ] @@ -6007,9 +6008,9 @@ dependencies = [ [[package]] name = "unic-langid" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "238722e6d794ed130f91f4ea33e01fcff4f188d92337a21297892521c72df516" +checksum = "23dd9d1e72a73b25e07123a80776aae3e7b0ec461ef94f9151eed6ec88005a44" dependencies = [ "unic-langid-impl", "unic-langid-macros", @@ -6017,18 +6018,18 @@ dependencies = [ [[package]] name = "unic-langid-impl" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bd55a2063fdea4ef1f8633243a7b0524cbeef1905ae04c31a1c9b9775c55bc6" +checksum = "0a5422c1f65949306c99240b81de9f3f15929f5a8bfe05bb44b034cc8bf593e5" dependencies = [ "tinystr", ] [[package]] name = "unic-langid-macros" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c854cefb82ff2816410ce606acbad1b3af065140907b29be9229040752b83ec" +checksum = "0da1cd2c042d3c7569a1008806b02039e7a4a2bdf8f8e96bd3c792434a0e275e" dependencies = [ "proc-macro-hack", "tinystr", @@ -6038,13 +6039,13 @@ dependencies = [ [[package]] name = "unic-langid-macros-impl" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fea2a4c80deb4fb3ca51f66b5e2dd91e3642bbce52234bcf22e41668281208e4" +checksum = "1ed7f4237ba393424195053097c1516bd4590dc82b84f2f97c5c69e12704555b" dependencies = [ "proc-macro-hack", "quote", - "syn 2.0.58", + "syn 2.0.62", "unic-langid-impl", ] @@ -6115,9 +6116,9 @@ checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" [[package]] name = "unicode-width" -version = "0.1.11" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" +checksum = "68f5e5f3158ecfd4b8ff6fe086db7c8467a2dfdac97fe420f2b7c4aa97af66d6" dependencies = [ "compiler_builtins", "rustc-std-workspace-core", @@ -6276,7 +6277,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.62", "wasm-bindgen-shared", ] @@ -6310,7 +6311,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.62", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -6368,11 +6369,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.6" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" +checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b" dependencies = [ - "winapi", + "windows-sys 0.52.0", ] [[package]] @@ -6388,7 +6389,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e48a53791691ab099e5e2ad123536d0fff50652600abaf43bbf952894110d0be" dependencies = [ "windows-core", - "windows-targets 0.52.4", + "windows-targets 0.52.5", ] [[package]] @@ -6401,7 +6402,7 @@ dependencies = [ "rayon", "serde", "serde_json", - "syn 2.0.58", + "syn 2.0.62", "windows-metadata", ] @@ -6411,7 +6412,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" dependencies = [ - "windows-targets 0.52.4", + "windows-targets 0.52.5", ] [[package]] @@ -6435,7 +6436,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.4", + "windows-targets 0.52.5", ] [[package]] @@ -6455,17 +6456,18 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b" +checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" dependencies = [ - "windows_aarch64_gnullvm 0.52.4", - "windows_aarch64_msvc 0.52.4", - "windows_i686_gnu 0.52.4", - "windows_i686_msvc 0.52.4", - "windows_x86_64_gnu 0.52.4", - "windows_x86_64_gnullvm 0.52.4", - "windows_x86_64_msvc 0.52.4", + "windows_aarch64_gnullvm 0.52.5", + "windows_aarch64_msvc 0.52.5", + "windows_i686_gnu 0.52.5", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.5", + "windows_x86_64_gnu 0.52.5", + "windows_x86_64_gnullvm 0.52.5", + "windows_x86_64_msvc 0.52.5", ] [[package]] @@ -6476,9 +6478,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9" +checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" [[package]] name = "windows_aarch64_msvc" @@ -6488,9 +6490,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_aarch64_msvc" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675" +checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" [[package]] name = "windows_i686_gnu" @@ -6500,9 +6502,15 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_gnu" -version = "0.52.4" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3" +checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" [[package]] name = "windows_i686_msvc" @@ -6512,9 +6520,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_i686_msvc" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02" +checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" [[package]] name = "windows_x86_64_gnu" @@ -6524,9 +6532,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnu" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03" +checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" [[package]] name = "windows_x86_64_gnullvm" @@ -6536,9 +6544,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177" +checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" [[package]] name = "windows_x86_64_msvc" @@ -6548,9 +6556,9 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "windows_x86_64_msvc" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8" +checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" [[package]] name = "winnow" @@ -6626,28 +6634,28 @@ checksum = "9e6936f0cce458098a201c245a11bef556c6a0181129c7034d10d76d1ec3a2b8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.62", "synstructure", ] [[package]] name = "zerocopy" -version = "0.7.32" +version = "0.7.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" +checksum = "ae87e3fcd617500e5d106f0380cf7b77f3c6092aae37191433159dda23cfb087" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.7.32" +version = "0.7.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" +checksum = "15e934569e47891f7d9411f1a451d947a60e000ab3bd24fbb970f000387d1b3b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.62", ] [[package]] @@ -6667,7 +6675,7 @@ checksum = "e6a647510471d372f2e6c2e6b7219e44d8c574d24fdc11c610a61455782f18c3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.62", "synstructure", ] @@ -6690,7 +6698,7 @@ checksum = "7b4e5997cbf58990550ef1f0e5124a05e47e1ebd33a84af25739be6031a62c20" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.62", ] [[package]] From 8cf40c46b20d5b3e2f9ce3d4c82fcbcf5c4dec40 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sat, 11 May 2024 16:36:12 +0000 Subject: [PATCH 059/179] Don't attempt to polymorphize statics Fixes rust-lang/rust#124319 --- src/constant.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/constant.rs b/src/constant.rs index cdf499a22f8dd..64e83e43d3272 100644 --- a/src/constant.rs +++ b/src/constant.rs @@ -258,7 +258,7 @@ fn data_id_for_static( ) -> DataId { let attrs = tcx.codegen_fn_attrs(def_id); - let instance = Instance::mono(tcx, def_id).polymorphize(tcx); + let instance = Instance::mono(tcx, def_id); let symbol_name = tcx.symbol_name(instance).name; if let Some(import_linkage) = attrs.import_linkage { From 906db0229f8ffadccbb736977113bdc17b9e49f0 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sat, 11 May 2024 17:03:34 +0000 Subject: [PATCH 060/179] Avoid CValue::const_val for discriminants --- src/discriminant.rs | 45 +++++++++++++++++++++++++++------------------ 1 file changed, 27 insertions(+), 18 deletions(-) diff --git a/src/discriminant.rs b/src/discriminant.rs index 670384663e83f..e7ac084558a5a 100644 --- a/src/discriminant.rs +++ b/src/discriminant.rs @@ -28,16 +28,20 @@ pub(crate) fn codegen_set_discriminant<'tcx>( } => { let ptr = place.place_field(fx, FieldIdx::new(tag_field)); let to = layout.ty.discriminant_for_variant(fx.tcx, variant_index).unwrap().val; - let to = if ptr.layout().abi.is_signed() { - ty::ScalarInt::try_from_int( - ptr.layout().size.sign_extend(to) as i128, - ptr.layout().size, - ) - .unwrap() - } else { - ty::ScalarInt::try_from_uint(to, ptr.layout().size).unwrap() + let to = match ptr.layout().ty.kind() { + ty::Uint(UintTy::U128) | ty::Int(IntTy::I128) => { + let lsb = fx.bcx.ins().iconst(types::I64, to as u64 as i64); + let msb = fx.bcx.ins().iconst(types::I64, (to >> 64) as u64 as i64); + fx.bcx.ins().iconcat(lsb, msb) + } + ty::Uint(_) | ty::Int(_) => { + let clif_ty = fx.clif_type(ptr.layout().ty).unwrap(); + let raw_val = ptr.layout().size.truncate(to); + fx.bcx.ins().iconst(clif_ty, raw_val as i64) + } + _ => unreachable!(), }; - let discr = CValue::const_val(fx, ptr.layout(), to); + let discr = CValue::by_val(to, ptr.layout()); ptr.write_cvalue(fx, discr); } Variants::Multiple { @@ -85,16 +89,21 @@ pub(crate) fn codegen_get_discriminant<'tcx>( .ty .discriminant_for_variant(fx.tcx, *index) .map_or(u128::from(index.as_u32()), |discr| discr.val); - let discr_val = if dest_layout.abi.is_signed() { - ty::ScalarInt::try_from_int( - dest_layout.size.sign_extend(discr_val) as i128, - dest_layout.size, - ) - .unwrap() - } else { - ty::ScalarInt::try_from_uint(discr_val, dest_layout.size).unwrap() + + let val = match dest_layout.ty.kind() { + ty::Uint(UintTy::U128) | ty::Int(IntTy::I128) => { + let lsb = fx.bcx.ins().iconst(types::I64, discr_val as u64 as i64); + let msb = fx.bcx.ins().iconst(types::I64, (discr_val >> 64) as u64 as i64); + fx.bcx.ins().iconcat(lsb, msb) + } + ty::Uint(_) | ty::Int(_) => { + let clif_ty = fx.clif_type(dest_layout.ty).unwrap(); + let raw_val = dest_layout.size.truncate(discr_val); + fx.bcx.ins().iconst(clif_ty, raw_val as i64) + } + _ => unreachable!(), }; - let res = CValue::const_val(fx, dest_layout, discr_val); + let res = CValue::by_val(val, dest_layout); dest.write_cvalue(fx, res); return; } From 9e4e8054882de9e0f9496e415eecd5205a52f0e7 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sat, 11 May 2024 17:06:43 +0000 Subject: [PATCH 061/179] Avoid ICE on transmuting invalid bools Fixes rust-lang/rustc_codegen_cranelift#1433 --- src/value_and_place.rs | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/value_and_place.rs b/src/value_and_place.rs index a11abd0c0e978..b6d6d211e658c 100644 --- a/src/value_and_place.rs +++ b/src/value_and_place.rs @@ -317,14 +317,6 @@ impl<'tcx> CValue<'tcx> { let clif_ty = fx.clif_type(layout.ty).unwrap(); - if let ty::Bool = layout.ty.kind() { - assert!( - const_val == ty::ScalarInt::FALSE || const_val == ty::ScalarInt::TRUE, - "Invalid bool 0x{:032X}", - const_val - ); - } - let val = match layout.ty.kind() { ty::Uint(UintTy::U128) | ty::Int(IntTy::I128) => { let const_val = const_val.assert_bits(layout.size); From 9ee010cc3488c22767848a359cc10f88c499dbdf Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sat, 11 May 2024 17:19:46 +0000 Subject: [PATCH 062/179] Try to workaround gha issue with the caching action --- .github/workflows/rustc.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/rustc.yml b/.github/workflows/rustc.yml index 75ea94ee79790..70c214ce8b147 100644 --- a/.github/workflows/rustc.yml +++ b/.github/workflows/rustc.yml @@ -20,7 +20,7 @@ jobs: uses: actions/cache@v4 with: path: build/cg_clif - key: ${{ runner.os }}-cargo-build-target-${{ hashFiles('rust-toolchain', '**/Cargo.lock') }} + key: ${{ runner.os }}-rustc-test-cargo-build-target-${{ hashFiles('rust-toolchain', 'Cargo.lock') }} - name: Prepare dependencies run: ./y.sh prepare @@ -43,7 +43,7 @@ jobs: uses: actions/cache@v4 with: path: build/cg_clif - key: ${{ runner.os }}-cargo-build-target-${{ hashFiles('rust-toolchain', '**/Cargo.lock') }} + key: ${{ runner.os }}-rustc-test-cargo-build-target-${{ hashFiles('rust-toolchain', 'Cargo.lock') }} - name: Install ripgrep run: | From 50b34279c3bb84ac5287626d8ee2bc4414e5d07a Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sat, 11 May 2024 17:39:51 +0000 Subject: [PATCH 063/179] Split cgus into todo and done before the main module codegen loop --- src/concurrency_limiter.rs | 13 ------- src/driver/aot.rs | 69 +++++++++++++++++++------------------- 2 files changed, 35 insertions(+), 47 deletions(-) diff --git a/src/concurrency_limiter.rs b/src/concurrency_limiter.rs index 9678969134a8d..c7f543cf7cd2c 100644 --- a/src/concurrency_limiter.rs +++ b/src/concurrency_limiter.rs @@ -78,11 +78,6 @@ impl ConcurrencyLimiter { } } - pub(super) fn job_already_done(&mut self) { - let mut state = self.state.lock().unwrap(); - state.job_already_done(); - } - pub(crate) fn finished(mut self) { self.helper_thread.take(); @@ -190,14 +185,6 @@ mod state { self.assert_invariants(); } - pub(super) fn job_already_done(&mut self) { - self.assert_invariants(); - self.pending_jobs -= 1; - self.assert_invariants(); - self.drop_excess_capacity(); - self.assert_invariants(); - } - pub(super) fn poison(&mut self, error: String) { self.poisoned = true; self.stored_error = Some(error); diff --git a/src/driver/aot.rs b/src/driver/aot.rs index e8c96486041b1..2466cbed29925 100644 --- a/src/driver/aot.rs +++ b/src/driver/aot.rs @@ -604,40 +604,41 @@ pub(crate) fn run_aot( let global_asm_config = Arc::new(crate::global_asm::GlobalAsmConfig::new(tcx)); - let mut concurrency_limiter = ConcurrencyLimiter::new(tcx.sess, cgus.len()); - - let modules = tcx.sess.time("codegen mono items", || { - cgus.iter() - .enumerate() - .map(|(i, cgu)| { - let cgu_reuse = - if backend_config.disable_incr_cache { CguReuse::No } else { cgu_reuse[i] }; - match cgu_reuse { - CguReuse::No => { - let dep_node = cgu.codegen_dep_node(tcx); - tcx.dep_graph - .with_task( - dep_node, - tcx, - ( - backend_config.clone(), - global_asm_config.clone(), - cgu.name(), - concurrency_limiter.acquire(tcx.dcx()), - ), - module_codegen, - Some(rustc_middle::dep_graph::hash_result), - ) - .0 - } - CguReuse::PreLto | CguReuse::PostLto => { - concurrency_limiter.job_already_done(); - OngoingModuleCodegen::Sync(reuse_workproduct_for_cgu(tcx, cgu)) - } - } - }) - .collect::>() - }); + let (todo_cgus, done_cgus) = + cgus.into_iter().enumerate().partition::, _>(|&(i, _)| match cgu_reuse[i] { + _ if backend_config.disable_incr_cache => true, + CguReuse::No => true, + CguReuse::PreLto | CguReuse::PostLto => false, + }); + + let mut concurrency_limiter = ConcurrencyLimiter::new(tcx.sess, todo_cgus.len()); + + let modules = + tcx.sess.time("codegen mono items", || { + todo_cgus + .into_iter() + .map(|(_, cgu)| { + let dep_node = cgu.codegen_dep_node(tcx); + tcx.dep_graph + .with_task( + dep_node, + tcx, + ( + backend_config.clone(), + global_asm_config.clone(), + cgu.name(), + concurrency_limiter.acquire(tcx.dcx()), + ), + module_codegen, + Some(rustc_middle::dep_graph::hash_result), + ) + .0 + }) + .chain(done_cgus.into_iter().map(|(_, cgu)| { + OngoingModuleCodegen::Sync(reuse_workproduct_for_cgu(tcx, cgu)) + })) + .collect::>() + }); let mut allocator_module = make_module(tcx.sess, &backend_config, "allocator_shim".to_string()); let mut allocator_unwind_context = UnwindContext::new(allocator_module.isa(), true); From b46c3f279d254fd386912ba3f844ef8b75bfb699 Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Thu, 9 May 2024 18:18:01 +0300 Subject: [PATCH 064/179] use shared stage0 parser from `build_helper` Signed-off-by: onur-ozkan --- Cargo.lock | 2 +- src/bootstrap/src/core/config/config.rs | 38 +----- src/bootstrap/src/core/download.rs | 8 +- src/tools/build_helper/src/lib.rs | 1 + src/tools/build_helper/src/stage0_parser.rs | 76 +++++++++++ src/tools/bump-stage0/Cargo.toml | 2 +- src/tools/bump-stage0/src/main.rs | 134 +++++--------------- 7 files changed, 120 insertions(+), 141 deletions(-) create mode 100644 src/tools/build_helper/src/stage0_parser.rs diff --git a/Cargo.lock b/Cargo.lock index c034cbae9912b..aeefa89a608dd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -380,10 +380,10 @@ name = "bump-stage0" version = "0.1.0" dependencies = [ "anyhow", + "build_helper", "curl", "indexmap", "serde", - "serde_json", "toml 0.5.11", ] diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index ed45bc30362a5..5550b2047f576 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -181,7 +181,7 @@ pub struct Config { pub test_compare_mode: bool, pub color: Color, pub patch_binaries_for_nix: Option, - pub stage0_metadata: Stage0Metadata, + pub stage0_metadata: build_helper::stage0_parser::Stage0, pub android_ndk: Option, /// Whether to use the `c` feature of the `compiler_builtins` crate. pub optimized_compiler_builtins: bool, @@ -350,34 +350,6 @@ pub struct Config { pub paths: Vec, } -#[derive(Default, Deserialize, Clone)] -pub struct Stage0Metadata { - pub compiler: CompilerMetadata, - pub config: Stage0Config, - pub checksums_sha256: HashMap, - pub rustfmt: Option, -} -#[derive(Default, Deserialize, Clone)] -pub struct CompilerMetadata { - pub date: String, - pub version: String, -} - -#[derive(Default, Deserialize, Clone)] -pub struct Stage0Config { - pub dist_server: String, - pub artifacts_server: String, - pub artifacts_with_llvm_assertions_server: String, - pub git_merge_commit_email: String, - pub git_repository: String, - pub nightly_branch: String, -} -#[derive(Default, Deserialize, Clone)] -pub struct RustfmtMetadata { - pub date: String, - pub version: String, -} - #[derive(Clone, Debug, Default)] pub enum RustfmtState { SystemToolchain(PathBuf), @@ -1296,13 +1268,13 @@ impl Config { Some(p) => PathBuf::from(p), None => git_root, }; - // If this doesn't have at least `stage0.json`, we guessed wrong. This can happen when, + // If this doesn't have at least `stage0`, we guessed wrong. This can happen when, // for example, the build directory is inside of another unrelated git directory. // In that case keep the original `CARGO_MANIFEST_DIR` handling. // // NOTE: this implies that downloadable bootstrap isn't supported when the build directory is outside // the source directory. We could fix that by setting a variable from all three of python, ./x, and x.ps1. - if git_root.join("src").join("stage0.json").exists() { + if git_root.join("src").join("stage0").exists() { config.src = git_root; } } else { @@ -1320,9 +1292,7 @@ impl Config { .to_path_buf(); } - let stage0_json = t!(std::fs::read(config.src.join("src").join("stage0.json"))); - - config.stage0_metadata = t!(serde_json::from_slice::(&stage0_json)); + config.stage0_metadata = build_helper::stage0_parser::parse_stage0_file(); // Read from `--config`, then `RUST_BOOTSTRAP_CONFIG`, then `./config.toml`, then `config.toml` in the root directory. let toml_path = flags diff --git a/src/bootstrap/src/core/download.rs b/src/bootstrap/src/core/download.rs index 75e0f646da699..a074d53aa36e6 100644 --- a/src/bootstrap/src/core/download.rs +++ b/src/bootstrap/src/core/download.rs @@ -9,9 +9,9 @@ use std::{ }; use build_helper::ci::CiEnv; +use build_helper::stage0_parser::VersionMetadata; use xz2::bufread::XzDecoder; -use crate::core::config::RustfmtMetadata; use crate::utils::helpers::{check_run, exe, program_out_of_date}; use crate::{core::build_steps::llvm::detect_llvm_sha, utils::helpers::hex_encode}; use crate::{t, Config}; @@ -408,7 +408,7 @@ impl Config { /// NOTE: rustfmt is a completely different toolchain than the bootstrap compiler, so it can't /// reuse target directories or artifacts pub(crate) fn maybe_download_rustfmt(&self) -> Option { - let RustfmtMetadata { date, version } = self.stage0_metadata.rustfmt.as_ref()?; + let VersionMetadata { date, version } = self.stage0_metadata.rustfmt.as_ref()?; let channel = format!("{version}-{date}"); let host = self.build; @@ -606,7 +606,7 @@ impl Config { DownloadSource::Dist => { let dist_server = env::var("RUSTUP_DIST_SERVER") .unwrap_or(self.stage0_metadata.config.dist_server.to_string()); - // NOTE: make `dist` part of the URL because that's how it's stored in src/stage0.json + // NOTE: make `dist` part of the URL because that's how it's stored in src/stage0 (dist_server, format!("dist/{key}/{filename}"), true) } }; @@ -616,7 +616,7 @@ impl Config { // this on each and every nightly ... let checksum = if should_verify { let error = format!( - "src/stage0.json doesn't contain a checksum for {url}. \ + "src/stage0 doesn't contain a checksum for {url}. \ Pre-built artifacts might not be available for this \ target at this time, see https://doc.rust-lang.org/nightly\ /rustc/platform-support.html for more information." diff --git a/src/tools/build_helper/src/lib.rs b/src/tools/build_helper/src/lib.rs index 575f3677155e5..6a4e86eb1dfe5 100644 --- a/src/tools/build_helper/src/lib.rs +++ b/src/tools/build_helper/src/lib.rs @@ -2,3 +2,4 @@ pub mod ci; pub mod git; pub mod metrics; pub mod util; +pub mod stage0_parser; diff --git a/src/tools/build_helper/src/stage0_parser.rs b/src/tools/build_helper/src/stage0_parser.rs new file mode 100644 index 0000000000000..ff05b1169895c --- /dev/null +++ b/src/tools/build_helper/src/stage0_parser.rs @@ -0,0 +1,76 @@ +use std::collections::BTreeMap; + +#[derive(Default, Clone)] +pub struct Stage0 { + pub compiler: VersionMetadata, + pub rustfmt: Option, + pub config: Stage0Config, + pub checksums_sha256: BTreeMap, +} + +#[derive(Default, Clone)] +pub struct VersionMetadata { + pub date: String, + pub version: String, +} + +#[derive(Default, Clone)] +pub struct Stage0Config { + pub dist_server: String, + pub artifacts_server: String, + pub artifacts_with_llvm_assertions_server: String, + pub git_merge_commit_email: String, + pub git_repository: String, + pub nightly_branch: String, +} + +pub fn parse_stage0_file() -> Stage0 { + let stage0_content = include_str!("../../../stage0"); + + let mut stage0 = Stage0::default(); + for line in stage0_content.lines() { + let line = line.trim(); + + if line.is_empty() { + continue; + } + + // Ignore comments + if line.starts_with('#') { + continue; + } + + let (key, value) = line.split_once('=').unwrap(); + + match key { + "dist_server" => stage0.config.dist_server = value.to_owned(), + "artifacts_server" => stage0.config.artifacts_server = value.to_owned(), + "artifacts_with_llvm_assertions_server" => { + stage0.config.artifacts_with_llvm_assertions_server = value.to_owned() + } + "git_merge_commit_email" => stage0.config.git_merge_commit_email = value.to_owned(), + "git_repository" => stage0.config.git_repository = value.to_owned(), + "nightly_branch" => stage0.config.nightly_branch = value.to_owned(), + + "compiler_date" => stage0.compiler.date = value.to_owned(), + "compiler_version" => stage0.compiler.version = value.to_owned(), + + "rustfmt_date" => { + stage0.rustfmt.get_or_insert(VersionMetadata::default()).date = value.to_owned(); + } + "rustfmt_version" => { + stage0.rustfmt.get_or_insert(VersionMetadata::default()).version = value.to_owned(); + } + + dist if dist.starts_with("dist") => { + stage0.checksums_sha256.insert(key.to_owned(), value.to_owned()); + } + + unsupported => { + println!("'{unsupported}' field is not supported."); + } + } + } + + stage0 +} diff --git a/src/tools/bump-stage0/Cargo.toml b/src/tools/bump-stage0/Cargo.toml index 4680a7ab66107..de5d821133d53 100644 --- a/src/tools/bump-stage0/Cargo.toml +++ b/src/tools/bump-stage0/Cargo.toml @@ -7,8 +7,8 @@ edition = "2021" [dependencies] anyhow = "1.0.34" +build_helper = { path = "../build_helper" } curl = "0.4.38" indexmap = { version = "2.0.0", features = ["serde"] } serde = { version = "1.0.125", features = ["derive"] } -serde_json = { version = "1.0.59", features = ["preserve_order"] } toml = "0.5.7" diff --git a/src/tools/bump-stage0/src/main.rs b/src/tools/bump-stage0/src/main.rs index 1999859ff9883..f9c1699eb4cea 100644 --- a/src/tools/bump-stage0/src/main.rs +++ b/src/tools/bump-stage0/src/main.rs @@ -1,4 +1,7 @@ +#![deny(unused_variables)] + use anyhow::{Context, Error}; +use build_helper::stage0_parser::{parse_stage0_file, Stage0Config, VersionMetadata}; use curl::easy::Easy; use indexmap::IndexMap; use std::collections::HashMap; @@ -8,7 +11,7 @@ const COMPILER_COMPONENTS: &[&str] = &["rustc", "rust-std", "cargo", "clippy-pre const RUSTFMT_COMPONENTS: &[&str] = &["rustfmt-preview", "rustc"]; struct Tool { - config: Config, + config: Stage0Config, channel: Channel, date: Option, @@ -34,73 +37,9 @@ impl Tool { .try_into() .map_err(|_| anyhow::anyhow!("failed to parse version"))?; - // let existing: Stage0 = serde_json::from_slice(&std::fs::read(PATH)?)?; - let existing = Self::parse_stage0_file()?; + let existing = parse_stage0_file(); - Ok(Self { - channel, - version, - date, - config: existing.config, - checksums: IndexMap::new(), - }) - } - - fn parse_stage0_file() -> Result { - let stage0_content = include_str!("../../../stage0"); - - let mut stage0 = Stage0::default(); - - for line in stage0_content.lines() { - let line = line.trim(); - - if line.is_empty() { - continue; - } - - // Ignore comments - if line.starts_with('#') { - continue; - } - - let key_value: Vec<&str> = line.splitn(2, '=').collect(); - let (key, value) = (*key_value.get(0).unwrap(), *key_value.get(1).unwrap()); - - match key { - "dist_server" => stage0.config.dist_server = value.to_owned(), - "artifacts_server" - | "artifacts_with_llvm_assertions_server" - | "git_merge_commit_email" - | "git_repository" - | "nightly_branch" => { - stage0.config.other.insert(key.to_owned(), value.to_owned()); - } - - "compiler_date" => stage0.compiler.date = value.to_owned(), - "compiler_version" => stage0.compiler.version = value.to_owned(), - - "rustfmt_date" => { - let mut rustfmt = stage0.rustfmt.unwrap_or(Stage0Toolchain::default()); - rustfmt.date = value.to_owned(); - stage0.rustfmt = Some(rustfmt); - } - "rustfmt_version" => { - let mut rustfmt = stage0.rustfmt.unwrap_or(Stage0Toolchain::default()); - rustfmt.version = value.to_owned(); - stage0.rustfmt = Some(rustfmt); - } - - dist if dist.starts_with("dist") => { - stage0.checksums_sha256.insert(key.to_owned(), value.to_owned()); - } - - unsupported => { - println!("'{unsupported}' field is not supported."); - } - } - } - - Ok(stage0) + Ok(Self { channel, version, date, config: existing.config, checksums: IndexMap::new() }) } fn update_stage0_file(mut self) -> Result<(), Error> { @@ -115,11 +54,25 @@ impl Tool { "#; let mut file_content = HEADER.to_owned(); - file_content.push_str(&format!("\ndist_server={}", self.config.dist_server)); - for (key, value) in &self.config.other { - file_content.push_str(&format!("\n{}={}", key, value.as_str())); - } + let Stage0Config { + dist_server, + artifacts_server, + artifacts_with_llvm_assertions_server, + git_merge_commit_email, + git_repository, + nightly_branch, + } = &self.config; + + file_content.push_str(&format!("\ndist_server={}", dist_server)); + file_content.push_str(&format!("\nartifacts_server={}", artifacts_server)); + file_content.push_str(&format!( + "\nartifacts_with_llvm_assertions_server={}", + artifacts_with_llvm_assertions_server + )); + file_content.push_str(&format!("\ngit_merge_commit_email={}", git_merge_commit_email)); + file_content.push_str(&format!("\ngit_repository={}", git_repository)); + file_content.push_str(&format!("\nnightly_branch={}", nightly_branch)); file_content.push_str("\n"); @@ -149,7 +102,7 @@ impl Tool { // On the master branch the compiler version is configured to `beta` whereas if you're looking // at the beta or stable channel you'll likely see `1.x.0` as the version, with the previous // release's version number. - fn detect_compiler(&mut self) -> Result { + fn detect_compiler(&mut self) -> Result { let channel = match self.channel { Channel::Stable | Channel::Beta => { // The 1.XX manifest points to the latest point release of that minor release. @@ -160,7 +113,7 @@ impl Tool { let manifest = fetch_manifest(&self.config, &channel, self.date.as_deref())?; self.collect_checksums(&manifest, COMPILER_COMPONENTS)?; - Ok(Stage0Toolchain { + Ok(VersionMetadata { date: manifest.date, version: if self.channel == Channel::Nightly { "beta".to_string() @@ -179,14 +132,14 @@ impl Tool { /// We use a nightly rustfmt to format the source because it solves some bootstrapping issues /// with use of new syntax in this repo. For the beta/stable channels rustfmt is not provided, /// as we don't want to depend on rustfmt from nightly there. - fn detect_rustfmt(&mut self) -> Result, Error> { + fn detect_rustfmt(&mut self) -> Result, Error> { if self.channel != Channel::Nightly { return Ok(None); } let manifest = fetch_manifest(&self.config, "nightly", self.date.as_deref())?; self.collect_checksums(&manifest, RUSTFMT_COMPONENTS)?; - Ok(Some(Stage0Toolchain { date: manifest.date, version: "nightly".into() })) + Ok(Some(VersionMetadata { date: manifest.date, version: "nightly".into() })) } fn collect_checksums(&mut self, manifest: &Manifest, components: &[&str]) -> Result<(), Error> { @@ -220,7 +173,11 @@ fn main() -> Result<(), Error> { Ok(()) } -fn fetch_manifest(config: &Config, channel: &str, date: Option<&str>) -> Result { +fn fetch_manifest( + config: &Stage0Config, + channel: &str, + date: Option<&str>, +) -> Result { let url = if let Some(date) = date { format!("{}/dist/{}/channel-rust-{}.toml", config.dist_server, date, channel) } else { @@ -253,31 +210,6 @@ enum Channel { Nightly, } -#[derive(Debug, Default, serde::Serialize, serde::Deserialize)] -struct Stage0 { - config: Config, - compiler: Stage0Toolchain, - rustfmt: Option, - checksums_sha256: IndexMap, -} - -#[derive(Debug, Default, serde::Serialize, serde::Deserialize)] -struct Config { - dist_server: String, - /// There are other fields in the configuration, which will be read by src/bootstrap or other - /// tools consuming stage0 file. To avoid the need to update bump-stage0 every time a new field - /// is added, we collect all the fields in `IndexMap` and serialize them back with the - /// same order and structure they were deserialized in. - #[serde(flatten)] - other: IndexMap, -} - -#[derive(Debug, Default, serde::Serialize, serde::Deserialize)] -struct Stage0Toolchain { - date: String, - version: String, -} - #[derive(Debug, serde::Serialize, serde::Deserialize)] struct Manifest { date: String, From aa2faefe12498a6aaa8abfb9cbda5d848023dcc7 Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Thu, 9 May 2024 18:25:18 +0300 Subject: [PATCH 065/179] remove outdated stage0.json parts Signed-off-by: onur-ozkan --- config.example.toml | 6 +- src/stage0.json | 456 -------------------------------------------- triagebot.toml | 6 +- 3 files changed, 6 insertions(+), 462 deletions(-) delete mode 100644 src/stage0.json diff --git a/config.example.toml b/config.example.toml index 5c1fac7672a9a..33a3050417ee4 100644 --- a/config.example.toml +++ b/config.example.toml @@ -213,17 +213,17 @@ # the root of the repository. #build-dir = "build" -# Instead of downloading the src/stage0.json version of Cargo specified, use +# Instead of downloading the src/stage0 version of Cargo specified, use # this Cargo binary instead to build all Rust code # If you set this, you likely want to set `rustc` as well. #cargo = "/path/to/cargo" -# Instead of downloading the src/stage0.json version of the compiler +# Instead of downloading the src/stage0 version of the compiler # specified, use this rustc binary instead as the stage0 snapshot compiler. # If you set this, you likely want to set `cargo` as well. #rustc = "/path/to/rustc" -# Instead of downloading the src/stage0.json version of rustfmt specified, +# Instead of downloading the src/stage0 version of rustfmt specified, # use this rustfmt binary instead as the stage0 snapshot rustfmt. #rustfmt = "/path/to/rustfmt" diff --git a/src/stage0.json b/src/stage0.json deleted file mode 100644 index a9a53a7528fee..0000000000000 --- a/src/stage0.json +++ /dev/null @@ -1,456 +0,0 @@ -{ - "config": { - "dist_server": "https://static.rust-lang.org", - "artifacts_server": "https://ci-artifacts.rust-lang.org/rustc-builds", - "artifacts_with_llvm_assertions_server": "https://ci-artifacts.rust-lang.org/rustc-builds-alt", - "git_merge_commit_email": "bors@rust-lang.org", - "git_repository": "rust-lang/rust", - "nightly_branch": "master" - }, - "__comments": [ - "The configuration above this comment is editable, and can be changed", - "by forks of the repository if they have alternate values.", - "", - "The section below is generated by `./x.py run src/tools/bump-stage0`,", - "run that command again to update the bootstrap compiler.", - "", - "All changes below this comment will be overridden the next time the", - "tool is executed." - ], - "compiler": { - "date": "2024-04-29", - "version": "beta" - }, - "rustfmt": { - "date": "2024-04-29", - "version": "nightly" - }, - "checksums_sha256": { - "dist/2024-04-29/cargo-beta-aarch64-apple-darwin.tar.gz": "5a8c5e48a88e7c7b41eb720d60fbd2e879b97639c7ff83710526e8e6caaf8afb", - "dist/2024-04-29/cargo-beta-aarch64-apple-darwin.tar.xz": "0d237535ae8d435d99104fa5b9dbf41878e2304bb0f2eb574bf17dd685caadc2", - "dist/2024-04-29/cargo-beta-aarch64-pc-windows-msvc.tar.gz": "c56733bb6198af0a9b0df9a44ef979150e00de33b70853c239cccfcce23c328f", - "dist/2024-04-29/cargo-beta-aarch64-pc-windows-msvc.tar.xz": "7da5f887151215ddec640684077d98551fe2aed75a3ece2c73b20698754a70bb", - "dist/2024-04-29/cargo-beta-aarch64-unknown-linux-gnu.tar.gz": "73851e304a539d41bedc0d8a5d98800c8279ae623d3e58e863f8c1f8b458b01c", - "dist/2024-04-29/cargo-beta-aarch64-unknown-linux-gnu.tar.xz": "db9c28841344b0154756e19a21795ef6e0c4e27c7844be9996824f1039edaa81", - "dist/2024-04-29/cargo-beta-aarch64-unknown-linux-musl.tar.gz": "a706c8c7e37b9e80d7faa000c5d179a772746eef071387fb2879fdeab1f1f891", - "dist/2024-04-29/cargo-beta-aarch64-unknown-linux-musl.tar.xz": "2060634afe1b4a19bae874c6ce3cf4256e613af26e06104b45da5bd71cfb133c", - "dist/2024-04-29/cargo-beta-arm-unknown-linux-gnueabi.tar.gz": "7af61e74faea669fdd41793e4b88eb6a37bfacf845af364ee02bb7cf08c612c7", - "dist/2024-04-29/cargo-beta-arm-unknown-linux-gnueabi.tar.xz": "4759fb3e3d89ead605c4eeba23be5cb9b3ac98086a9de20f8dbfdfa9282ee486", - "dist/2024-04-29/cargo-beta-arm-unknown-linux-gnueabihf.tar.gz": "4cab18df2d94702e8b551357373bcae60d1023e644148f0f82e8971023362121", - "dist/2024-04-29/cargo-beta-arm-unknown-linux-gnueabihf.tar.xz": "7de4f0d72b4e5770376ede82b02d6bcfd450788a40375fad34d75524c941d72c", - "dist/2024-04-29/cargo-beta-armv7-unknown-linux-gnueabihf.tar.gz": "6401391a426cf33d6c58f07e7b2828b178720cb4f2b8577ae932b5f5b7d6744e", - "dist/2024-04-29/cargo-beta-armv7-unknown-linux-gnueabihf.tar.xz": "c3f6729bc769325046f0f62c51b5bed30068c37dc2a36a6283e50565d8cb7d5c", - "dist/2024-04-29/cargo-beta-i686-pc-windows-gnu.tar.gz": "d116c97c1242220c7972b63010aee1ed36bf5353e84a06d3561cd5fe9d7dae84", - "dist/2024-04-29/cargo-beta-i686-pc-windows-gnu.tar.xz": "65eba577f7775b3eef36e7f000b5007264392b20a7759f8ed567f3a45b2877db", - "dist/2024-04-29/cargo-beta-i686-pc-windows-msvc.tar.gz": "d418a3371b3631328bde2b1e0c3159700f12424e83b1d8ece1349fea90f9e403", - "dist/2024-04-29/cargo-beta-i686-pc-windows-msvc.tar.xz": "23ae73c776fdb0795944656d743444e3b4c440f45084028206c1aec52333b1ba", - "dist/2024-04-29/cargo-beta-i686-unknown-linux-gnu.tar.gz": "b6bbdeb7c8bfac2e8a083adb4782caf5321799f47acb4eaf81da32bd11730e9c", - "dist/2024-04-29/cargo-beta-i686-unknown-linux-gnu.tar.xz": "6b409691da6ddb8c04409667b2c3d9d6429c6b5bf53ad18177248406a5f06cb9", - "dist/2024-04-29/cargo-beta-loongarch64-unknown-linux-gnu.tar.gz": "24cd888d14a788e8fb5b886735f3c07a028a8681df48a777b2bb971c62a175ae", - "dist/2024-04-29/cargo-beta-loongarch64-unknown-linux-gnu.tar.xz": "e8eece6412936fe4dc863a5e19e6766fbb20e81da0069ad7831465e638db23da", - "dist/2024-04-29/cargo-beta-powerpc-unknown-linux-gnu.tar.gz": "8f007a2aa02e35c5ddb2152cc7589092a0e3083211c6aa23e676e3a3ad5a4b8d", - "dist/2024-04-29/cargo-beta-powerpc-unknown-linux-gnu.tar.xz": "3e423e693dd0813f5d87d9eded94894076258ece56684f3598321cd013aeef3c", - "dist/2024-04-29/cargo-beta-powerpc64-unknown-linux-gnu.tar.gz": "2eec5e45e389a52b526a5cf683d56a9df92004f6095936b16cd8d7d63722cc6c", - "dist/2024-04-29/cargo-beta-powerpc64-unknown-linux-gnu.tar.xz": "64c5135cbff9d4fa9575074c55e79d85f72cb1783498a72e1f77865b9b2d1ba3", - "dist/2024-04-29/cargo-beta-powerpc64le-unknown-linux-gnu.tar.gz": "d64552a80ca386728e42f00d7f1c700b5e30e5a6939f32ffa15a7ce715d4c8e9", - "dist/2024-04-29/cargo-beta-powerpc64le-unknown-linux-gnu.tar.xz": "fe91adce8ba35bf06251448b5214ed112556dc8814de92e66bc5dc51193c442f", - "dist/2024-04-29/cargo-beta-riscv64gc-unknown-linux-gnu.tar.gz": "77aafa8b63a4bf4475e82cd777646be5254e1f62d44b2a8fbd40066fdd7020d3", - "dist/2024-04-29/cargo-beta-riscv64gc-unknown-linux-gnu.tar.xz": "c38f0b4adcc8e48f70b475636bbd5851406bba296d66df12e1ba54888a4bf21a", - "dist/2024-04-29/cargo-beta-s390x-unknown-linux-gnu.tar.gz": "c05df24d7e8dff26c01055ad40f9e81e6fcb3ae634ecc1f7cc43c3108677fa0e", - "dist/2024-04-29/cargo-beta-s390x-unknown-linux-gnu.tar.xz": "47e8f4ec4d996600e60ddc49daeeb43d4c21e0583a86c12395c16eddc7db76ee", - "dist/2024-04-29/cargo-beta-x86_64-apple-darwin.tar.gz": "f024bd225b77160dc2fabde78002c8deac5cbb9a35345340964c3b988b0d1791", - "dist/2024-04-29/cargo-beta-x86_64-apple-darwin.tar.xz": "96c9e44bd9f0c85c793e3dd6043cc4f89fbeeab5ddf0fdb5daefca8f690bce05", - "dist/2024-04-29/cargo-beta-x86_64-pc-windows-gnu.tar.gz": "517889f222b62150fe16bcfd3a0eb5f353956b0084d85713480197bff4558145", - "dist/2024-04-29/cargo-beta-x86_64-pc-windows-gnu.tar.xz": "a6653ea4aec51569c1300c044d8bf2517a1f5111f710d12cd352190425b8f317", - "dist/2024-04-29/cargo-beta-x86_64-pc-windows-msvc.tar.gz": "4cb5b5054dffe6721efbbf29192a67e59cda69ea4ab4791aaec6f314eefa5a5e", - "dist/2024-04-29/cargo-beta-x86_64-pc-windows-msvc.tar.xz": "08bc45be22e9e4f615d1c9e70500046c8db89045f5d40dcde853c610591712a7", - "dist/2024-04-29/cargo-beta-x86_64-unknown-freebsd.tar.gz": "9661357ee8ea8973016fdbaa2de3cb98713136dcd25f07aa9f9d101180276815", - "dist/2024-04-29/cargo-beta-x86_64-unknown-freebsd.tar.xz": "7fab806227d1a3be817602abb121ac7e039ba0bbf81e0a1d47bdcccca74203c6", - "dist/2024-04-29/cargo-beta-x86_64-unknown-illumos.tar.gz": "4c79bb48cfe64bd38af7fe3660cd8bdc99ec90738a0d8fdf80843ecda910dab0", - "dist/2024-04-29/cargo-beta-x86_64-unknown-illumos.tar.xz": "0fb9edfdafde1820ccb25c22369cafb0e75e68795effeb615cb284a5837c75ba", - "dist/2024-04-29/cargo-beta-x86_64-unknown-linux-gnu.tar.gz": "c1902a072e61ab5ae9737a1092732e3972deee426424bc85fcf8702adffdd41d", - "dist/2024-04-29/cargo-beta-x86_64-unknown-linux-gnu.tar.xz": "d39ea1195dcc95e428bd540abd2db5b5d4c997a7661a41a4c0ca41cbdd18d27e", - "dist/2024-04-29/cargo-beta-x86_64-unknown-linux-musl.tar.gz": "0edfdb6f6bb2a4a1a96a5e95cec897c444c936e6624bb4a530ffed4847b97445", - "dist/2024-04-29/cargo-beta-x86_64-unknown-linux-musl.tar.xz": "70c264b7845febdee45d0c6e44b65d47ba7f367ef33ec906a9fd7f992ba7cc13", - "dist/2024-04-29/cargo-beta-x86_64-unknown-netbsd.tar.gz": "f1bd6417a54f3b53d572ce4af799242db7c11265c71201cc09c78d71be38c13a", - "dist/2024-04-29/cargo-beta-x86_64-unknown-netbsd.tar.xz": "53569810469c483785333759f86434706ee5368d5e18270ee13a17817ad57d40", - "dist/2024-04-29/clippy-beta-aarch64-apple-darwin.tar.gz": "7b693bde61a090854527a145455ff774314c65ec0cd47d25a19c76c6a166d96c", - "dist/2024-04-29/clippy-beta-aarch64-apple-darwin.tar.xz": "2494e9fdd8d342b6bc3e55eecfd555c43e3cca8421f3236df2d5a366288fec62", - "dist/2024-04-29/clippy-beta-aarch64-pc-windows-msvc.tar.gz": "90307f09c6fcb0c1fbe3ad1522a5381a17e2f69637c6d00f4a2cb5f3149bf736", - "dist/2024-04-29/clippy-beta-aarch64-pc-windows-msvc.tar.xz": "f7e0dec4a4862bd85d894252366152b3b6a7627e7e5a25ce323fa2db3bd87c2b", - "dist/2024-04-29/clippy-beta-aarch64-unknown-linux-gnu.tar.gz": "7c719e38f2a1030ae61985205df52f9a0c37b659463a5e2dea8e60e632de2d73", - "dist/2024-04-29/clippy-beta-aarch64-unknown-linux-gnu.tar.xz": "181ff4ae6adced6522a4c29869be3cc5dac8b961c7c88f2957cd31f831490807", - "dist/2024-04-29/clippy-beta-aarch64-unknown-linux-musl.tar.gz": "4e0e63e6f200386995e369a2673867d1bc3005d51d6a57c00ca80056dd85316b", - "dist/2024-04-29/clippy-beta-aarch64-unknown-linux-musl.tar.xz": "3d5b22a13aed6821482e60d9cc8571e2da9d95d82104284b77c56985a35a9c4e", - "dist/2024-04-29/clippy-beta-arm-unknown-linux-gnueabi.tar.gz": "9f788db76a5d55b3ecdd04a70b0e2be466959f76ae9fd3497ca2c503504e0c03", - "dist/2024-04-29/clippy-beta-arm-unknown-linux-gnueabi.tar.xz": "f4d8fc103807fba61d71d88b8e25a7016bfbd1a2905330f9a9fb3d7ba082713a", - "dist/2024-04-29/clippy-beta-arm-unknown-linux-gnueabihf.tar.gz": "d61bec3d017dd0be43e48350190ad18c0a0269e43d964600b62e1f7fd4f84399", - "dist/2024-04-29/clippy-beta-arm-unknown-linux-gnueabihf.tar.xz": "c00cbdc41a4da0c313a1a282b0158b059dd34f640b582cb7ca18e3d290ca8fa5", - "dist/2024-04-29/clippy-beta-armv7-unknown-linux-gnueabihf.tar.gz": "52143a530ca5274fbb760beecddff16f860ea787443d3dc708dda7c8f32ca9bd", - "dist/2024-04-29/clippy-beta-armv7-unknown-linux-gnueabihf.tar.xz": "c6d2dfeac6f40811bc9b4cec3c23f9c3bb46f761e006257b9313aa7c1a647b5a", - "dist/2024-04-29/clippy-beta-i686-pc-windows-gnu.tar.gz": "325d39e426b1907fa17d93c0752d3d73bd95750f4f967c2a84aab2c5dac8a588", - "dist/2024-04-29/clippy-beta-i686-pc-windows-gnu.tar.xz": "536f591d4da455302029384ed196932d71119ef0160ac5415617d6b777c51123", - "dist/2024-04-29/clippy-beta-i686-pc-windows-msvc.tar.gz": "c3684c9bf471669d444853bf484880d17e150ecb0e7505de90883382023e343b", - "dist/2024-04-29/clippy-beta-i686-pc-windows-msvc.tar.xz": "0b00e6132f73d5dc762e359b0005fceab0cf7b01337d8f4aa9eacfb4552f9245", - "dist/2024-04-29/clippy-beta-i686-unknown-linux-gnu.tar.gz": "c91c1eadfc4cbae360a0eecf11c32d2509b68aca86c7b1de3b102944f43e1511", - "dist/2024-04-29/clippy-beta-i686-unknown-linux-gnu.tar.xz": "6f7a5a287dd6226c203bb674ff02ec773e5d0813091b2af744b88ecd6997a304", - "dist/2024-04-29/clippy-beta-loongarch64-unknown-linux-gnu.tar.gz": "58383f094995823ea6db6a87b9ad4b33bdae2264d29bab88ab71ec60ccab3b93", - "dist/2024-04-29/clippy-beta-loongarch64-unknown-linux-gnu.tar.xz": "dbf4680a6fd4dca54acca5503a7fd94502b8e85819bc02346ae9cecd275e4514", - "dist/2024-04-29/clippy-beta-powerpc-unknown-linux-gnu.tar.gz": "e28eb32cda42654c0f0247aa8e15f01f73770b36f7626c8d6f1b7659accc56e6", - "dist/2024-04-29/clippy-beta-powerpc-unknown-linux-gnu.tar.xz": "fcc48a83b748e1e46f9daef40563f8e5abbb0e3f014a168b04f3c700c2ace2b8", - "dist/2024-04-29/clippy-beta-powerpc64-unknown-linux-gnu.tar.gz": "b626faf3275fcd196cd627e8a36c67721bae16a56f61cd080c79d137b3ec7737", - "dist/2024-04-29/clippy-beta-powerpc64-unknown-linux-gnu.tar.xz": "2c599d2dc719d69f67625f3c6573fcc4f1ea3266801557dd3892bdb7c761b4cf", - "dist/2024-04-29/clippy-beta-powerpc64le-unknown-linux-gnu.tar.gz": "0bc1f546fe0cef2b9516231ab608de68d55f72022fbc9ced5101b600e005f8c4", - "dist/2024-04-29/clippy-beta-powerpc64le-unknown-linux-gnu.tar.xz": "993294f2ae5202785ab242c1c6567df9c8ab1ef44ad35748c526b7fe854fb94e", - "dist/2024-04-29/clippy-beta-riscv64gc-unknown-linux-gnu.tar.gz": "210a4f0d208e0c8e13a57fb3b3e6c98ab5f620e4988d10a127ff1424ac1d5ca9", - "dist/2024-04-29/clippy-beta-riscv64gc-unknown-linux-gnu.tar.xz": "f10f7df41a13ee2ecdc25d60e697cba2342129a912ef20d8bfca5f611a9ec97f", - "dist/2024-04-29/clippy-beta-s390x-unknown-linux-gnu.tar.gz": "3e24d2af65f0c9667c9997ce091711b2be48e673de3707cddfd8cda455dfecc7", - "dist/2024-04-29/clippy-beta-s390x-unknown-linux-gnu.tar.xz": "0e7b8fbd0207489e38c78c2ae1aa0df4fcbdd84741aa50a86379e4d7ede286b1", - "dist/2024-04-29/clippy-beta-x86_64-apple-darwin.tar.gz": "9c0c47fd97ce72abcd6126315834c62aa7297fe09d447ee4cefa1eb46a116326", - "dist/2024-04-29/clippy-beta-x86_64-apple-darwin.tar.xz": "49dd65c5340fd804399edfa2402cf255fd9bfce1f4aa7fbb3c193c11bc03f8af", - "dist/2024-04-29/clippy-beta-x86_64-pc-windows-gnu.tar.gz": "6c1c3bdf097a1846ae08b098c555c0c5e9e9b646c744d6bb5a855789196b8bf6", - "dist/2024-04-29/clippy-beta-x86_64-pc-windows-gnu.tar.xz": "0a7319d1062f73af1c8f0efe6ad970d10d02259162c5bc84bb1f3a10f3911bcb", - "dist/2024-04-29/clippy-beta-x86_64-pc-windows-msvc.tar.gz": "52fef3f8a64fa58934a633bd4944e8ba9e15f2c2766d0f302dea1a6523864dab", - "dist/2024-04-29/clippy-beta-x86_64-pc-windows-msvc.tar.xz": "8fdbe7590e62ab68a2e463b14da2595e8c4592744f578a813f64d430ed7db4b6", - "dist/2024-04-29/clippy-beta-x86_64-unknown-freebsd.tar.gz": "509bf535622bd26385184ee0c17e4e27a5061a8aeebf5759f24bd578692b2f5d", - "dist/2024-04-29/clippy-beta-x86_64-unknown-freebsd.tar.xz": "2fcd10ada329ba7633616bebc584dca13f11c465e7cf513e76efeb0c3174486f", - "dist/2024-04-29/clippy-beta-x86_64-unknown-illumos.tar.gz": "ea8cea0d4a2379bcd0693f6174b25bc1f90a016dbe8280159cbb61d859806fb0", - "dist/2024-04-29/clippy-beta-x86_64-unknown-illumos.tar.xz": "5a243df8d1345db6bd18e4386ba628e6d302bce1cc572fb447cca4264fda3ee9", - "dist/2024-04-29/clippy-beta-x86_64-unknown-linux-gnu.tar.gz": "2ee560d3c1e306e103eb06d8e8033cd1489b3f6ff9df3bd8a95e25e977befa27", - "dist/2024-04-29/clippy-beta-x86_64-unknown-linux-gnu.tar.xz": "aaf6e54184a65ad6592bf03955a84ad12b561afd86064b1ac5fa03cf637052f8", - "dist/2024-04-29/clippy-beta-x86_64-unknown-linux-musl.tar.gz": "1b3877424a0a0eb507675a50e9d2c793f00ab85f6f12b1e27f871331070325b8", - "dist/2024-04-29/clippy-beta-x86_64-unknown-linux-musl.tar.xz": "6df5eaae5afb64557ba5c3a53ee3e56dab85455838a6044c7671c1180acfeaf9", - "dist/2024-04-29/clippy-beta-x86_64-unknown-netbsd.tar.gz": "1ac05ed7b607fff8b77ff203a663e9f4f2487779bc25e2dcd454cdf5b7583328", - "dist/2024-04-29/clippy-beta-x86_64-unknown-netbsd.tar.xz": "da502375b3cee8b254ab5999809f522692c2d1d90ea0544ad03c0ca514c65ef4", - "dist/2024-04-29/rust-std-beta-aarch64-apple-darwin.tar.gz": "2fdd35ca3b3e3d6f548f11c93337f5bf2e3c088bc78a79881e6f8e230b38b9a5", - "dist/2024-04-29/rust-std-beta-aarch64-apple-darwin.tar.xz": "bc16b3a1ab6ed69f0121a117c50cbcd201500dae4d72ad0dab148913d04cc529", - "dist/2024-04-29/rust-std-beta-aarch64-apple-ios-sim.tar.gz": "9375c786703c17baae1c2066f8d972ac316bc840e478ecd1b94288a1d428324e", - "dist/2024-04-29/rust-std-beta-aarch64-apple-ios-sim.tar.xz": "50d6818a8dd3ab7a3ddbbd7a062b538d9ff3ceb6eada031d1c22ab1dc7ba512c", - "dist/2024-04-29/rust-std-beta-aarch64-apple-ios.tar.gz": "56c3a01e8fd5c2ed75df811993b0b724709fb5473cc308ac09e7f5644468f751", - "dist/2024-04-29/rust-std-beta-aarch64-apple-ios.tar.xz": "3527d1f2c99c806479fb4b3801335dc921b514f171b82cd252cbbfc9ed30b163", - "dist/2024-04-29/rust-std-beta-aarch64-linux-android.tar.gz": "bf8cae7c66489f1aa27f1dea1b37f0d0ae514a6e21b93ff2dc6400dc88feca03", - "dist/2024-04-29/rust-std-beta-aarch64-linux-android.tar.xz": "46799f0bc1b3c13877f6cb732774cb3b33e0d8a081bfb56d0f877e79482aa1de", - "dist/2024-04-29/rust-std-beta-aarch64-pc-windows-gnullvm.tar.gz": "9f90fadab5104e1d415edf3b4edfaf7222f9f0d55f849851efdec74ffee16f8d", - "dist/2024-04-29/rust-std-beta-aarch64-pc-windows-gnullvm.tar.xz": "87ed6774202b18691bd6884df6944c7e9fe9c944b57a2837e7a7647518bf94e8", - "dist/2024-04-29/rust-std-beta-aarch64-pc-windows-msvc.tar.gz": "4a0692ad28f7f130b472ffa4aa766b745ba01fb75aa921f2da6622c9c68750df", - "dist/2024-04-29/rust-std-beta-aarch64-pc-windows-msvc.tar.xz": "a3d45962489a1e18a87e567cbbc8d3665f38809d0ad2ef15bcf0ff9fb9f470a4", - "dist/2024-04-29/rust-std-beta-aarch64-unknown-fuchsia.tar.gz": "c724f4eb135f73b9c79618f27a1ab35dc7b9d26ca62ed796accce68f9e747a66", - "dist/2024-04-29/rust-std-beta-aarch64-unknown-fuchsia.tar.xz": "8eab25782d16bcee75f86ecbb826346beb4a7525b220b45b3ba05a567c6d4391", - "dist/2024-04-29/rust-std-beta-aarch64-unknown-linux-gnu.tar.gz": "33ab1f8410edf590570d7468dbe2ebb5a0907125bbc8d360a928dcb355f0d0e6", - "dist/2024-04-29/rust-std-beta-aarch64-unknown-linux-gnu.tar.xz": "d3d870209a55ac96391affaa347c04f48cf98c089ac5056f340b8bb38bcc8e60", - "dist/2024-04-29/rust-std-beta-aarch64-unknown-linux-musl.tar.gz": "4d2bb72b898c30a2fc8d5d3333c2e99a8e30c15891fab641b6a519dc9f0cb611", - "dist/2024-04-29/rust-std-beta-aarch64-unknown-linux-musl.tar.xz": "fa343e6b6110fcd0c5dae4287ff1a799de5d7e4a805dbf4e9a034bbaed2bf269", - "dist/2024-04-29/rust-std-beta-aarch64-unknown-linux-ohos.tar.gz": "f1ec4139783169fd83e1b0184518ed25d26cee7b21f196deecc74e83a1d78725", - "dist/2024-04-29/rust-std-beta-aarch64-unknown-linux-ohos.tar.xz": "d100be2f6f0346c4b1f5b41aec0c13a47426bf4d49127f2341c8332903e4e782", - "dist/2024-04-29/rust-std-beta-aarch64-unknown-none-softfloat.tar.gz": "bab6051e1071a58cd126580f6644decf16edb4473fe4be6a34791610d820a294", - "dist/2024-04-29/rust-std-beta-aarch64-unknown-none-softfloat.tar.xz": "d9b68f06ff23629063e92dfc42aa3115a858238d368e4b52b35c1ea4491b1402", - "dist/2024-04-29/rust-std-beta-aarch64-unknown-none.tar.gz": "96804c2d9accd3242bdc22dad688b2ccee071952477b9c592f099377aee6c591", - "dist/2024-04-29/rust-std-beta-aarch64-unknown-none.tar.xz": "3fed6812d84bdaf787e85c37e23ba729b81a6d25a2b33fed75320e66e6641c89", - "dist/2024-04-29/rust-std-beta-aarch64-unknown-uefi.tar.gz": "8da5f301bff35fc067ec7cfb878ebfa5607af7dbc276a6b34a77404432c700d2", - "dist/2024-04-29/rust-std-beta-aarch64-unknown-uefi.tar.xz": "80d643189dc9af98b6410a01261ce6ad34b1325f3aebf3ff61fb43f1261b41ff", - "dist/2024-04-29/rust-std-beta-arm-linux-androideabi.tar.gz": "2e86b54b0d1f7fefead11d6383bdc80fe0a7b3ccf58381d2a731e6f1c62926de", - "dist/2024-04-29/rust-std-beta-arm-linux-androideabi.tar.xz": "9831a0270457cad2798b5ae4fe956c257c7e10ce5ad211793dc467577cdec29e", - "dist/2024-04-29/rust-std-beta-arm-unknown-linux-gnueabi.tar.gz": "f96bc303c0c2be9cf589f00aa63b2cf3fb8585ca9dd8860fe525821bfa1fe19a", - "dist/2024-04-29/rust-std-beta-arm-unknown-linux-gnueabi.tar.xz": "e57a053b1c2bb6fad93dfaffedce7f48fa292196fc8ba6fd2f0c74dc810a13a9", - "dist/2024-04-29/rust-std-beta-arm-unknown-linux-gnueabihf.tar.gz": "49b2cb2ba5296871b5fac5ad9a74a2891e8b78321078a455ba4a65e003bebd40", - "dist/2024-04-29/rust-std-beta-arm-unknown-linux-gnueabihf.tar.xz": "0f9c15d834a9d282a4018934759f7b48ef3d275e09679a68c5fd1b3f047d02e4", - "dist/2024-04-29/rust-std-beta-arm-unknown-linux-musleabi.tar.gz": "e59f92827241e670c1aa92b35235ad12340869d59327fb83084b5f4149acbe06", - "dist/2024-04-29/rust-std-beta-arm-unknown-linux-musleabi.tar.xz": "ad1cf96bb1fcceaa016e29e8ad34b4cfd711d2e0bd7cabb9cd7cc28abf64d894", - "dist/2024-04-29/rust-std-beta-arm-unknown-linux-musleabihf.tar.gz": "14a6d318af85bb9fa5c229e45a88a32a71f44ed02cd90a24bb67921eb64dee41", - "dist/2024-04-29/rust-std-beta-arm-unknown-linux-musleabihf.tar.xz": "ed6b48502ab9169818bceb300b4e6b4fd63366ad5808b047bf9988dae04c2729", - "dist/2024-04-29/rust-std-beta-armebv7r-none-eabi.tar.gz": "345e8a023be55e3b88a0c2677ea28c7bb4fcc5f3ab707638de76065c7592c2d5", - "dist/2024-04-29/rust-std-beta-armebv7r-none-eabi.tar.xz": "6d9b11d08f2d62611327a893b45ba07c36df11f077250496ab0881eb7ac84c65", - "dist/2024-04-29/rust-std-beta-armebv7r-none-eabihf.tar.gz": "a2ae1bf003a8a12b2ecb6bde9868a978820f184af523f0e4c3fc935edd509423", - "dist/2024-04-29/rust-std-beta-armebv7r-none-eabihf.tar.xz": "3d1dcf8308f9d4590b429f6abbf8f42f04496ab490ccf4ed8c9e381e6d886cae", - "dist/2024-04-29/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.gz": "a54106d27e4ce97463e7867ceff9dd22ba456f840ec23229e6909b37d48ad554", - "dist/2024-04-29/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.xz": "e6abfaa0905a00efeaee85b9f93793bab93e2cf4e172c9d829c5ba85006c688a", - "dist/2024-04-29/rust-std-beta-armv5te-unknown-linux-musleabi.tar.gz": "cbed18e5dc61fcecb2920affc3890c3b8ae46b7fe5a80b3288689e18d490f3f4", - "dist/2024-04-29/rust-std-beta-armv5te-unknown-linux-musleabi.tar.xz": "2b58bb0dd5cd2c5f7f93f4c6e9135090b931e0ffa27ff9efe2b8ff9fbbb7e48c", - "dist/2024-04-29/rust-std-beta-armv7-linux-androideabi.tar.gz": "6a371c2ececd349dfa76a02563069912fc91577ac4446d36c22f96723d7f5e9f", - "dist/2024-04-29/rust-std-beta-armv7-linux-androideabi.tar.xz": "9325daf41ddab02fa845971c10a5e0538a18c7bea14e66fa0f5f6fb16654c7ae", - "dist/2024-04-29/rust-std-beta-armv7-unknown-linux-gnueabi.tar.gz": "7f5ba76cfb7c85333c8dab76fb4ad3f12ddc254b95f9ee07fadb8e1270a4f767", - "dist/2024-04-29/rust-std-beta-armv7-unknown-linux-gnueabi.tar.xz": "f853b7f929b7a309ed6c08ff8c57d583ce0ccb19270674fb30e63a873834dc87", - "dist/2024-04-29/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.gz": "0680005d0a12498b687afc583d4f36bd67d0877cd9d3323bfd2df50d15c27afe", - "dist/2024-04-29/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.xz": "a494b78fcad01c83df9522d460ac2d35d2d00736a921381f2c611dc516edaa16", - "dist/2024-04-29/rust-std-beta-armv7-unknown-linux-musleabi.tar.gz": "cfa555db31b5470e878b0f53d86617e7342e8bf018fe62cb0271dfe13db95f51", - "dist/2024-04-29/rust-std-beta-armv7-unknown-linux-musleabi.tar.xz": "0a8ccd6d88cbe79a855111fbda45aa1a728de655b6927f3d429d901d2afc6503", - "dist/2024-04-29/rust-std-beta-armv7-unknown-linux-musleabihf.tar.gz": "eac53424001c884a540c42f0b68447349ec5d0601a030c060aaed76d54895728", - "dist/2024-04-29/rust-std-beta-armv7-unknown-linux-musleabihf.tar.xz": "42d78fca62361ff28db5bc43bb01cef7af5c6f4ab2110fe6170c3dce4707aab8", - "dist/2024-04-29/rust-std-beta-armv7-unknown-linux-ohos.tar.gz": "c88de9f2e667da73177fb9c9309d7f1f467e31c18e3ae50d722c71ec8dd876a4", - "dist/2024-04-29/rust-std-beta-armv7-unknown-linux-ohos.tar.xz": "24b3c04a42d511cdc8c6107b597be38981114f0574eced493d0e90fc748094bc", - "dist/2024-04-29/rust-std-beta-armv7a-none-eabi.tar.gz": "cd4ad182a098c61550265879ccc04733c39110827f7ef62eecfb8c120ae4ece8", - "dist/2024-04-29/rust-std-beta-armv7a-none-eabi.tar.xz": "8499a014dfdf448f474a58f148784c2eef245dc909587d876d2fb9ddc6a4ec3f", - "dist/2024-04-29/rust-std-beta-armv7r-none-eabi.tar.gz": "e8e1870e5b12b3d8643d712efb91eb86b2081284cada4a140c1526692ab183c4", - "dist/2024-04-29/rust-std-beta-armv7r-none-eabi.tar.xz": "d6029121eacc44bd4dcd9ef6dd3cd0d775cb6e9a3d99f3d62d746fcbf8981cab", - "dist/2024-04-29/rust-std-beta-armv7r-none-eabihf.tar.gz": "1e0fc42c3802e205130c01ca90f92d793c1c5427b34da66fe77b97cf67b4a5c1", - "dist/2024-04-29/rust-std-beta-armv7r-none-eabihf.tar.xz": "4c8cfdb11bb686111fa4842d13430c86d9d14ada30e9df334b3777fe899233e0", - "dist/2024-04-29/rust-std-beta-i586-pc-windows-msvc.tar.gz": "ff895c1b39b84587f10903f4be13d275b545e690da6761190d12c01acc25c6d8", - "dist/2024-04-29/rust-std-beta-i586-pc-windows-msvc.tar.xz": "fdcbcff7b740235bb16e44174fff9080a7c0a31be358c8abc41805c02c20c3b2", - "dist/2024-04-29/rust-std-beta-i586-unknown-linux-gnu.tar.gz": "6b227f3b9001e148b66b7001f753a6f88fef9677e39d8fcf4d9c35fe8d345568", - "dist/2024-04-29/rust-std-beta-i586-unknown-linux-gnu.tar.xz": "1e29297beb8de3778ba958731294823d9a93aac1e0d8833abc5aa99e2935965b", - "dist/2024-04-29/rust-std-beta-i586-unknown-linux-musl.tar.gz": "26481ad5f22a319830d42f69b1c0195bd65900ebe112e659432334b3468f3d0e", - "dist/2024-04-29/rust-std-beta-i586-unknown-linux-musl.tar.xz": "c8a837e0d9da8ad976fc1539541c085365aac9dd28b34e4a289d38a823d1b065", - "dist/2024-04-29/rust-std-beta-i686-linux-android.tar.gz": "f05e28a52f17e22f36ffc70018012a1fe6a07f4b461e774b36464f32bc8f8dea", - "dist/2024-04-29/rust-std-beta-i686-linux-android.tar.xz": "f9501b2691c51e54a6f4cc6fb72e41901eb551d3a7be5f82a94ce2d3e217828b", - "dist/2024-04-29/rust-std-beta-i686-pc-windows-gnu.tar.gz": "8d9a782d4f7450bca536aab45147c6ef08bc3847b43fdd171c6449e29762eda0", - "dist/2024-04-29/rust-std-beta-i686-pc-windows-gnu.tar.xz": "4008712e03fb6494eaba3d79051c5e3fdd93d4c52ae8d86cf8f344b5f051cbca", - "dist/2024-04-29/rust-std-beta-i686-pc-windows-gnullvm.tar.gz": "cfb23242e495834a3d0f7ffa3da4a0b206dcae35872b1455b11faeee5511ba5f", - "dist/2024-04-29/rust-std-beta-i686-pc-windows-gnullvm.tar.xz": "95415742c0171945ffc2b67c913ebd1330e29634af238f5ccc843a965340374a", - "dist/2024-04-29/rust-std-beta-i686-pc-windows-msvc.tar.gz": "e9354d69e39ecfac1d2928664d17d73f808256a4076b849171a9667705c0aa08", - "dist/2024-04-29/rust-std-beta-i686-pc-windows-msvc.tar.xz": "a34bb0a91170d84195f35ba52afa4c9be8a2f2706dbeea02bd6e8908e08ac65e", - "dist/2024-04-29/rust-std-beta-i686-unknown-freebsd.tar.gz": "d65f286de399ccc9e9acaf7a4dc4f885357c750231d54a144ba9a59181814f11", - "dist/2024-04-29/rust-std-beta-i686-unknown-freebsd.tar.xz": "4c93a7da70a69b2ebbac01df64af16344e523d16470b29e57237b1d0925f7721", - "dist/2024-04-29/rust-std-beta-i686-unknown-linux-gnu.tar.gz": "1b978bfd1a9234be7ef197c8c98c5a6b625f6fbb7b0fca58695986768bdca176", - "dist/2024-04-29/rust-std-beta-i686-unknown-linux-gnu.tar.xz": "98d4eb5b89a593c8c4f86244c9a7c737d9c18c0168aebe5923b8d9145adcf89a", - "dist/2024-04-29/rust-std-beta-i686-unknown-linux-musl.tar.gz": "dbf9b3c5b54b3eb0727f976f5632c5b0fcb2f90ac7453962d6cef20f7dae4284", - "dist/2024-04-29/rust-std-beta-i686-unknown-linux-musl.tar.xz": "f209ade093753342dda6e710ee832a538dbdaa08a24d606f9a2a1bc59b83da29", - "dist/2024-04-29/rust-std-beta-i686-unknown-uefi.tar.gz": "3c3ca7f34569b2c70c6b223754418a535dd7dfa087ab6e28ed2ec78d20065887", - "dist/2024-04-29/rust-std-beta-i686-unknown-uefi.tar.xz": "72a7cd0f430ab40d80e93f409b8e26a181010ab4bb75d151e829d51ccdcf8c62", - "dist/2024-04-29/rust-std-beta-loongarch64-unknown-linux-gnu.tar.gz": "b7dfa59bb05cf806c87854d6fce5ef0f160697052fdf6e5a0cad121499108608", - "dist/2024-04-29/rust-std-beta-loongarch64-unknown-linux-gnu.tar.xz": "88bc22f68bab3367cdfa91676418ce1ffc0ec002afb32aed7def880bdd4be402", - "dist/2024-04-29/rust-std-beta-loongarch64-unknown-none-softfloat.tar.gz": "d61019048b941064a99d19e46ff3236a88a2e8fcfb963cedd1d9d1c47963c170", - "dist/2024-04-29/rust-std-beta-loongarch64-unknown-none-softfloat.tar.xz": "7474bda08134c676d74afe5263317af3f271963d8ceaa5efbfa1b657f885c572", - "dist/2024-04-29/rust-std-beta-loongarch64-unknown-none.tar.gz": "e089c77d433d838ca02d7531d6f4a1770fb4a0568acbd96c8f43034d76f2990b", - "dist/2024-04-29/rust-std-beta-loongarch64-unknown-none.tar.xz": "364ae6c89c7a930098286e55193d2f5ee3d5ea80b7cca73046e41725f4a8a2f9", - "dist/2024-04-29/rust-std-beta-nvptx64-nvidia-cuda.tar.gz": "c17bfad87d16f3a8d26646525dc59a352718db9e7572acb583b68a18cfdc338a", - "dist/2024-04-29/rust-std-beta-nvptx64-nvidia-cuda.tar.xz": "f5c4ecef1c08d19ba6fddbd359a0ce94e46888021cae057fce969276026d086c", - "dist/2024-04-29/rust-std-beta-powerpc-unknown-linux-gnu.tar.gz": "3e7e13b0d2e804d228e1e3a9dac0205d294ae29dcc37132f15fb1e218861eb39", - "dist/2024-04-29/rust-std-beta-powerpc-unknown-linux-gnu.tar.xz": "ea31b7678e6f64c2f9c28a9af120be04ed6f2a25a496e40afbf6e9aa0dd20b60", - "dist/2024-04-29/rust-std-beta-powerpc64-unknown-linux-gnu.tar.gz": "f0e1b314c3d5ad1676c68c112581dce62fa06ad557cd5f61034e147b064ed270", - "dist/2024-04-29/rust-std-beta-powerpc64-unknown-linux-gnu.tar.xz": "8ab7bbea6e2f72df1286facc7d306d01809a4dd9f8901dfdec7e50b594658d49", - "dist/2024-04-29/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.gz": "48f6abda1c7dac185858744aa2cdc3513cdfb6552535282ee83cf9c5365573c7", - "dist/2024-04-29/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.xz": "d920d97f15b56ba6ea81e08b3c29dc7f44f5f30b7513c53446edf95843c332af", - "dist/2024-04-29/rust-std-beta-riscv32i-unknown-none-elf.tar.gz": "0a198a770f6e6043e923b0ab1a508fd8b190612d0370c33c8dd2c5f63b6f19dd", - "dist/2024-04-29/rust-std-beta-riscv32i-unknown-none-elf.tar.xz": "424a93313cfe2d85acf956be3d9ac71ea8e34ee61617a550ad6ff5360e1dff52", - "dist/2024-04-29/rust-std-beta-riscv32im-unknown-none-elf.tar.gz": "2e2b0a8e41f4ea774d665d6248cbc2fdbe3e582206efeb87d250786ebaad0b1a", - "dist/2024-04-29/rust-std-beta-riscv32im-unknown-none-elf.tar.xz": "2da372c091017b7096e473e5c7016a504d2e041e14173d2520086cb43e0a615a", - "dist/2024-04-29/rust-std-beta-riscv32imac-unknown-none-elf.tar.gz": "69d3b21403181b2df14243816388169db2466477ec34bcca5693fb017703686c", - "dist/2024-04-29/rust-std-beta-riscv32imac-unknown-none-elf.tar.xz": "281b9c20f8641a3d1b349e762b7f713fb0b91da0d21eec798e639e36a0ea3dab", - "dist/2024-04-29/rust-std-beta-riscv32imafc-unknown-none-elf.tar.gz": "dd9bfd3fd8446d35180fe781139dfb4e04dd658b112eb2a749e8f4aea14f0271", - "dist/2024-04-29/rust-std-beta-riscv32imafc-unknown-none-elf.tar.xz": "b1366375e0c5f53da581741dec91972b0c46d7d466052539207e8feaab0ba3ec", - "dist/2024-04-29/rust-std-beta-riscv32imc-unknown-none-elf.tar.gz": "7c6650d8cf8abd51547010e8211af3ef3195099ef43a563460ad4780de20ba17", - "dist/2024-04-29/rust-std-beta-riscv32imc-unknown-none-elf.tar.xz": "bab46f3c0078ce346de563bb7a248ca92f15dbdc73bf5a3bc520486118442320", - "dist/2024-04-29/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.gz": "01735b4ad5bc0a53087dd0ccaef2cf174b27e45bf4d2e3c15e64f7522f059c63", - "dist/2024-04-29/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.xz": "0bb272c2c235583ed3e9ec151b3bfc601f8cd07822c2fe47a1258b358be507f0", - "dist/2024-04-29/rust-std-beta-riscv64gc-unknown-none-elf.tar.gz": "b2c7f8ee0efe6d0812e4b5dd0979f60f105b84d34d4f600ef75f2eacd954893d", - "dist/2024-04-29/rust-std-beta-riscv64gc-unknown-none-elf.tar.xz": "0d5301fc553a6911af6643ab7f57b6438bf649ffcd050d486278c0c5fe38eeba", - "dist/2024-04-29/rust-std-beta-riscv64imac-unknown-none-elf.tar.gz": "0d1d35ecb88ee717720ad8e74bd5b602fd6011fe321baddb939f3b161e9cd8c5", - "dist/2024-04-29/rust-std-beta-riscv64imac-unknown-none-elf.tar.xz": "a5cf0b98596e68e6f72be2e83c61b8aaa19ead42f248ee2408a3b8f4e97a6657", - "dist/2024-04-29/rust-std-beta-s390x-unknown-linux-gnu.tar.gz": "629ed749cdae110668ad9ddbc5c61e99e8d400f3dd0981146c3820deadc360f6", - "dist/2024-04-29/rust-std-beta-s390x-unknown-linux-gnu.tar.xz": "192819438ed27a565cdb67b51d2f5caeb6ae258de86191d6922574327f132acd", - "dist/2024-04-29/rust-std-beta-sparc64-unknown-linux-gnu.tar.gz": "84286f6cf6f00f3c92dc881f64a31e1ec5910102d8d3d4faf6fc7e2ddf1544a7", - "dist/2024-04-29/rust-std-beta-sparc64-unknown-linux-gnu.tar.xz": "304b5f876b47dcbb7c3483c49295b822e8ba83234bb568ce67896ae4773ae2fa", - "dist/2024-04-29/rust-std-beta-sparcv9-sun-solaris.tar.gz": "25062159b859e21dda76ca22d4a31d3aba4fcdb0def78bc5b5cf9887c07c1be9", - "dist/2024-04-29/rust-std-beta-sparcv9-sun-solaris.tar.xz": "5d557ee86457f288462603fe53bcc2e092d84faee543659419fa68c1bd88f554", - "dist/2024-04-29/rust-std-beta-thumbv6m-none-eabi.tar.gz": "a9663048aad82ef832b2cf82fa9fb94be047f77e283e8aa3e2df6ad957d0782d", - "dist/2024-04-29/rust-std-beta-thumbv6m-none-eabi.tar.xz": "4c4b703a846b4123d09c1eace6322e82784a004b278f1f3b1ca1279e96207f18", - "dist/2024-04-29/rust-std-beta-thumbv7em-none-eabi.tar.gz": "32907c33f240abb1cb17ac438da42c5fa3932b270ad08fd6914775c5b59a02f5", - "dist/2024-04-29/rust-std-beta-thumbv7em-none-eabi.tar.xz": "112583227d2b6abfef6eeb78d980bf2efef392f3b66e433c4959a642d72ffc7b", - "dist/2024-04-29/rust-std-beta-thumbv7em-none-eabihf.tar.gz": "7ba0084527a18479c4b6f6a0dba8ae23a0ed50e9fc5fbfce23cae1babb5a1e12", - "dist/2024-04-29/rust-std-beta-thumbv7em-none-eabihf.tar.xz": "49eb4e2efe3a76713ce1fecacaf915717eeed8552912b92895c7fee068a85a36", - "dist/2024-04-29/rust-std-beta-thumbv7m-none-eabi.tar.gz": "518a532b52f2dad2825158614cd00b12aac6c6e1983a1ad53e2b0e26d1f1b845", - "dist/2024-04-29/rust-std-beta-thumbv7m-none-eabi.tar.xz": "2895e5796a29fd016462694d880e38eb191cb92c9bdb14414c1d6e63b23d3394", - "dist/2024-04-29/rust-std-beta-thumbv7neon-linux-androideabi.tar.gz": "2af590c063344c4c3f65d704fa255232b5f5954872d03c4c55d48662cbe6bb17", - "dist/2024-04-29/rust-std-beta-thumbv7neon-linux-androideabi.tar.xz": "a09df5f38183d9fe6116c807619f812410763ddedf06055bfe8040b5794104d3", - "dist/2024-04-29/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.gz": "eac22c4972bde3a57cf2ec4e31b43db3c4b7d961ae31475d8942e898c07640cc", - "dist/2024-04-29/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.xz": "104f2c6490e30cc47833edbd806c2efe6256d1194600b2278339612f94704d45", - "dist/2024-04-29/rust-std-beta-thumbv8m.base-none-eabi.tar.gz": "b3c9c9d7ce8c1db6f20e8ede542e67aacd6047c52882a5d06c4f96a40a7304d9", - "dist/2024-04-29/rust-std-beta-thumbv8m.base-none-eabi.tar.xz": "76bfb114bc7674792934a4892d2db41fdc8f5bd30c3aa96c43e8055199157476", - "dist/2024-04-29/rust-std-beta-thumbv8m.main-none-eabi.tar.gz": "1308335fe80dcafaba511ee589959d461145533de5f76118fee29a7e9a15841f", - "dist/2024-04-29/rust-std-beta-thumbv8m.main-none-eabi.tar.xz": "cb8acdb8920983c03b9495cf3506a3014384b4d2f6a53e7907924d38a0baf7f0", - "dist/2024-04-29/rust-std-beta-thumbv8m.main-none-eabihf.tar.gz": "9dd2e5ce7534ab4fbb93ff652196e877f4e9eea3863920c3d34a05d9a3598c81", - "dist/2024-04-29/rust-std-beta-thumbv8m.main-none-eabihf.tar.xz": "4b6e962facf7c54846965a8d6880e4a980804459151f2e22ac5af79bc79e26bb", - "dist/2024-04-29/rust-std-beta-wasm32-unknown-emscripten.tar.gz": "731603392b6e3d36b3a4956928d084e293ef18c8b8593efa756e753a2a309709", - "dist/2024-04-29/rust-std-beta-wasm32-unknown-emscripten.tar.xz": "8b681b3af47855eb63c4ffe06a2bc6bc4f365354ffbc171ce8cbd8c2a3588a07", - "dist/2024-04-29/rust-std-beta-wasm32-unknown-unknown.tar.gz": "7b87e59391493c3147c03794061111e25bdae669aea58190a951cdef111e75e0", - "dist/2024-04-29/rust-std-beta-wasm32-unknown-unknown.tar.xz": "d15eaadb101027906c2fce15b95a3f820bdbc4cf145b705bafc2ac5291289c3b", - "dist/2024-04-29/rust-std-beta-wasm32-wasi.tar.gz": "07390ec742b79ec11b2c3ec65f60efe5d7c616f50c33058fce346f6e9ad21af3", - "dist/2024-04-29/rust-std-beta-wasm32-wasi.tar.xz": "79e34d46621c298cadb98c00ce3b25d97474aec300d85255153b47e21b7bb744", - "dist/2024-04-29/rust-std-beta-wasm32-wasip1-threads.tar.gz": "b916dc9051b0278f820ea0b093db3ecae2e27de641ef67a9b508df75dc92c938", - "dist/2024-04-29/rust-std-beta-wasm32-wasip1-threads.tar.xz": "2867922a39da3b02ebdb93fb78b010695daf468f87485ad8ab79c7f3eeb18b11", - "dist/2024-04-29/rust-std-beta-wasm32-wasip1.tar.gz": "792b718c0a72e97ba85a17ba67ee09e55b85de829fe4021f828ce54ff8cb31e0", - "dist/2024-04-29/rust-std-beta-wasm32-wasip1.tar.xz": "abff86499119bddfeda9059004549941dbcd3d911702d4a9c198b94f60e60f4e", - "dist/2024-04-29/rust-std-beta-x86_64-apple-darwin.tar.gz": "0bcc7698efafb42a37f20815f5660e39829a42a2776304e7129d0a4ec0c7520b", - "dist/2024-04-29/rust-std-beta-x86_64-apple-darwin.tar.xz": "c437626e250b0d06c05dc828ab81d0d2c543ffce4b100567910508974ea50045", - "dist/2024-04-29/rust-std-beta-x86_64-apple-ios.tar.gz": "7c98c9f491bfc837111769a45c10ce2f1ef73c22377158ef9ae80b38034892c0", - "dist/2024-04-29/rust-std-beta-x86_64-apple-ios.tar.xz": "f4bda724e6e382e02ddf4e4e7a479120420666a5a1ad3c87a85d4d3c763f2cb2", - "dist/2024-04-29/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.gz": "01efbb2e48045318e18bfc7b6c190b461a219e81fc1cca6c855bf0c658aef556", - "dist/2024-04-29/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.xz": "9bff316c6d2fbb3c0889f9ffe4eae496b293fb3afaf8d597155e6badbf0c6a8e", - "dist/2024-04-29/rust-std-beta-x86_64-linux-android.tar.gz": "5da713547a8af2c86da7db5d8aa4c27188dea1089fded81ffbbeb0f78952a10f", - "dist/2024-04-29/rust-std-beta-x86_64-linux-android.tar.xz": "9d6a45d6af395360c63ce97bcfc2f9a2967c708afcd979f17fa447239703a92b", - "dist/2024-04-29/rust-std-beta-x86_64-pc-solaris.tar.gz": "d1a71110bee002c8edfbcc00e0f5eede5afa005b09944bb2cde469c658049e70", - "dist/2024-04-29/rust-std-beta-x86_64-pc-solaris.tar.xz": "6b8d18c83b9fffdddf9e55c807dc7d5784cc6d7ae90a57c29b87d707f0656964", - "dist/2024-04-29/rust-std-beta-x86_64-pc-windows-gnu.tar.gz": "28921ee14426f54aa09523547516437130654b2d9814120d286f209666c88533", - "dist/2024-04-29/rust-std-beta-x86_64-pc-windows-gnu.tar.xz": "7c3125cce30978ca2619e9aab150cb5b9b2535fbb6274d4ac1b1d4342c7b0220", - "dist/2024-04-29/rust-std-beta-x86_64-pc-windows-gnullvm.tar.gz": "ee5c237f092f8a4ba797c4c7769dfd4da81b5c86d2f4b88704d127642d222a22", - "dist/2024-04-29/rust-std-beta-x86_64-pc-windows-gnullvm.tar.xz": "30c84b04bd2d4d33abf1875cfee5f227ef6484edc67b3cc4c9c96d92c8406d6f", - "dist/2024-04-29/rust-std-beta-x86_64-pc-windows-msvc.tar.gz": "81274050e72c5a8ffdead83f7be62434f35a65517a1b3c6f7d9d14d0d59da710", - "dist/2024-04-29/rust-std-beta-x86_64-pc-windows-msvc.tar.xz": "215e20c78a2a4edf9b8368a29a09af5f4cf8d0edd1995de3bbf2eff01127cab7", - "dist/2024-04-29/rust-std-beta-x86_64-unknown-freebsd.tar.gz": "340131cba121827a9753e19cb3a4b9ba2ebe30569fb20d7f9300b4dbe2a15cf4", - "dist/2024-04-29/rust-std-beta-x86_64-unknown-freebsd.tar.xz": "69626178bc5309afc8a02c941bd77e70e1aa6917ffb6bf0d67a57d921b5c664a", - "dist/2024-04-29/rust-std-beta-x86_64-unknown-fuchsia.tar.gz": "22c6c90533dad3a731ad8a6696e6cdc1b15579e25c658fa2b094185e1893934f", - "dist/2024-04-29/rust-std-beta-x86_64-unknown-fuchsia.tar.xz": "30d7ef6684fa98e28037b69d4220cba40489c23e80fe7793c98b388dc161757d", - "dist/2024-04-29/rust-std-beta-x86_64-unknown-illumos.tar.gz": "9d7192d32eaa6b6ccb0f615da0f4cd80827ba6484eabeaf401d8217678f1e313", - "dist/2024-04-29/rust-std-beta-x86_64-unknown-illumos.tar.xz": "7a3fb35e0bb252d5f90773136d1417c26d5601beadb77d6da6f5ad3081977f07", - "dist/2024-04-29/rust-std-beta-x86_64-unknown-linux-gnu.tar.gz": "e987635519c1edc8a1d147ca4a86283637e4dbd0a49736b01d605e45a3a14e8f", - "dist/2024-04-29/rust-std-beta-x86_64-unknown-linux-gnu.tar.xz": "c3ab6b97dccc0038c68494b03b6d444d534e447226a2b2e140af54c94fca0b2d", - "dist/2024-04-29/rust-std-beta-x86_64-unknown-linux-gnux32.tar.gz": "72e8113687be8f947c50befb42b0957dd564f01693cf4d68d749a9e074032ada", - "dist/2024-04-29/rust-std-beta-x86_64-unknown-linux-gnux32.tar.xz": "867b24f33b19f40727c71818c8a002718d44d4cd4ceca44314331e19c1adc1a4", - "dist/2024-04-29/rust-std-beta-x86_64-unknown-linux-musl.tar.gz": "f9b0fd9605bd4e264f5303bd740d9a0195bc147132969965b221f9da0d7875bf", - "dist/2024-04-29/rust-std-beta-x86_64-unknown-linux-musl.tar.xz": "022dcf4887df41d776ba2666858b9aaab479758134a71f7c6b2172ed7c1a1752", - "dist/2024-04-29/rust-std-beta-x86_64-unknown-linux-ohos.tar.gz": "b5ff4a0ecd7e0f71a9557b6096bb907e5cbc8982431f0d9b01d8e1a895d8b37e", - "dist/2024-04-29/rust-std-beta-x86_64-unknown-linux-ohos.tar.xz": "e40d5bfb46aadf6faf849df548154db3f35f356f8b98037a056802a235922b8a", - "dist/2024-04-29/rust-std-beta-x86_64-unknown-netbsd.tar.gz": "57cfb1fa472dd9c01fc0caf605a55b7248375d616acf84ec12f6430d5e07e2ee", - "dist/2024-04-29/rust-std-beta-x86_64-unknown-netbsd.tar.xz": "e4121f060b917c811d971e85ce02495e83150ddcceb2204615edff24bd55bfa6", - "dist/2024-04-29/rust-std-beta-x86_64-unknown-none.tar.gz": "d63559803c8eb47e0d10d9f3a2284477b570a2536bb541762774271451e1f0ce", - "dist/2024-04-29/rust-std-beta-x86_64-unknown-none.tar.xz": "5388cf8ecaa234d507e505e8c6d433c5de8811b2717aa254e4caac9f4aa6cd97", - "dist/2024-04-29/rust-std-beta-x86_64-unknown-redox.tar.gz": "0f027163f37618df4330ecd82afece432b0a509ab20333d7b787c0d139ea89c2", - "dist/2024-04-29/rust-std-beta-x86_64-unknown-redox.tar.xz": "b1c722e894b145c2183183fa58762c64402fac077419dc7874f8b08eee665651", - "dist/2024-04-29/rust-std-beta-x86_64-unknown-uefi.tar.gz": "24e2ac0d44619ef9b76cb1af6178103d65ab12e2677b366e8aee0604798fe5f1", - "dist/2024-04-29/rust-std-beta-x86_64-unknown-uefi.tar.xz": "1d8a45f1bfe6650edc5ddfc8683190eff5a74384abcb2f73eb3d1e88d566ccfc", - "dist/2024-04-29/rustc-beta-aarch64-apple-darwin.tar.gz": "ea113c567692d54983ab6c376761651b6dcf9bedad5b5d822d28c0d0d0733cf2", - "dist/2024-04-29/rustc-beta-aarch64-apple-darwin.tar.xz": "e36363f1ea531d2fd563f471758e387de37a34e7ef6f4c12175979657333c5b4", - "dist/2024-04-29/rustc-beta-aarch64-pc-windows-msvc.tar.gz": "52d77d540fc3f83d82f35f358ccd9055fb75453af3e3bee4b11636742559db13", - "dist/2024-04-29/rustc-beta-aarch64-pc-windows-msvc.tar.xz": "843c56f5431c1feda85ceaeef0daf988e8ae020b3556326fb1f75ea7968bf2df", - "dist/2024-04-29/rustc-beta-aarch64-unknown-linux-gnu.tar.gz": "ba2fe37dda1a487a2c75151895f4f6e886e9476a992272ce26e9b5fd7adb11f9", - "dist/2024-04-29/rustc-beta-aarch64-unknown-linux-gnu.tar.xz": "ccb7be3935de1920509d2061d38f92f1fb8d2a5dd6cef392492242a929363fa9", - "dist/2024-04-29/rustc-beta-aarch64-unknown-linux-musl.tar.gz": "40636e0936bd311803317825c5fb6b446cdb5536ada1db097b567df04a86d7dd", - "dist/2024-04-29/rustc-beta-aarch64-unknown-linux-musl.tar.xz": "804ef68f24bc0ba5150177d8b8515daa54aa82fcb61472385ef1a1d897c5c3e1", - "dist/2024-04-29/rustc-beta-arm-unknown-linux-gnueabi.tar.gz": "a320c2869d1d2c92b698397d4467c8498cad9481f38d28ac810bd165399ca46b", - "dist/2024-04-29/rustc-beta-arm-unknown-linux-gnueabi.tar.xz": "7ce92211d87068d9c223806929adc34ca611a1321cd58b5bd81aabb0ec3ff085", - "dist/2024-04-29/rustc-beta-arm-unknown-linux-gnueabihf.tar.gz": "79c16b902884301882d16be36fe75ecb32a8e49abde0038ce21cfbee883c2c3a", - "dist/2024-04-29/rustc-beta-arm-unknown-linux-gnueabihf.tar.xz": "9384eb9bdbb585b414b6c04c592a79e90a0c0ebfeeb970e5e1b920cb638807cc", - "dist/2024-04-29/rustc-beta-armv7-unknown-linux-gnueabihf.tar.gz": "ff99de5b819a4fb9adce9386a309b9841bd33632eb7d5079415a6ca6fc86b9dd", - "dist/2024-04-29/rustc-beta-armv7-unknown-linux-gnueabihf.tar.xz": "55635cde13af11dd8cc007d2e0499bfee493bdfba87b6efd7b1fa4115f5728dc", - "dist/2024-04-29/rustc-beta-i686-pc-windows-gnu.tar.gz": "de82ac745275f069225b84574ed145afaf9f54abde5246592e49d5d1cf40cac1", - "dist/2024-04-29/rustc-beta-i686-pc-windows-gnu.tar.xz": "a8a7bf64d33c95a2f94265fba8dd9ac50bbb727f4bc3e79be5bf61212cb5d22b", - "dist/2024-04-29/rustc-beta-i686-pc-windows-msvc.tar.gz": "88967a99c993d6e0c3c7948308510644286ac826266dbd3d89aaa083100711db", - "dist/2024-04-29/rustc-beta-i686-pc-windows-msvc.tar.xz": "1804f75786482946258ff0e827274357c49e90a7f2f568add7353249f2ab78b9", - "dist/2024-04-29/rustc-beta-i686-unknown-linux-gnu.tar.gz": "3cb7e02c61d4a21d8289289b874b25e8b020c1d553e5af950160bffc14f51c18", - "dist/2024-04-29/rustc-beta-i686-unknown-linux-gnu.tar.xz": "2ad4b1311a0e39c359798375912faa91b4e13cd473bd59efd1e4f721777d254f", - "dist/2024-04-29/rustc-beta-loongarch64-unknown-linux-gnu.tar.gz": "ab19efb741a127615b9022dedf1d895b53c69740cc3da745f9b9888bade9d98b", - "dist/2024-04-29/rustc-beta-loongarch64-unknown-linux-gnu.tar.xz": "492cc11d54df410c2547890803930fc65950e6b81ced512e24bef56c3e70f3d2", - "dist/2024-04-29/rustc-beta-powerpc-unknown-linux-gnu.tar.gz": "c5a631a41f417336f3f65c85adefd1fb0bacc02465485f37d29fc1223c9f6cec", - "dist/2024-04-29/rustc-beta-powerpc-unknown-linux-gnu.tar.xz": "0701183b615d9eec9daea724d4cd8fa98dede2260cfb6b137d6cbf8ad6b29a4f", - "dist/2024-04-29/rustc-beta-powerpc64-unknown-linux-gnu.tar.gz": "cb70e92d5275862b500614d79eaea3d19319b96798f4850cb19dea9a8038a651", - "dist/2024-04-29/rustc-beta-powerpc64-unknown-linux-gnu.tar.xz": "908cbe562d82cca1bf176fdc99af867966ea423d244c4a50e14bad19f6878201", - "dist/2024-04-29/rustc-beta-powerpc64le-unknown-linux-gnu.tar.gz": "8580a3eb6d6df1774f4b6ca06dc1195c42b1e2a463488a5d851e99b0ca6d0249", - "dist/2024-04-29/rustc-beta-powerpc64le-unknown-linux-gnu.tar.xz": "2627948036e905f2e280663c56c86c172e2b0d057311ade7ca238953b7e0c36a", - "dist/2024-04-29/rustc-beta-riscv64gc-unknown-linux-gnu.tar.gz": "526e4f129fdb4b2c8f4317c57105a09ff03e71771d6d6bbbc9380917b5440d71", - "dist/2024-04-29/rustc-beta-riscv64gc-unknown-linux-gnu.tar.xz": "fd9dcf60838376478d7cc505ec7fc39f86f9d042646a3b836e9c06825927c7eb", - "dist/2024-04-29/rustc-beta-s390x-unknown-linux-gnu.tar.gz": "664c1255a9435d1ad086329a3c215974b9302d481762240cc9d0328d9f1b8c9a", - "dist/2024-04-29/rustc-beta-s390x-unknown-linux-gnu.tar.xz": "a585ce7684e4174f03adb09df17221e1729e8179dbc91b9a0f8813c3ecc0822d", - "dist/2024-04-29/rustc-beta-x86_64-apple-darwin.tar.gz": "59a1d91009b506a5bce3c276993cb8acfd71f73d01f9eaf4195b36114ac822c3", - "dist/2024-04-29/rustc-beta-x86_64-apple-darwin.tar.xz": "f86f3309cf2784b076f14e7da9e921c294a7701ea92d378c609061deccbc6bff", - "dist/2024-04-29/rustc-beta-x86_64-pc-windows-gnu.tar.gz": "f5c074461409b33a9791325d4014e6861ad36f99b9e48e54ecceb73986450be1", - "dist/2024-04-29/rustc-beta-x86_64-pc-windows-gnu.tar.xz": "045431eec6f839b1c40b5a75c5000f80bd6351274a59b29d962833495324ecb6", - "dist/2024-04-29/rustc-beta-x86_64-pc-windows-msvc.tar.gz": "a3abfb68e60544170f47209bbf048f1374e5bb75901a529e2ac2f315758155f8", - "dist/2024-04-29/rustc-beta-x86_64-pc-windows-msvc.tar.xz": "398c41a3219781c7cf1a907406506526b672abca6d3ab59c30556390a5f992c9", - "dist/2024-04-29/rustc-beta-x86_64-unknown-freebsd.tar.gz": "38895e615efd0bf75ca14b0ab0a085527cca64fae17631d1780a8f51acd26d17", - "dist/2024-04-29/rustc-beta-x86_64-unknown-freebsd.tar.xz": "786f40030dbe5e6897aafe4bda44770920b2010b93fc5ce86574774e531e2eff", - "dist/2024-04-29/rustc-beta-x86_64-unknown-illumos.tar.gz": "7003cab7650dae7e3d29032422a57782a2c146024c437a6466ae1dd2b61a6618", - "dist/2024-04-29/rustc-beta-x86_64-unknown-illumos.tar.xz": "bed3cc10203e8bd4d43b6245928c8a607acc5b6e633635caea45eb4eef4bda56", - "dist/2024-04-29/rustc-beta-x86_64-unknown-linux-gnu.tar.gz": "84cdea91c9f1e848ea17f554229ca80d18d093fc609641d8f003c4f2d4871866", - "dist/2024-04-29/rustc-beta-x86_64-unknown-linux-gnu.tar.xz": "a20fce7512f7c8cc6230a0f63f12855b04370d25e621183f71aa444c90c36b4b", - "dist/2024-04-29/rustc-beta-x86_64-unknown-linux-musl.tar.gz": "87e0c484ade99efab57c655ef96dbabf7a02314540575b65a14372ab5496c36c", - "dist/2024-04-29/rustc-beta-x86_64-unknown-linux-musl.tar.xz": "469757d8f35c9f4210aefd2ba660ee249e4409d47b908a6c68c1e650ee81ae67", - "dist/2024-04-29/rustc-beta-x86_64-unknown-netbsd.tar.gz": "4a38000480fe78fd5da7f9b71d36f296a6ae103254d932c4de6b902354e86bbf", - "dist/2024-04-29/rustc-beta-x86_64-unknown-netbsd.tar.xz": "45945d6af237fe4c91fde7db02ca19e99bac56a911b8db79be9b6ab8bb3934e1", - "dist/2024-04-29/rustc-nightly-aarch64-apple-darwin.tar.gz": "0b07375a9a6507fd4932a05b5aaf28ed349fe2040103f1cb69c8a2494437258f", - "dist/2024-04-29/rustc-nightly-aarch64-apple-darwin.tar.xz": "143bd7ed3ca7b913ddd0cea7cda8d1a0e4c29cc2ccbb7d29f0e45c2a87c3ec46", - "dist/2024-04-29/rustc-nightly-aarch64-pc-windows-msvc.tar.gz": "9404c111b91fd092367b88adbc37dce10a98c443bd8d9e13a860e1fb4e3af96e", - "dist/2024-04-29/rustc-nightly-aarch64-pc-windows-msvc.tar.xz": "f9f432907c276edcae5ad8ade0264f3c03109be02e791a814edc8ad3d229637a", - "dist/2024-04-29/rustc-nightly-aarch64-unknown-linux-gnu.tar.gz": "33425c90427424f0b30fa2a6331a3b59c680f1c1bd0d8845d7e6bc1e2f80292d", - "dist/2024-04-29/rustc-nightly-aarch64-unknown-linux-gnu.tar.xz": "03792890c64c72f30143849894b15f0eb3d6ad735fceede9092abd900ee733e4", - "dist/2024-04-29/rustc-nightly-aarch64-unknown-linux-musl.tar.gz": "cf6f2bffa0db1b4b9b8e95801bf415dcce413f902e26f4c1831dff1a00752b99", - "dist/2024-04-29/rustc-nightly-aarch64-unknown-linux-musl.tar.xz": "9192fdb668df8d4cab776623db7d01e35af42fea94098c1d4ba53190825d81a8", - "dist/2024-04-29/rustc-nightly-arm-unknown-linux-gnueabi.tar.gz": "a174e7e08da2abc6b84499360670188f5cc61b6d055967e04bf602ff3d831f45", - "dist/2024-04-29/rustc-nightly-arm-unknown-linux-gnueabi.tar.xz": "5a59811027586863852b15fc2b603e7e69b19841f4c10d2527ef1fc5b77d8af2", - "dist/2024-04-29/rustc-nightly-arm-unknown-linux-gnueabihf.tar.gz": "645bb5dd7a96bb9292b9956cb9705e9aed2408e47728f245564f1f7404ede783", - "dist/2024-04-29/rustc-nightly-arm-unknown-linux-gnueabihf.tar.xz": "1fe34911b082c3a5ca4f24656675c095d2cf56f8005be9ca2517d0ef7d0a2b37", - "dist/2024-04-29/rustc-nightly-armv7-unknown-linux-gnueabihf.tar.gz": "f2d6403d81bb0afe2e14956828987a0bb044c95f2d9566e1d792dd922dad7914", - "dist/2024-04-29/rustc-nightly-armv7-unknown-linux-gnueabihf.tar.xz": "d93fdafcbbfd50c88c3f4feb4c68b053882ccae02c45e1615aeeae5a86f4aa98", - "dist/2024-04-29/rustc-nightly-i686-pc-windows-gnu.tar.gz": "a9e997b03559b3dfa2a0eba6ed7a142d7651ea7f4ba4e788d9de807b50558e58", - "dist/2024-04-29/rustc-nightly-i686-pc-windows-gnu.tar.xz": "4412b5fbfab8c5b31e57cf8c4ce9a9d13cfc9c0a8174ea1fc8a7c05281e1cb54", - "dist/2024-04-29/rustc-nightly-i686-pc-windows-msvc.tar.gz": "1725c41500dbf6bea554f3d4acaba70167f0e89087aaa3eb3c0f8a99047c55c4", - "dist/2024-04-29/rustc-nightly-i686-pc-windows-msvc.tar.xz": "27db022494afebbe05605f134191e8b2e78bfdeaa638d4215174038ca9dd2fd7", - "dist/2024-04-29/rustc-nightly-i686-unknown-linux-gnu.tar.gz": "dc1a05d49b773dba06808c1c50653ecac506b3433f0f6dfa307109a7c621cc1a", - "dist/2024-04-29/rustc-nightly-i686-unknown-linux-gnu.tar.xz": "cc58ce3af8f5481ada4dc129079cd558664717526b2f7f9a02bde6bafb6f45ad", - "dist/2024-04-29/rustc-nightly-loongarch64-unknown-linux-gnu.tar.gz": "34cfe803126ae9218b17adfe833a55c697dfa50729ac83b642529f3682d12d15", - "dist/2024-04-29/rustc-nightly-loongarch64-unknown-linux-gnu.tar.xz": "c752dc8962656c09047151fd24166f3134fbeed85006b5d22496691079c7fb9c", - "dist/2024-04-29/rustc-nightly-powerpc-unknown-linux-gnu.tar.gz": "386b086b8aad922050c813dd58bb79a52ef806b2d1413e2e9cc46d6e43b81d7c", - "dist/2024-04-29/rustc-nightly-powerpc-unknown-linux-gnu.tar.xz": "d9eec9ab7c265444ac5f04d4ec9e77d4c0c3c2e34c5804db8abf5f94c8fd2272", - "dist/2024-04-29/rustc-nightly-powerpc64-unknown-linux-gnu.tar.gz": "91df129046443554bfb836d25886aa9807b917acbc9dcf30f6531cde7bf912fa", - "dist/2024-04-29/rustc-nightly-powerpc64-unknown-linux-gnu.tar.xz": "ca9b574b9f2e914b5a6d9e011aba805d1e6f9b687dc1a1868e88f0e4d9e4401c", - "dist/2024-04-29/rustc-nightly-powerpc64le-unknown-linux-gnu.tar.gz": "8b44f96a1ccd6d501b0af3960edb2c1a6c93957676a1c2cdb831e614de398f8b", - "dist/2024-04-29/rustc-nightly-powerpc64le-unknown-linux-gnu.tar.xz": "f8a10a6767b80bf24f73223b9e46e1b18b6bf6746ad2115eb8968a0e482f0e4e", - "dist/2024-04-29/rustc-nightly-riscv64gc-unknown-linux-gnu.tar.gz": "a197208807503a9cfbc6df938d614a192da48884b2e4892f7b1d234579091be1", - "dist/2024-04-29/rustc-nightly-riscv64gc-unknown-linux-gnu.tar.xz": "af3a1a33942bd8a3417593dc118abb1db0373f5410f54771713c05bb86724fed", - "dist/2024-04-29/rustc-nightly-s390x-unknown-linux-gnu.tar.gz": "5a3a3aa73b6a0f21c63b9a40bdbd0bb4dc59bd75add0a06e292ced791fad31be", - "dist/2024-04-29/rustc-nightly-s390x-unknown-linux-gnu.tar.xz": "6d7903f1c9fc95a23448717326d667dce59e54aaff821443d3cd9137cf3537fb", - "dist/2024-04-29/rustc-nightly-x86_64-apple-darwin.tar.gz": "64eede54da4bf88b0a42ecf7f7a4bf8002b5550e60a64e1e48244c7f5b04768c", - "dist/2024-04-29/rustc-nightly-x86_64-apple-darwin.tar.xz": "0a8f95e3bb0bebf9bcc8116b91bab3ba97cb6ff4021713586280aaceed9da030", - "dist/2024-04-29/rustc-nightly-x86_64-pc-windows-gnu.tar.gz": "58f9e0dd9c1aadde2dfd869528adadd4acc29ab0850236f3cee5f023d4211939", - "dist/2024-04-29/rustc-nightly-x86_64-pc-windows-gnu.tar.xz": "a211a962093e0d09358d51a6eb48da0966a02383c6b00c8acc077b5663d7d707", - "dist/2024-04-29/rustc-nightly-x86_64-pc-windows-msvc.tar.gz": "5631926874dc54204c319137a77a89de5e6f408de2a832109e2be71ea79f27d1", - "dist/2024-04-29/rustc-nightly-x86_64-pc-windows-msvc.tar.xz": "a8cf87bc663b5e3dbcc97b0eb58bb1b9b5b0100aacb47dc0c372fe1612517244", - "dist/2024-04-29/rustc-nightly-x86_64-unknown-freebsd.tar.gz": "1011f98197a9fe82d6095f4521934a06eea5f7e9719a6e4c9e3bf13d68f799ca", - "dist/2024-04-29/rustc-nightly-x86_64-unknown-freebsd.tar.xz": "79599b3f91f9372262e97a417f4e104ef5192c0f6f8df204aea9c8b3ee39430e", - "dist/2024-04-29/rustc-nightly-x86_64-unknown-illumos.tar.gz": "7179a453bdcb17e401c0af8f4ab86cb5a4752a8ec80b0cbdd4cf1854c7f36a35", - "dist/2024-04-29/rustc-nightly-x86_64-unknown-illumos.tar.xz": "d565fc366fdbc305fbfe59e72b971c58f201d69e03a9ffa667d2ca0735cdb7f3", - "dist/2024-04-29/rustc-nightly-x86_64-unknown-linux-gnu.tar.gz": "ae6bd8e20560d48519290d78e3d21f84b983403ca1f8f466a85496276d7866da", - "dist/2024-04-29/rustc-nightly-x86_64-unknown-linux-gnu.tar.xz": "c7c0f8f44b0275456a27952178caa04c32eb9a1507056ddc05926a0730e17359", - "dist/2024-04-29/rustc-nightly-x86_64-unknown-linux-musl.tar.gz": "3246797ddbc9118de819b13b005b83748338f3c825a7436ebd5aa79ca55539c0", - "dist/2024-04-29/rustc-nightly-x86_64-unknown-linux-musl.tar.xz": "c7e784e77dbabedad88d24d2ae6dc4abb68bc04b1cd6c9d45f6dc28b6d0e2edc", - "dist/2024-04-29/rustc-nightly-x86_64-unknown-netbsd.tar.gz": "c9452de4b3f15f0cf0b7d737b217b2cc7b88a96543bd8ce587ee14be1e21a90a", - "dist/2024-04-29/rustc-nightly-x86_64-unknown-netbsd.tar.xz": "de9b05278a5c69d53ccbb31223526ea2aa2275c0fb3f046d1c1b4d67c0b0c275", - "dist/2024-04-29/rustfmt-nightly-aarch64-apple-darwin.tar.gz": "3734353a58dbf6c3831cc6b4ea606357140c191c89e8dfca1d7aa2f3fb8ac53d", - "dist/2024-04-29/rustfmt-nightly-aarch64-apple-darwin.tar.xz": "e5e3a6e609fbfd537aa4acfefd3681d4b6c8029e2801a1ef23e8b09cf5a47bfe", - "dist/2024-04-29/rustfmt-nightly-aarch64-pc-windows-msvc.tar.gz": "22f54857e01d759301d099b67547cdc485596499088d0d749d38058c28e0f752", - "dist/2024-04-29/rustfmt-nightly-aarch64-pc-windows-msvc.tar.xz": "db48a9d45dc7c7aad4c9bb0d20789dd35fb6ef7a966948c44fbbae132de4c16b", - "dist/2024-04-29/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.gz": "fa5d1fb9f3627e7d59269a1f8008d780c685ea04975473f1808287134e7bc5a7", - "dist/2024-04-29/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.xz": "61ab625b47fa9097af90a79a1e75a2f2492a415f4009c9043cf453bd4128f031", - "dist/2024-04-29/rustfmt-nightly-aarch64-unknown-linux-musl.tar.gz": "cc79969341fc60991059d0e3f13a69489c1e0915ea5787a88b8605ed5b7f3cd0", - "dist/2024-04-29/rustfmt-nightly-aarch64-unknown-linux-musl.tar.xz": "bbdb75f922b4b1716b033d91c76c4c0aa53061d6e7fa53a9bf16fe076814bbb2", - "dist/2024-04-29/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.gz": "13ca68afc3f3970a37951504664b58035102e1ae06d10a744389603b2f7499f5", - "dist/2024-04-29/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.xz": "04b174aa724945b6359a555892506c6a742a7c427464e8206433bb3f9a65fc02", - "dist/2024-04-29/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.gz": "430333380a590a9de211c8d735989fedb89321cf9f5f9a0b1ef651ec8b598691", - "dist/2024-04-29/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.xz": "924713e648806945cd56e54d4c11dc74b65241c8dbf6cc7b401c5c93d0f7ffdb", - "dist/2024-04-29/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.gz": "bb6e5a8b5cc88099e613aa5f4d926165976d8e4a7fccbecf4ac3b0eb966d7a0f", - "dist/2024-04-29/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.xz": "34d5e970304e1734aacb26c095e926c27a07e1a41fe70db9fa2997bef97ad3ec", - "dist/2024-04-29/rustfmt-nightly-i686-pc-windows-gnu.tar.gz": "835447a1d9d60659e99903275f327641809fc0148f35149f980d1a17ff87cc9a", - "dist/2024-04-29/rustfmt-nightly-i686-pc-windows-gnu.tar.xz": "ddd84a7f900aa239f93711f7da71e57aaedeeba2c9c8a8f23608acc7e48613c0", - "dist/2024-04-29/rustfmt-nightly-i686-pc-windows-msvc.tar.gz": "02f0af2bdae167c6091099a9b54ceb150c22b0f20dc861587a02cac78deb0b39", - "dist/2024-04-29/rustfmt-nightly-i686-pc-windows-msvc.tar.xz": "822f78f39dcbe3282bf7888a8cdae04efe7b023ded026a7e7f430e4ff15e7942", - "dist/2024-04-29/rustfmt-nightly-i686-unknown-linux-gnu.tar.gz": "68a6189652c11a2c142c5339e2f5fb09d5f3e85d860bff063f62d5d3a3d111bf", - "dist/2024-04-29/rustfmt-nightly-i686-unknown-linux-gnu.tar.xz": "6740ea882effa2fb87dd72744c08888ce5ec59c9797c00369156b24847bb180e", - "dist/2024-04-29/rustfmt-nightly-loongarch64-unknown-linux-gnu.tar.gz": "0bb365e2d895ef3c39c4899a01187a23f9b7c5195c30bf845da3917f62f5eafd", - "dist/2024-04-29/rustfmt-nightly-loongarch64-unknown-linux-gnu.tar.xz": "2e54c9887bc6ed1eb09b9f69c8425da843ea12bf33248fa0ccdc0d14387c1c57", - "dist/2024-04-29/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.gz": "b0c0fe437921d17e2f50cbff87beeac067efa3d5211a241fb6f4c10b8ab500ac", - "dist/2024-04-29/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.xz": "64e7282c0cf4a714b11eed1d28be3a64ba0ccc6d899211a872a5a7809d514c08", - "dist/2024-04-29/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.gz": "100cfde057c81460b8cfde2047fe83ddde360a6df1ff178da5a968b17ecc9df8", - "dist/2024-04-29/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.xz": "38e8712e98fa0bc6962ab2fd2e3b96a2a5dcaa6c16161d8caf71131a1ca5031e", - "dist/2024-04-29/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.gz": "4dab52b50e19348fb39fdad39ab44189c27c10f80b5fbe2cc4723b644611fa87", - "dist/2024-04-29/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.xz": "36d1b2c9150fafc5976c296200ba3fac3e923df3e6f18032068200e2a887146c", - "dist/2024-04-29/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.gz": "7cb4a536320c23d305ce3bd3b7a954d951bf4d358ef3732be75b9b290c4818a5", - "dist/2024-04-29/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.xz": "ede1afc7dc5892ef6f780e987737e145c4b4d00495da8c2e9902182a3a174e20", - "dist/2024-04-29/rustfmt-nightly-s390x-unknown-linux-gnu.tar.gz": "e2d2d561cbfa0add0e5349682976216d3a7cff4094372c1ed26854bb4e4d93fd", - "dist/2024-04-29/rustfmt-nightly-s390x-unknown-linux-gnu.tar.xz": "e0380e65e83e4131f6aa7ee4e185689add4372b0c1653312e2ffd56072fdd0fe", - "dist/2024-04-29/rustfmt-nightly-x86_64-apple-darwin.tar.gz": "73a140c7ed9c80f209ff976c63b0a34d625d651553c38692c91f048f4e0ae470", - "dist/2024-04-29/rustfmt-nightly-x86_64-apple-darwin.tar.xz": "9946b7120465181e05916b8023bc075b32bd85cf45a3b1d8bfba2f94ac78d927", - "dist/2024-04-29/rustfmt-nightly-x86_64-pc-windows-gnu.tar.gz": "eda273f27714b1e45adcc2388149f48de0e32a9104db0b9d1a02f6d37de43fef", - "dist/2024-04-29/rustfmt-nightly-x86_64-pc-windows-gnu.tar.xz": "f2955a4b696d050c219a96c093162b42a2fab921f9f3cb7570f8462928306c6d", - "dist/2024-04-29/rustfmt-nightly-x86_64-pc-windows-msvc.tar.gz": "ec900cc2d3c6d45ef039653f4418f9b9a4a5fddd5d7e8077c3fb08b36c539a28", - "dist/2024-04-29/rustfmt-nightly-x86_64-pc-windows-msvc.tar.xz": "04e6999a3405acc79f5fdcafeeab52880e5eeeedd3909b5f3c57e7647c86ef99", - "dist/2024-04-29/rustfmt-nightly-x86_64-unknown-freebsd.tar.gz": "0730c5ebd576fec5371085f9fac0adde9424e1d7626456ed33bc66351b0ad307", - "dist/2024-04-29/rustfmt-nightly-x86_64-unknown-freebsd.tar.xz": "90cbd84b8d48f0235a1954166f5edd53dc3031532ec6dfcb364f9a9624c9ce11", - "dist/2024-04-29/rustfmt-nightly-x86_64-unknown-illumos.tar.gz": "5f5c62d321db27eb495f6ea312ef8bea0bf17a7a501a44e062986c416951700f", - "dist/2024-04-29/rustfmt-nightly-x86_64-unknown-illumos.tar.xz": "a3bf64e2f22436e4484fc818f69d2f750fddd05a96463fd4abfcf655edce36b9", - "dist/2024-04-29/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.gz": "a847a6f9c7a3ce71c7cd8d81bdfcfcd8e4d128aa28ba0dafea89b0cc37c6c36c", - "dist/2024-04-29/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.xz": "21fa794456566c64d08f629a385f89b3cfe9d9b69f317ae85fbe7425419108ff", - "dist/2024-04-29/rustfmt-nightly-x86_64-unknown-linux-musl.tar.gz": "b3f792f10a98993b4b55d1df951727a4422102d51b1145e51824268d48587ad0", - "dist/2024-04-29/rustfmt-nightly-x86_64-unknown-linux-musl.tar.xz": "d791f0ec3c004e7baa0381962bf8ca2f18a3c861152702de5301d0149260e7fa", - "dist/2024-04-29/rustfmt-nightly-x86_64-unknown-netbsd.tar.gz": "9807b2887e976d29f0c04484f8459175b4f6b70ef000037cdc4dada48e3cbd74", - "dist/2024-04-29/rustfmt-nightly-x86_64-unknown-netbsd.tar.xz": "019920d64778af62879e2146c2c13d9f6e2165a38bbfa1982694bfb48864d308" - } -} diff --git a/triagebot.toml b/triagebot.toml index 499ba6e470cda..76b8e084b2419 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -302,7 +302,7 @@ trigger_files = [ "configure", "Cargo.toml", "config.example.toml", - "src/stage0.json", + "src/stage0", "src/tools/compiletest", "src/tools/tidy", "src/tools/rustdoc-gui-test", @@ -362,7 +362,7 @@ trigger_files = [ [autolabel."T-release"] trigger_files = [ "RELEASES.md", - "src/stage0.json", + "src/stage0", "src/version" ] @@ -1038,7 +1038,7 @@ project-exploit-mitigations = [ "/src/librustdoc" = ["rustdoc"] "/src/llvm-project" = ["@cuviper"] "/src/rustdoc-json-types" = ["rustdoc"] -"/src/stage0.json" = ["bootstrap"] +"/src/stage0" = ["bootstrap"] "/tests/run-make" = ["@jieyouxu"] "/tests/ui" = ["compiler"] "/src/tools/cargo" = ["@ehuss"] From 8c5375ad8e9e53334df1bdec10244589dfca109e Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Thu, 9 May 2024 19:08:04 +0300 Subject: [PATCH 066/179] move comments position in `src/stage0` Signed-off-by: onur-ozkan --- src/stage0 | 16 ++++++++-------- src/tools/bump-stage0/src/main.rs | 11 +++++++---- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/src/stage0 b/src/stage0 index ed06372741eb1..5ec8f5b715e07 100644 --- a/src/stage0 +++ b/src/stage0 @@ -1,3 +1,10 @@ +dist_server=https://static.rust-lang.org +artifacts_server=https://ci-artifacts.rust-lang.org/rustc-builds +artifacts_with_llvm_assertions_server=https://ci-artifacts.rust-lang.org/rustc-builds-alt +git_merge_commit_email=bors@rust-lang.org +git_repository=rust-lang/rust +nightly_branch=master + # The configuration above this comment is editable, and can be changed # by forks of the repository if they have alternate values. # @@ -6,14 +13,7 @@ # # All changes below this comment will be overridden the next time the # tool is executed. - -dist_server=https://static.rust-lang.org -artifacts_server=https://ci-artifacts.rust-lang.org/rustc-builds -artifacts_with_llvm_assertions_server=https://ci-artifacts.rust-lang.org/rustc-builds-alt -git_merge_commit_email=bors@rust-lang.org -git_repository=rust-lang/rust -nightly_branch=master - + compiler_date=2024-04-29 compiler_version=beta rustfmt_date=2024-04-29 diff --git a/src/tools/bump-stage0/src/main.rs b/src/tools/bump-stage0/src/main.rs index f9c1699eb4cea..bb06e113c0e94 100644 --- a/src/tools/bump-stage0/src/main.rs +++ b/src/tools/bump-stage0/src/main.rs @@ -43,7 +43,7 @@ impl Tool { } fn update_stage0_file(mut self) -> Result<(), Error> { - const HEADER: &str = r#"# The configuration above this comment is editable, and can be changed + const COMMENTS: &str = r#"# The configuration above this comment is editable, and can be changed # by forks of the repository if they have alternate values. # # The section below is generated by `./x.py run src/tools/bump-stage0`, @@ -53,8 +53,10 @@ impl Tool { # tool is executed. "#; - let mut file_content = HEADER.to_owned(); + let mut file_content = String::new(); + // Destructure `Stage0Config` here to ensure the stage0 file is synced with any new + // fields when they are added. let Stage0Config { dist_server, artifacts_server, @@ -64,7 +66,7 @@ impl Tool { nightly_branch, } = &self.config; - file_content.push_str(&format!("\ndist_server={}", dist_server)); + file_content.push_str(&format!("dist_server={}", dist_server)); file_content.push_str(&format!("\nartifacts_server={}", artifacts_server)); file_content.push_str(&format!( "\nartifacts_with_llvm_assertions_server={}", @@ -74,7 +76,8 @@ impl Tool { file_content.push_str(&format!("\ngit_repository={}", git_repository)); file_content.push_str(&format!("\nnightly_branch={}", nightly_branch)); - file_content.push_str("\n"); + file_content.push_str("\n\n"); + file_content.push_str(COMMENTS); let compiler = self.detect_compiler()?; file_content.push_str(&format!("\ncompiler_date={}", compiler.date)); From 1e232fea1b0e5bcf43230a8a28a24f9e2cbac988 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Mon, 6 May 2024 14:27:24 +0000 Subject: [PATCH 067/179] std::alloc: using posix_memalign instead of memalign on solarish. simpler code path since small alignments are already taking care of. close GH-124787 --- library/std/src/sys/pal/unix/alloc.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/library/std/src/sys/pal/unix/alloc.rs b/library/std/src/sys/pal/unix/alloc.rs index 9938c0bac25b0..993bf55edcf10 100644 --- a/library/std/src/sys/pal/unix/alloc.rs +++ b/library/std/src/sys/pal/unix/alloc.rs @@ -61,9 +61,7 @@ unsafe impl GlobalAlloc for System { cfg_if::cfg_if! { if #[cfg(any( target_os = "android", - target_os = "illumos", target_os = "redox", - target_os = "solaris", target_os = "espidf", target_os = "horizon", target_os = "vita", From 1cefaa7432f2b8ffe05d10889e2e6f9115e7c630 Mon Sep 17 00:00:00 2001 From: Joshua Liebow-Feeser Date: Sat, 11 May 2024 11:50:20 -0700 Subject: [PATCH 068/179] Relax slice safety requirements Per https://github.com/rust-lang/rust/pull/116677#issuecomment-1945495786, the language as written promises too much. This PR relaxes the language to be consistent with current semantics. If and when #117945 is implemented, we can revert to the old language. --- library/core/src/primitive_docs.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/primitive_docs.rs b/library/core/src/primitive_docs.rs index d8597369b9bfd..331067b8975ca 100644 --- a/library/core/src/primitive_docs.rs +++ b/library/core/src/primitive_docs.rs @@ -1468,7 +1468,7 @@ mod prim_usize {} /// boundary, the following invariants must generally be upheld: /// /// * `t` is aligned to `align_of_val(t)` -/// * `t` is dereferenceable for `size_of_val(t)` many bytes +/// * if `size_of_val(t) > 0`, then `t` is dereferenceable for `size_of_val(t)` many bytes /// /// If `t` points at address `a`, being "dereferenceable" for N bytes means that the memory range /// `[a, a + N)` is all contained within a single [allocated object]. From a167142946224a81ad4cdae45795a75474572fce Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sat, 11 May 2024 18:51:59 +0000 Subject: [PATCH 069/179] Translate MIR to clif ir in parallel with parallel rustc On dev-desktop the advantage of cg_clif over cg_llvm on simple-raytracer is 15% when parallel rustc is disabled. With -Zthreads=16 the advantage goes from 5% to 22% with this change. --- src/concurrency_limiter.rs | 8 +++--- src/driver/aot.rs | 56 +++++++++++++++++++------------------- 2 files changed, 32 insertions(+), 32 deletions(-) diff --git a/src/concurrency_limiter.rs b/src/concurrency_limiter.rs index c7f543cf7cd2c..a73860cf18b2d 100644 --- a/src/concurrency_limiter.rs +++ b/src/concurrency_limiter.rs @@ -6,7 +6,7 @@ use rustc_session::Session; // FIXME don't panic when a worker thread panics pub(super) struct ConcurrencyLimiter { - helper_thread: Option, + helper_thread: Option>, state: Arc>, available_token_condvar: Arc, finished: bool, @@ -39,14 +39,14 @@ impl ConcurrencyLimiter { }) .unwrap(); ConcurrencyLimiter { - helper_thread: Some(helper_thread), + helper_thread: Some(Mutex::new(helper_thread)), state, available_token_condvar, finished: false, } } - pub(super) fn acquire(&mut self, dcx: &rustc_errors::DiagCtxt) -> ConcurrencyLimiterToken { + pub(super) fn acquire(&self, dcx: &rustc_errors::DiagCtxt) -> ConcurrencyLimiterToken { let mut state = self.state.lock().unwrap(); loop { state.assert_invariants(); @@ -73,7 +73,7 @@ impl ConcurrencyLimiter { } } - self.helper_thread.as_mut().unwrap().request_token(); + self.helper_thread.as_ref().unwrap().lock().unwrap().request_token(); state = self.available_token_condvar.wait(state).unwrap(); } } diff --git a/src/driver/aot.rs b/src/driver/aot.rs index 2466cbed29925..2651e56cac45f 100644 --- a/src/driver/aot.rs +++ b/src/driver/aot.rs @@ -15,6 +15,7 @@ use rustc_codegen_ssa::errors as ssa_errors; use rustc_codegen_ssa::{CodegenResults, CompiledModule, CrateInfo, ModuleKind}; use rustc_data_structures::profiling::SelfProfilerRef; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; +use rustc_data_structures::sync::{par_map, IntoDynSyncSend}; use rustc_metadata::fs::copy_to_stdout; use rustc_metadata::EncodedMetadata; use rustc_middle::dep_graph::{WorkProduct, WorkProductId}; @@ -611,34 +612,33 @@ pub(crate) fn run_aot( CguReuse::PreLto | CguReuse::PostLto => false, }); - let mut concurrency_limiter = ConcurrencyLimiter::new(tcx.sess, todo_cgus.len()); - - let modules = - tcx.sess.time("codegen mono items", || { - todo_cgus - .into_iter() - .map(|(_, cgu)| { - let dep_node = cgu.codegen_dep_node(tcx); - tcx.dep_graph - .with_task( - dep_node, - tcx, - ( - backend_config.clone(), - global_asm_config.clone(), - cgu.name(), - concurrency_limiter.acquire(tcx.dcx()), - ), - module_codegen, - Some(rustc_middle::dep_graph::hash_result), - ) - .0 - }) - .chain(done_cgus.into_iter().map(|(_, cgu)| { - OngoingModuleCodegen::Sync(reuse_workproduct_for_cgu(tcx, cgu)) - })) - .collect::>() + let concurrency_limiter = IntoDynSyncSend(ConcurrencyLimiter::new(tcx.sess, todo_cgus.len())); + + let modules = tcx.sess.time("codegen mono items", || { + let mut modules: Vec<_> = par_map(todo_cgus, |(_, cgu)| { + let dep_node = cgu.codegen_dep_node(tcx); + tcx.dep_graph + .with_task( + dep_node, + tcx, + ( + backend_config.clone(), + global_asm_config.clone(), + cgu.name(), + concurrency_limiter.acquire(tcx.dcx()), + ), + module_codegen, + Some(rustc_middle::dep_graph::hash_result), + ) + .0 }); + modules.extend( + done_cgus + .into_iter() + .map(|(_, cgu)| OngoingModuleCodegen::Sync(reuse_workproduct_for_cgu(tcx, cgu))), + ); + modules + }); let mut allocator_module = make_module(tcx.sess, &backend_config, "allocator_shim".to_string()); let mut allocator_unwind_context = UnwindContext::new(allocator_module.isa(), true); @@ -706,6 +706,6 @@ pub(crate) fn run_aot( metadata_module, metadata, crate_info: CrateInfo::new(tcx, target_cpu), - concurrency_limiter, + concurrency_limiter: concurrency_limiter.0, }) } From 15df3d78e47466e651510d93ee36c0852ac4374e Mon Sep 17 00:00:00 2001 From: Joshua Liebow-Feeser Date: Sat, 11 May 2024 12:08:19 -0700 Subject: [PATCH 070/179] References must also be non-null --- library/core/src/primitive_docs.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/library/core/src/primitive_docs.rs b/library/core/src/primitive_docs.rs index 331067b8975ca..8283fdc459be1 100644 --- a/library/core/src/primitive_docs.rs +++ b/library/core/src/primitive_docs.rs @@ -1467,6 +1467,7 @@ mod prim_usize {} /// For all types, `T: ?Sized`, and for all `t: &T` or `t: &mut T`, when such values cross an API /// boundary, the following invariants must generally be upheld: /// +/// * `t` is non-null /// * `t` is aligned to `align_of_val(t)` /// * if `size_of_val(t) > 0`, then `t` is dereferenceable for `size_of_val(t)` many bytes /// From 23e965eb68f5e903cbcb3bf86ca3431e4c272586 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 11 May 2024 20:31:07 +0200 Subject: [PATCH 071/179] Add `crate_type` method to `Rustdoc` --- src/tools/run-make-support/src/rustdoc.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/tools/run-make-support/src/rustdoc.rs b/src/tools/run-make-support/src/rustdoc.rs index aa3c7dcf0e356..dcd5b5a93e1fa 100644 --- a/src/tools/run-make-support/src/rustdoc.rs +++ b/src/tools/run-make-support/src/rustdoc.rs @@ -107,6 +107,13 @@ impl Rustdoc { self } + /// Specify the crate type. + pub fn crate_type(&mut self, crate_type: &str) -> &mut Self { + self.cmd.arg("--crate-type"); + self.cmd.arg(crate_type); + self + } + #[track_caller] pub fn run_fail_assert_exit_code(&mut self, code: i32) -> Output { let caller_location = std::panic::Location::caller(); From 4a00debfefda0ea72735252e098bd303df6a3ff3 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 11 May 2024 20:32:19 +0200 Subject: [PATCH 072/179] Add `crate_name` method to `Rustdoc` and `Rustc` --- src/tools/run-make-support/src/rustc.rs | 7 +++++++ src/tools/run-make-support/src/rustdoc.rs | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/src/tools/run-make-support/src/rustc.rs b/src/tools/run-make-support/src/rustc.rs index de773d688ef00..852353575a983 100644 --- a/src/tools/run-make-support/src/rustc.rs +++ b/src/tools/run-make-support/src/rustc.rs @@ -176,6 +176,13 @@ impl Rustc { self } + /// Specify the crate name. + pub fn crate_name(&mut self, name: &str) -> &mut Self { + self.cmd.arg("--crate-name"); + self.cmd.arg(name); + self + } + /// Get the [`Output`][::std::process::Output] of the finished process. #[track_caller] pub fn command_output(&mut self) -> ::std::process::Output { diff --git a/src/tools/run-make-support/src/rustdoc.rs b/src/tools/run-make-support/src/rustdoc.rs index dcd5b5a93e1fa..df91742f4e29d 100644 --- a/src/tools/run-make-support/src/rustdoc.rs +++ b/src/tools/run-make-support/src/rustdoc.rs @@ -114,6 +114,13 @@ impl Rustdoc { self } + /// Specify the crate name. + pub fn crate_name(&mut self, name: &str) -> &mut Self { + self.cmd.arg("--crate-name"); + self.cmd.arg(name); + self + } + #[track_caller] pub fn run_fail_assert_exit_code(&mut self, code: i32) -> Output { let caller_location = std::panic::Location::caller(); From 0761802e50e3f11ef4cc170f63659f895bc25d42 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 11 May 2024 20:51:18 +0200 Subject: [PATCH 073/179] Add `python_command` and `source_path` functions --- src/tools/run-make-support/src/lib.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/tools/run-make-support/src/lib.rs b/src/tools/run-make-support/src/lib.rs index 9888ca2d1ed95..cc81d23a8ff01 100644 --- a/src/tools/run-make-support/src/lib.rs +++ b/src/tools/run-make-support/src/lib.rs @@ -54,6 +54,15 @@ pub fn static_lib(name: &str) -> PathBuf { tmp_dir().join(static_lib_name(name)) } +pub fn python_command() -> Command { + let python_path = std::env::var("PYTHON").expect("PYTHON environment variable does not exist"); + Command::new(python_path) +} + +pub fn source_path() -> PathBuf { + std::env::var("S").expect("S variable does not exist").into() +} + /// Construct the static library name based on the platform. pub fn static_lib_name(name: &str) -> String { // See tools.mk (irrelevant lines omitted): From 0712ae865f6658c5c36b5ccf347309a03742441d Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 11 May 2024 20:52:10 +0200 Subject: [PATCH 074/179] Add `extern_` method to `Rustdoc` --- src/tools/run-make-support/src/rustdoc.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/tools/run-make-support/src/rustdoc.rs b/src/tools/run-make-support/src/rustdoc.rs index df91742f4e29d..6a65d9616fcc5 100644 --- a/src/tools/run-make-support/src/rustdoc.rs +++ b/src/tools/run-make-support/src/rustdoc.rs @@ -45,6 +45,21 @@ impl Rustdoc { Self { cmd, stdin: None } } + /// Specify where an external library is located. + pub fn extern_>(&mut self, crate_name: &str, path: P) -> &mut Self { + assert!( + !crate_name.contains(|c: char| c.is_whitespace() || c == '\\' || c == '/'), + "crate name cannot contain whitespace or path separators" + ); + + let path = path.as_ref().to_string_lossy(); + + self.cmd.arg("--extern"); + self.cmd.arg(format!("{crate_name}={path}")); + + self + } + /// Specify path to the input file. pub fn input>(&mut self, path: P) -> &mut Self { self.cmd.arg(path.as_ref()); From 50539da261b885d1d829f77484ef689435fd571c Mon Sep 17 00:00:00 2001 From: Oneirical Date: Sat, 11 May 2024 15:35:49 -0400 Subject: [PATCH 075/179] rewrite alloc tests & remove import --- tests/run-make/alloc-no-oom-handling/Makefile | 7 ------- tests/run-make/alloc-no-oom-handling/rmake.rs | 14 ++++++++++++++ tests/run-make/alloc-no-rc/Makefile | 7 ------- tests/run-make/alloc-no-rc/rmake.rs | 14 ++++++++++++++ tests/run-make/alloc-no-sync/Makefile | 7 ------- tests/run-make/alloc-no-sync/rmake.rs | 14 ++++++++++++++ tests/run-make/core-no-fp-fmt-parse/rmake.rs | 1 - 7 files changed, 42 insertions(+), 22 deletions(-) delete mode 100644 tests/run-make/alloc-no-oom-handling/Makefile create mode 100644 tests/run-make/alloc-no-oom-handling/rmake.rs delete mode 100644 tests/run-make/alloc-no-rc/Makefile create mode 100644 tests/run-make/alloc-no-rc/rmake.rs delete mode 100644 tests/run-make/alloc-no-sync/Makefile create mode 100644 tests/run-make/alloc-no-sync/rmake.rs diff --git a/tests/run-make/alloc-no-oom-handling/Makefile b/tests/run-make/alloc-no-oom-handling/Makefile deleted file mode 100644 index 7c3ae90b58d67..0000000000000 --- a/tests/run-make/alloc-no-oom-handling/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -# This test checks that alloc can still compile correctly when the unstable no_global_oom_handling feature is turned on. -# See https://github.com/rust-lang/rust/pull/84266 - -include ../tools.mk - -all: - $(RUSTC) --edition=2021 -Dwarnings --crate-type=rlib ../../../library/alloc/src/lib.rs --cfg no_global_oom_handling diff --git a/tests/run-make/alloc-no-oom-handling/rmake.rs b/tests/run-make/alloc-no-oom-handling/rmake.rs new file mode 100644 index 0000000000000..102a770030270 --- /dev/null +++ b/tests/run-make/alloc-no-oom-handling/rmake.rs @@ -0,0 +1,14 @@ +// This test checks that alloc can still compile correctly when the unstable no_global_oom_handling feature is turned on. +// See https://github.com/rust-lang/rust/pull/84266 + +use run_make_support::rustc; + +fn main() { + rustc() + .edition("2021") + .arg("-Dwarnings") + .crate_type("rlib") + .input("../../../library/alloc/src/lib.rs") + .cfg("no_global_oom_handling") + .run(); +} diff --git a/tests/run-make/alloc-no-rc/Makefile b/tests/run-make/alloc-no-rc/Makefile deleted file mode 100644 index fcfe1603b6ce9..0000000000000 --- a/tests/run-make/alloc-no-rc/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -# This test checks that alloc can still compile correctly when the unstable no_rc feature is turned on. -# See https://github.com/rust-lang/rust/pull/89891 - -include ../tools.mk - -all: - $(RUSTC) --edition=2021 -Dwarnings --crate-type=rlib ../../../library/alloc/src/lib.rs --cfg no_rc diff --git a/tests/run-make/alloc-no-rc/rmake.rs b/tests/run-make/alloc-no-rc/rmake.rs new file mode 100644 index 0000000000000..b4a0950d3e48c --- /dev/null +++ b/tests/run-make/alloc-no-rc/rmake.rs @@ -0,0 +1,14 @@ +// This test checks that alloc can still compile correctly when the unstable no_rc feature is turned on. +// See https://github.com/rust-lang/rust/pull/84266 + +use run_make_support::rustc; + +fn main() { + rustc() + .edition("2021") + .arg("-Dwarnings") + .crate_type("rlib") + .input("../../../library/alloc/src/lib.rs") + .cfg("no_rc") + .run(); +} diff --git a/tests/run-make/alloc-no-sync/Makefile b/tests/run-make/alloc-no-sync/Makefile deleted file mode 100644 index 997dbcf66036d..0000000000000 --- a/tests/run-make/alloc-no-sync/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -# This test checks that alloc can still compile correctly when the unstable no_sync feature is turned on. -# See https://github.com/rust-lang/rust/pull/89891 - -include ../tools.mk - -all: - $(RUSTC) --edition=2021 -Dwarnings --crate-type=rlib ../../../library/alloc/src/lib.rs --cfg no_sync diff --git a/tests/run-make/alloc-no-sync/rmake.rs b/tests/run-make/alloc-no-sync/rmake.rs new file mode 100644 index 0000000000000..32196ba929447 --- /dev/null +++ b/tests/run-make/alloc-no-sync/rmake.rs @@ -0,0 +1,14 @@ +// This test checks that alloc can still compile correctly when the unstable no_sync feature is turned on. +// See https://github.com/rust-lang/rust/pull/84266 + +use run_make_support::rustc; + +fn main() { + rustc() + .edition("2021") + .arg("-Dwarnings") + .crate_type("rlib") + .input("../../../library/alloc/src/lib.rs") + .cfg("no_sync") + .run(); +} diff --git a/tests/run-make/core-no-fp-fmt-parse/rmake.rs b/tests/run-make/core-no-fp-fmt-parse/rmake.rs index e3484888ca5a2..aef28fd252812 100644 --- a/tests/run-make/core-no-fp-fmt-parse/rmake.rs +++ b/tests/run-make/core-no-fp-fmt-parse/rmake.rs @@ -2,7 +2,6 @@ // support for formatting and parsing floating-point numbers. use run_make_support::rustc; -use std::path::PathBuf; fn main() { rustc() From a3ef01b1fc14fb4b4af00f8437c4a462db8af9ab Mon Sep 17 00:00:00 2001 From: Federico Maria Morrone Date: Sun, 24 Mar 2024 15:33:00 +0100 Subject: [PATCH 076/179] Add x86_64-unknown-linux-none target --- compiler/rustc_target/src/spec/mod.rs | 3 +++ .../spec/targets/x86_64_unknown_linux_none.rs | 25 +++++++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_none.rs diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 8307803676e1c..8ba945e193c1b 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -1774,6 +1774,9 @@ supported_targets! { ("aarch64-unknown-linux-ohos", aarch64_unknown_linux_ohos), ("armv7-unknown-linux-ohos", armv7_unknown_linux_ohos), ("x86_64-unknown-linux-ohos", x86_64_unknown_linux_ohos), + + ("x86_64-unknown-linux-none", x86_64_unknown_linux_none), + } /// Cow-Vec-Str: Cow<'static, [Cow<'static, str>]> diff --git a/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_none.rs b/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_none.rs new file mode 100644 index 0000000000000..b6e331bd85453 --- /dev/null +++ b/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_none.rs @@ -0,0 +1,25 @@ +use crate::spec::{base, Cc, LinkerFlavor, Lld, StackProbeType, Target}; + +pub fn target() -> Target { + let mut base = base::linux::opts(); + base.cpu = "x86-64".into(); + base.max_atomic_width = Some(64); + base.stack_probes = StackProbeType::Inline; + base.linker_flavor = LinkerFlavor::Gnu(Cc::No, Lld::Yes); + base.linker = Some("rust-lld".into()); + + Target { + llvm_target: "x86_64-unknown-linux-none".into(), + metadata: crate::spec::TargetMetadata { + description: None, + tier: None, + host_tools: None, + std: None, + }, + pointer_width: 64, + data_layout: + "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128".into(), + arch: "x86_64".into(), + options: base, + } +} From 9cf080099d230fc6602d51df37c8bbd5cf4a8e8e Mon Sep 17 00:00:00 2001 From: Federico Maria Morrone Date: Sat, 11 May 2024 20:51:54 +0200 Subject: [PATCH 077/179] docs: Document x86_64-unknown-linux-none target --- src/doc/rustc/src/SUMMARY.md | 1 + src/doc/rustc/src/platform-support.md | 1 + .../x86_64-unknown-linux-none.md | 40 +++++++++++++++++++ 3 files changed, 42 insertions(+) create mode 100644 src/doc/rustc/src/platform-support/x86_64-unknown-linux-none.md diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md index c9c0ee4067f1b..c7e3293e35ade 100644 --- a/src/doc/rustc/src/SUMMARY.md +++ b/src/doc/rustc/src/SUMMARY.md @@ -74,6 +74,7 @@ - [wasm64-unknown-unknown](platform-support/wasm64-unknown-unknown.md) - [\*-win7-windows-msvc](platform-support/win7-windows-msvc.md) - [x86_64-fortanix-unknown-sgx](platform-support/x86_64-fortanix-unknown-sgx.md) + - [x86_64-unknown-linux-none.md](platform-support/x86_64-unknown-linux-none.md) - [x86_64-unknown-none](platform-support/x86_64-unknown-none.md) - [x86_64h-apple-darwin](platform-support/x86_64h-apple-darwin.md) - [Targets](targets/index.md) diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index 764798a80e6d2..8adc410455eda 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -382,5 +382,6 @@ target | std | host | notes [`x86_64-win7-windows-msvc`](platform-support/win7-windows-msvc.md) | ✓ | | 64-bit Windows 7 support `x86_64-wrs-vxworks` | ? | | [`x86_64h-apple-darwin`](platform-support/x86_64h-apple-darwin.md) | ✓ | ✓ | macOS with late-gen Intel (at least Haswell) +[`x86_64-unknown-linux-none`](platform-support/x86_64-unknown-linux-none.md) | * | | 64-bit Linux with no libc [runs on NVIDIA GPUs]: https://github.com/japaric-archived/nvptx#targets diff --git a/src/doc/rustc/src/platform-support/x86_64-unknown-linux-none.md b/src/doc/rustc/src/platform-support/x86_64-unknown-linux-none.md new file mode 100644 index 0000000000000..ef8fd3aa2e384 --- /dev/null +++ b/src/doc/rustc/src/platform-support/x86_64-unknown-linux-none.md @@ -0,0 +1,40 @@ +# `x86_64-unknown-linux-none` + +**Tier: 3** + +Freestanding x86-64 linux binary with no depedency on libc. + +## Target maintainers + +- [morr0ne](https://github.com/morr0ne/) + +## Requirements + +This target is cross compiled and can be built from any host. + +This target has no support for host tools, std and alloc. + +## Building the target + +The target can be built by enabling it for a `rustc` build: + +```toml +[build] +build-stage = 1 +target = ["x86_64-unknown-linux-none"] +``` + +## Building Rust programs + +Rust does not yet ship pre-compiled artifacts for this target. To compile for +this target, you will either need to build Rust with the target enabled (see +"Building the target" above), or build your own copy of `core` by using +`build-std` or similar. + +## Testing + +Created binaries will run on linux without any external requirements + +## Cross-compilation toolchains and C code + +Support for C code is currently untested From 7b50189dce74cf5b86cd928161138a2bd6c9305f Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Sat, 11 May 2024 21:38:25 +0200 Subject: [PATCH 078/179] add the `llvm.x86.sse42.crc32.32.32` intrinsic (#1488) * add the `llvm.x86.sse42.crc32.32.32` intrinsic --- src/intrinsics/llvm_x86.rs | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/intrinsics/llvm_x86.rs b/src/intrinsics/llvm_x86.rs index 8df83c706a100..71e06c73a376e 100644 --- a/src/intrinsics/llvm_x86.rs +++ b/src/intrinsics/llvm_x86.rs @@ -832,6 +832,32 @@ pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>( } } + "llvm.x86.sse42.crc32.32.32" => { + // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#ig_expand=1419&text=_mm_crc32_u32 + intrinsic_args!(fx, args => (crc, v); intrinsic); + + let crc = crc.load_scalar(fx); + let v = v.load_scalar(fx); + + codegen_inline_asm_inner( + fx, + &[InlineAsmTemplatePiece::String("crc32 eax, edx".to_string())], + &[ + CInlineAsmOperand::InOut { + reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::ax)), + _late: true, + in_value: crc, + out_place: Some(ret), + }, + CInlineAsmOperand::In { + reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::dx)), + value: v, + }, + ], + InlineAsmOptions::NOSTACK | InlineAsmOptions::PURE | InlineAsmOptions::NOMEM, + ); + } + "llvm.x86.sse42.pcmpestri128" => { // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_cmpestri&ig_expand=939 intrinsic_args!(fx, args => (a, la, b, lb, _imm8); intrinsic); From e7b6662464d62bbe1590fa8b8b709b4ffc3d3831 Mon Sep 17 00:00:00 2001 From: Folkert Date: Sat, 11 May 2024 21:44:08 +0200 Subject: [PATCH 079/179] support crc32 with 8-bit and 16-bit inputs, and add crc64 support --- src/intrinsics/llvm_x86.rs | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/intrinsics/llvm_x86.rs b/src/intrinsics/llvm_x86.rs index 71e06c73a376e..1155a00a2f026 100644 --- a/src/intrinsics/llvm_x86.rs +++ b/src/intrinsics/llvm_x86.rs @@ -832,16 +832,27 @@ pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>( } } - "llvm.x86.sse42.crc32.32.32" => { + "llvm.x86.sse42.crc32.32.8" + | "llvm.x86.sse42.crc32.32.16" + | "llvm.x86.sse42.crc32.32.32" + | "llvm.x86.sse42.crc32.64.64" => { // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#ig_expand=1419&text=_mm_crc32_u32 intrinsic_args!(fx, args => (crc, v); intrinsic); let crc = crc.load_scalar(fx); let v = v.load_scalar(fx); + let asm = match intrinsic { + "llvm.x86.sse42.crc32.32.8" => "crc32 eax, dl", + "llvm.x86.sse42.crc32.32.16" => "crc32 eax, dx", + "llvm.x86.sse42.crc32.32.32" => "crc32 eax, edx", + "llvm.x86.sse42.crc32.64.64" => "crc32 rax, rdx", + _ => unreachable!(), + }; + codegen_inline_asm_inner( fx, - &[InlineAsmTemplatePiece::String("crc32 eax, edx".to_string())], + &[InlineAsmTemplatePiece::String(asm.to_string())], &[ CInlineAsmOperand::InOut { reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::ax)), From 198b073192402510eb7b0b0ec2a98ca6dbdeebc1 Mon Sep 17 00:00:00 2001 From: Oneirical Date: Sat, 11 May 2024 15:54:18 -0400 Subject: [PATCH 080/179] make tidy happy --- src/tools/tidy/src/allowed_run_make_makefiles.txt | 3 --- tests/run-make/alloc-no-oom-handling/rmake.rs | 3 ++- tests/run-make/alloc-no-rc/rmake.rs | 3 ++- tests/run-make/alloc-no-sync/rmake.rs | 3 ++- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index e87950b36d9df..d96fc3f41f724 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -1,6 +1,3 @@ -run-make/alloc-no-oom-handling/Makefile -run-make/alloc-no-rc/Makefile -run-make/alloc-no-sync/Makefile run-make/allocator-shim-circular-deps/Makefile run-make/allow-non-lint-warnings-cmdline/Makefile run-make/allow-warnings-cmdline-stability/Makefile diff --git a/tests/run-make/alloc-no-oom-handling/rmake.rs b/tests/run-make/alloc-no-oom-handling/rmake.rs index 102a770030270..fec3c6532940e 100644 --- a/tests/run-make/alloc-no-oom-handling/rmake.rs +++ b/tests/run-make/alloc-no-oom-handling/rmake.rs @@ -1,4 +1,5 @@ -// This test checks that alloc can still compile correctly when the unstable no_global_oom_handling feature is turned on. +// This test checks that alloc can still compile correctly +// when the unstable no_global_oom_handling feature is turned on. // See https://github.com/rust-lang/rust/pull/84266 use run_make_support::rustc; diff --git a/tests/run-make/alloc-no-rc/rmake.rs b/tests/run-make/alloc-no-rc/rmake.rs index b4a0950d3e48c..c5744a3f5eef5 100644 --- a/tests/run-make/alloc-no-rc/rmake.rs +++ b/tests/run-make/alloc-no-rc/rmake.rs @@ -1,4 +1,5 @@ -// This test checks that alloc can still compile correctly when the unstable no_rc feature is turned on. +// This test checks that alloc can still compile correctly +// when the unstable no_rc feature is turned on. // See https://github.com/rust-lang/rust/pull/84266 use run_make_support::rustc; diff --git a/tests/run-make/alloc-no-sync/rmake.rs b/tests/run-make/alloc-no-sync/rmake.rs index 32196ba929447..6410eca80abff 100644 --- a/tests/run-make/alloc-no-sync/rmake.rs +++ b/tests/run-make/alloc-no-sync/rmake.rs @@ -1,4 +1,5 @@ -// This test checks that alloc can still compile correctly when the unstable no_sync feature is turned on. +// This test checks that alloc can still compile correctly +// when the unstable no_sync feature is turned on. // See https://github.com/rust-lang/rust/pull/84266 use run_make_support::rustc; From 4a4535a57cef0182d516888f1abb5d4a9ec84fdc Mon Sep 17 00:00:00 2001 From: Folkert Date: Sat, 11 May 2024 21:16:38 +0200 Subject: [PATCH 081/179] add `llvm.x86.avx2.permd` intrinsic --- example/std_example.rs | 11 +++++++++++ src/intrinsics/llvm_x86.rs | 15 +++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/example/std_example.rs b/example/std_example.rs index 90d4ab721daef..0e1004420dd71 100644 --- a/example/std_example.rs +++ b/example/std_example.rs @@ -244,6 +244,7 @@ unsafe fn test_simd() { test_mm256_shuffle_epi8(); test_mm256_permute2x128_si256(); + test_mm256_permutevar8x32_epi32(); #[rustfmt::skip] let mask1 = _mm_movemask_epi8(dbg!(_mm_setr_epi8(255u8 as i8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0))); @@ -447,6 +448,16 @@ unsafe fn test_mm256_permute2x128_si256() { assert_eq_m256i(r, e); } +#[cfg(target_arch = "x86_64")] +#[target_feature(enable = "avx2")] +unsafe fn test_mm256_permutevar8x32_epi32() { + let a = _mm256_setr_epi32(100, 200, 300, 400, 500, 600, 700, 800); + let idx = _mm256_setr_epi32(7, 6, 5, 4, 3, 2, 1, 0); + let r = _mm256_setr_epi32(800, 700, 600, 500, 400, 300, 200, 100); + let e = _mm256_permutevar8x32_epi32(a, idx); + assert_eq_m256i(r, e); +} + fn test_checked_mul() { let u: Option = u8::from_str_radix("1000", 10).ok(); assert_eq!(u, None); diff --git a/src/intrinsics/llvm_x86.rs b/src/intrinsics/llvm_x86.rs index 8df83c706a100..f0c48884745e2 100644 --- a/src/intrinsics/llvm_x86.rs +++ b/src/intrinsics/llvm_x86.rs @@ -374,6 +374,21 @@ pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>( } } } + "llvm.x86.avx2.permd" => { + // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm256_permutevar8x32_epi32 + intrinsic_args!(fx, args => (a, idx); intrinsic); + + for j in 0..=7 { + let index = idx.value_typed_lane(fx, fx.tcx.types.u32, j).load_scalar(fx); + let index = fx.bcx.ins().uextend(fx.pointer_type, index); + let value = a.value_lane_dyn(fx, index).load_scalar(fx); + ret.place_typed_lane(fx, fx.tcx.types.u32, j).to_ptr().store( + fx, + value, + MemFlags::trusted(), + ); + } + } "llvm.x86.avx2.vperm2i128" | "llvm.x86.avx.vperm2f128.ps.256" | "llvm.x86.avx.vperm2f128.pd.256" => { From 9059a74fd00657b5a7f58d2f339774c977bdbdda Mon Sep 17 00:00:00 2001 From: Folkert Date: Sat, 11 May 2024 21:49:59 +0200 Subject: [PATCH 082/179] test x86 crc intrinsics --- example/std_example.rs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/example/std_example.rs b/example/std_example.rs index 90d4ab721daef..6a7f1905816ac 100644 --- a/example/std_example.rs +++ b/example/std_example.rs @@ -210,6 +210,21 @@ struct I64X2(i64, i64); #[allow(improper_ctypes_definitions)] extern "C" fn foo(_a: I64X2) {} +#[cfg(target_arch = "x86_64")] +#[target_feature(enable = "sse4.2")] +#[cfg(not(jit))] +unsafe fn test_crc32() { + assert!(is_x86_feature_detected!("sse4.2")); + + let a = 42u32; + let b = 0xdeadbeefu64; + + assert_eq!(_mm_crc32_u8(a, b as u8), 4135334616); + assert_eq!(_mm_crc32_u16(a, b as u16), 1200687288); + assert_eq!(_mm_crc32_u32(a, b as u32), 2543798776); + assert_eq!(_mm_crc32_u64(a as u64, b as u64), 241952147); +} + #[cfg(target_arch = "x86_64")] #[target_feature(enable = "sse2")] unsafe fn test_simd() { @@ -248,6 +263,9 @@ unsafe fn test_simd() { #[rustfmt::skip] let mask1 = _mm_movemask_epi8(dbg!(_mm_setr_epi8(255u8 as i8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0))); assert_eq!(mask1, 1); + + #[cfg(not(jit))] + test_crc32(); } #[cfg(target_arch = "x86_64")] From a2e7e79a137a853b250ed106c16e61106b900d3b Mon Sep 17 00:00:00 2001 From: Oneirical Date: Sat, 11 May 2024 16:41:07 -0400 Subject: [PATCH 083/179] Port c-link-to-rust-va-list-fn to Rust --- .../tidy/src/allowed_run_make_makefiles.txt | 1 - .../c-link-to-rust-va-list-fn/Makefile | 7 ------- .../c-link-to-rust-va-list-fn/rmake.rs | 21 +++++++++++++++++++ 3 files changed, 21 insertions(+), 8 deletions(-) delete mode 100644 tests/run-make/c-link-to-rust-va-list-fn/Makefile create mode 100644 tests/run-make/c-link-to-rust-va-list-fn/rmake.rs diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index e87950b36d9df..029bb7806dbd5 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -12,7 +12,6 @@ run-make/c-dynamic-dylib/Makefile run-make/c-dynamic-rlib/Makefile run-make/c-link-to-rust-dylib/Makefile run-make/c-link-to-rust-staticlib/Makefile -run-make/c-link-to-rust-va-list-fn/Makefile run-make/c-static-dylib/Makefile run-make/c-static-rlib/Makefile run-make/c-unwind-abi-catch-lib-panic/Makefile diff --git a/tests/run-make/c-link-to-rust-va-list-fn/Makefile b/tests/run-make/c-link-to-rust-va-list-fn/Makefile deleted file mode 100644 index 596c0fce3ceae..0000000000000 --- a/tests/run-make/c-link-to-rust-va-list-fn/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -# ignore-cross-compile -include ../tools.mk - -all: - $(RUSTC) checkrust.rs - $(CC) test.c $(call STATICLIB,checkrust) $(call OUT_EXE,test) $(EXTRACFLAGS) - $(call RUN,test) diff --git a/tests/run-make/c-link-to-rust-va-list-fn/rmake.rs b/tests/run-make/c-link-to-rust-va-list-fn/rmake.rs new file mode 100644 index 0000000000000..d8d0e064c6080 --- /dev/null +++ b/tests/run-make/c-link-to-rust-va-list-fn/rmake.rs @@ -0,0 +1,21 @@ +// test.c and its static library checkrust.rs make use of variadic functions (VaList). +// This test checks that the use of this feature does not +// prevent the creation of a functional binary. +// See https://github.com/rust-lang/rust/pull/49878 + +//@ ignore-cross-compile + +use run_make_support::{cc, extra_c_flags, run, rustc, static_lib}; + +fn main() { + rustc() + .input("checkrust.rs") + .run(); + cc() + .input("test.c") + .input(static_lib("checkrust")) + .out_exe("test") + .args(&extra_c_flags()) + .run(); + run("test"); +} From e37d2989c1d1f1600f3769ce6f46e77493169b8d Mon Sep 17 00:00:00 2001 From: Julien <96022417+Oneirical@users.noreply.github.com> Date: Sat, 11 May 2024 16:52:28 -0400 Subject: [PATCH 084/179] remove trailing whitespace --- tests/run-make/c-link-to-rust-va-list-fn/rmake.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/run-make/c-link-to-rust-va-list-fn/rmake.rs b/tests/run-make/c-link-to-rust-va-list-fn/rmake.rs index d8d0e064c6080..36c31f973c6c7 100644 --- a/tests/run-make/c-link-to-rust-va-list-fn/rmake.rs +++ b/tests/run-make/c-link-to-rust-va-list-fn/rmake.rs @@ -1,5 +1,5 @@ // test.c and its static library checkrust.rs make use of variadic functions (VaList). -// This test checks that the use of this feature does not +// This test checks that the use of this feature does not // prevent the creation of a functional binary. // See https://github.com/rust-lang/rust/pull/49878 From 10c358f11189de4f639106253c8178dbbfa3f68e Mon Sep 17 00:00:00 2001 From: Julien <96022417+Oneirical@users.noreply.github.com> Date: Sat, 11 May 2024 16:59:29 -0400 Subject: [PATCH 085/179] Make tidy happy --- tests/run-make/c-link-to-rust-va-list-fn/rmake.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/tests/run-make/c-link-to-rust-va-list-fn/rmake.rs b/tests/run-make/c-link-to-rust-va-list-fn/rmake.rs index 36c31f973c6c7..489a637c44533 100644 --- a/tests/run-make/c-link-to-rust-va-list-fn/rmake.rs +++ b/tests/run-make/c-link-to-rust-va-list-fn/rmake.rs @@ -8,11 +8,9 @@ use run_make_support::{cc, extra_c_flags, run, rustc, static_lib}; fn main() { - rustc() - .input("checkrust.rs") + rustc().input("checkrust.rs") .run(); - cc() - .input("test.c") + cc().input("test.c") .input(static_lib("checkrust")) .out_exe("test") .args(&extra_c_flags()) From d5797e938a371c96c6ed649e605091a9ca0ad775 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 10 May 2024 20:30:24 -0400 Subject: [PATCH 086/179] Make it possible to derive Lift/TypeVisitable/TypeFoldable in rustc_type_ir --- Cargo.lock | 11 ++ compiler/rustc_type_ir/Cargo.toml | 1 + compiler/rustc_type_ir/src/canonical.rs | 151 +++--------------- compiler/rustc_type_ir/src/const_kind.rs | 4 +- compiler/rustc_type_ir/src/predicate_kind.rs | 127 +-------------- compiler/rustc_type_ir/src/region_kind.rs | 5 +- compiler/rustc_type_ir/src/trait_ref.rs | 44 +---- compiler/rustc_type_ir/src/ty_kind.rs | 32 +--- compiler/rustc_type_ir_macros/Cargo.toml | 15 ++ compiler/rustc_type_ir_macros/src/lib.rs | 159 +++++++++++++++++++ 10 files changed, 218 insertions(+), 331 deletions(-) create mode 100644 compiler/rustc_type_ir_macros/Cargo.toml create mode 100644 compiler/rustc_type_ir_macros/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index f49bcf7c865cd..2aed7ebacd51f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4837,9 +4837,20 @@ dependencies = [ "rustc_macros", "rustc_serialize", "rustc_span", + "rustc_type_ir_macros", "smallvec", ] +[[package]] +name = "rustc_type_ir_macros" +version = "0.0.0" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.62", + "synstructure", +] + [[package]] name = "rustc_version" version = "0.4.0" diff --git a/compiler/rustc_type_ir/Cargo.toml b/compiler/rustc_type_ir/Cargo.toml index 79ff60802d28e..d12052625ea22 100644 --- a/compiler/rustc_type_ir/Cargo.toml +++ b/compiler/rustc_type_ir/Cargo.toml @@ -11,6 +11,7 @@ rustc_ast_ir = { path = "../rustc_ast_ir" } rustc_data_structures = { path = "../rustc_data_structures", optional = true } rustc_index = { path = "../rustc_index", default-features = false } rustc_macros = { path = "../rustc_macros", optional = true } +rustc_type_ir_macros = { path = "../rustc_type_ir_macros" } rustc_serialize = { path = "../rustc_serialize", optional = true } rustc_span = { path = "../rustc_span", optional = true } smallvec = { version = "1.8.1" } diff --git a/compiler/rustc_type_ir/src/canonical.rs b/compiler/rustc_type_ir/src/canonical.rs index f7c7ec242c10b..efefd174cd6f0 100644 --- a/compiler/rustc_type_ir/src/canonical.rs +++ b/compiler/rustc_type_ir/src/canonical.rs @@ -1,20 +1,25 @@ -use rustc_ast_ir::try_visit; -use rustc_ast_ir::visit::VisitorResult; #[cfg(feature = "nightly")] use rustc_macros::{HashStable_NoContext, TyDecodable, TyEncodable}; +use rustc_type_ir_macros::{TypeFoldable_Generic, TypeVisitable_Generic}; use std::fmt; use std::hash::Hash; -use crate::fold::{FallibleTypeFolder, TypeFoldable}; use crate::inherent::*; -use crate::visit::{TypeVisitable, TypeVisitor}; use crate::{Interner, UniverseIndex}; /// A "canonicalized" type `V` is one where all free inference /// variables have been rewritten to "canonical vars". These are /// numbered starting from 0 in order of first appearance. #[derive(derivative::Derivative)] -#[derivative(Clone(bound = "V: Clone"), Hash(bound = "V: Hash"))] +#[derivative( + Clone(bound = "V: Clone"), + Hash(bound = "V: Hash"), + PartialEq(bound = "V: PartialEq"), + Eq(bound = "V: Eq"), + Debug(bound = "V: fmt::Debug"), + Copy(bound = "V: Copy") +)] +#[derive(TypeVisitable_Generic, TypeFoldable_Generic)] #[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable, HashStable_NoContext))] pub struct Canonical { pub value: V, @@ -64,18 +69,6 @@ impl Canonical { } } -impl Eq for Canonical {} - -impl PartialEq for Canonical { - fn eq(&self, other: &Self) -> bool { - let Self { value, max_universe, variables, defining_opaque_types } = self; - *value == other.value - && *max_universe == other.max_universe - && *variables == other.variables - && *defining_opaque_types == other.defining_opaque_types - } -} - impl fmt::Display for Canonical { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let Self { value, max_universe, variables, defining_opaque_types } = self; @@ -86,84 +79,25 @@ impl fmt::Display for Canonical { } } -impl fmt::Debug for Canonical { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let Self { value, max_universe, variables, defining_opaque_types } = self; - f.debug_struct("Canonical") - .field("value", &value) - .field("max_universe", &max_universe) - .field("variables", &variables) - .field("defining_opaque_types", &defining_opaque_types) - .finish() - } -} - -impl Copy for Canonical where I::CanonicalVars: Copy {} - -impl> TypeFoldable for Canonical -where - I::CanonicalVars: TypeFoldable, -{ - fn try_fold_with>(self, folder: &mut F) -> Result { - Ok(Canonical { - value: self.value.try_fold_with(folder)?, - max_universe: self.max_universe.try_fold_with(folder)?, - variables: self.variables.try_fold_with(folder)?, - defining_opaque_types: self.defining_opaque_types, - }) - } -} - -impl> TypeVisitable for Canonical -where - I::CanonicalVars: TypeVisitable, -{ - fn visit_with>(&self, folder: &mut F) -> F::Result { - let Self { value, max_universe, variables, defining_opaque_types } = self; - try_visit!(value.visit_with(folder)); - try_visit!(max_universe.visit_with(folder)); - try_visit!(defining_opaque_types.visit_with(folder)); - variables.visit_with(folder) - } -} - /// Information about a canonical variable that is included with the /// canonical value. This is sufficient information for code to create /// a copy of the canonical value in some other inference context, /// with fresh inference variables replacing the canonical values. #[derive(derivative::Derivative)] -#[derivative(Clone(bound = ""), Copy(bound = ""), Hash(bound = ""), Debug(bound = ""))] +#[derivative( + Clone(bound = ""), + Copy(bound = ""), + Hash(bound = ""), + Debug(bound = ""), + Eq(bound = ""), + PartialEq(bound = "") +)] +#[derive(TypeVisitable_Generic, TypeFoldable_Generic)] #[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))] pub struct CanonicalVarInfo { pub kind: CanonicalVarKind, } -impl PartialEq for CanonicalVarInfo { - fn eq(&self, other: &Self) -> bool { - self.kind == other.kind - } -} - -impl Eq for CanonicalVarInfo {} - -impl TypeVisitable for CanonicalVarInfo -where - I::Ty: TypeVisitable, -{ - fn visit_with>(&self, visitor: &mut V) -> V::Result { - self.kind.visit_with(visitor) - } -} - -impl TypeFoldable for CanonicalVarInfo -where - I::Ty: TypeFoldable, -{ - fn try_fold_with>(self, folder: &mut F) -> Result { - Ok(CanonicalVarInfo { kind: self.kind.try_fold_with(folder)? }) - } -} - impl CanonicalVarInfo { pub fn universe(self) -> UniverseIndex { self.kind.universe() @@ -216,6 +150,7 @@ impl CanonicalVarInfo { /// that analyzes type-like values. #[derive(derivative::Derivative)] #[derivative(Clone(bound = ""), Copy(bound = ""), Hash(bound = ""), Debug(bound = ""))] +#[derive(TypeVisitable_Generic, TypeFoldable_Generic)] #[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))] pub enum CanonicalVarKind { /// Some kind of type inference variable. @@ -258,51 +193,6 @@ impl PartialEq for CanonicalVarKind { } } -impl Eq for CanonicalVarKind {} - -impl TypeVisitable for CanonicalVarKind -where - I::Ty: TypeVisitable, -{ - fn visit_with>(&self, visitor: &mut V) -> V::Result { - match self { - CanonicalVarKind::Ty(_) - | CanonicalVarKind::PlaceholderTy(_) - | CanonicalVarKind::Region(_) - | CanonicalVarKind::PlaceholderRegion(_) - | CanonicalVarKind::Effect => V::Result::output(), - CanonicalVarKind::Const(_, ty) | CanonicalVarKind::PlaceholderConst(_, ty) => { - ty.visit_with(visitor) - } - } - } -} - -impl TypeFoldable for CanonicalVarKind -where - I::Ty: TypeFoldable, -{ - fn try_fold_with>(self, folder: &mut F) -> Result { - Ok(match self { - CanonicalVarKind::Ty(kind) => CanonicalVarKind::Ty(kind), - CanonicalVarKind::Region(kind) => CanonicalVarKind::Region(kind), - CanonicalVarKind::Const(kind, ty) => { - CanonicalVarKind::Const(kind, ty.try_fold_with(folder)?) - } - CanonicalVarKind::PlaceholderTy(placeholder) => { - CanonicalVarKind::PlaceholderTy(placeholder) - } - CanonicalVarKind::PlaceholderRegion(placeholder) => { - CanonicalVarKind::PlaceholderRegion(placeholder) - } - CanonicalVarKind::PlaceholderConst(placeholder, ty) => { - CanonicalVarKind::PlaceholderConst(placeholder, ty.try_fold_with(folder)?) - } - CanonicalVarKind::Effect => CanonicalVarKind::Effect, - }) - } -} - impl CanonicalVarKind { pub fn universe(self) -> UniverseIndex { match self { @@ -355,6 +245,7 @@ impl CanonicalVarKind { /// usize or f32). In order to faithfully reproduce a type, we need to /// know what set of types a given type variable can be unified with. #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] +#[derive(TypeVisitable_Generic, TypeFoldable_Generic)] #[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))] pub enum CanonicalTyVarKind { /// General type variable `?T` that can be unified with arbitrary types. diff --git a/compiler/rustc_type_ir/src/const_kind.rs b/compiler/rustc_type_ir/src/const_kind.rs index c1506f9252b08..c748cdf6ed278 100644 --- a/compiler/rustc_type_ir/src/const_kind.rs +++ b/compiler/rustc_type_ir/src/const_kind.rs @@ -10,7 +10,7 @@ use self::ConstKind::*; /// Represents a constant in Rust. #[derive(derivative::Derivative)] -#[derivative(Clone(bound = ""), Copy(bound = ""), Hash(bound = ""))] +#[derivative(Clone(bound = ""), Copy(bound = ""), Hash(bound = ""), Eq(bound = ""))] #[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable, HashStable_NoContext))] pub enum ConstKind { /// A const generic parameter. @@ -58,8 +58,6 @@ impl PartialEq for ConstKind { } } -impl Eq for ConstKind {} - impl fmt::Debug for ConstKind { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { WithInfcx::with_no_infcx(self).fmt(f) diff --git a/compiler/rustc_type_ir/src/predicate_kind.rs b/compiler/rustc_type_ir/src/predicate_kind.rs index 5260d9061cfc8..c477ab14153e2 100644 --- a/compiler/rustc_type_ir/src/predicate_kind.rs +++ b/compiler/rustc_type_ir/src/predicate_kind.rs @@ -1,17 +1,15 @@ -use rustc_ast_ir::try_visit; -use rustc_ast_ir::visit::VisitorResult; #[cfg(feature = "nightly")] use rustc_macros::{Decodable, Encodable, HashStable_NoContext, TyDecodable, TyEncodable}; +use rustc_type_ir_macros::{TypeFoldable_Generic, TypeVisitable_Generic}; use std::fmt; -use crate::fold::{FallibleTypeFolder, TypeFoldable}; -use crate::visit::{TypeVisitable, TypeVisitor}; use crate::Interner; /// A clause is something that can appear in where bounds or be inferred /// by implied bounds. #[derive(derivative::Derivative)] -#[derivative(Clone(bound = ""), Copy(bound = ""), Hash(bound = ""))] +#[derivative(Clone(bound = ""), Copy(bound = ""), Hash(bound = ""), Eq(bound = ""))] +#[derive(TypeVisitable_Generic, TypeFoldable_Generic)] #[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable, HashStable_NoContext))] pub enum ClauseKind { /// Corresponds to `where Foo: Bar`. `Foo` here would be @@ -55,61 +53,6 @@ impl PartialEq for ClauseKind { } } -impl Eq for ClauseKind {} - -impl TypeFoldable for ClauseKind -where - I::Ty: TypeFoldable, - I::Const: TypeFoldable, - I::GenericArg: TypeFoldable, - I::TraitPredicate: TypeFoldable, - I::ProjectionPredicate: TypeFoldable, - I::TypeOutlivesPredicate: TypeFoldable, - I::RegionOutlivesPredicate: TypeFoldable, -{ - fn try_fold_with>(self, folder: &mut F) -> Result { - Ok(match self { - ClauseKind::Trait(p) => ClauseKind::Trait(p.try_fold_with(folder)?), - ClauseKind::RegionOutlives(p) => ClauseKind::RegionOutlives(p.try_fold_with(folder)?), - ClauseKind::TypeOutlives(p) => ClauseKind::TypeOutlives(p.try_fold_with(folder)?), - ClauseKind::Projection(p) => ClauseKind::Projection(p.try_fold_with(folder)?), - ClauseKind::ConstArgHasType(c, t) => { - ClauseKind::ConstArgHasType(c.try_fold_with(folder)?, t.try_fold_with(folder)?) - } - ClauseKind::WellFormed(p) => ClauseKind::WellFormed(p.try_fold_with(folder)?), - ClauseKind::ConstEvaluatable(p) => { - ClauseKind::ConstEvaluatable(p.try_fold_with(folder)?) - } - }) - } -} - -impl TypeVisitable for ClauseKind -where - I::Ty: TypeVisitable, - I::Const: TypeVisitable, - I::GenericArg: TypeVisitable, - I::TraitPredicate: TypeVisitable, - I::ProjectionPredicate: TypeVisitable, - I::TypeOutlivesPredicate: TypeVisitable, - I::RegionOutlivesPredicate: TypeVisitable, -{ - fn visit_with>(&self, visitor: &mut V) -> V::Result { - match self { - ClauseKind::Trait(p) => p.visit_with(visitor), - ClauseKind::RegionOutlives(p) => p.visit_with(visitor), - ClauseKind::TypeOutlives(p) => p.visit_with(visitor), - ClauseKind::Projection(p) => p.visit_with(visitor), - ClauseKind::ConstArgHasType(c, t) => { - try_visit!(c.visit_with(visitor)); - t.visit_with(visitor) - } - ClauseKind::WellFormed(p) => p.visit_with(visitor), - ClauseKind::ConstEvaluatable(p) => p.visit_with(visitor), - } - } -} - #[derive(derivative::Derivative)] #[derivative( Clone(bound = ""), @@ -118,6 +61,7 @@ where PartialEq(bound = ""), Eq(bound = "") )] +#[derive(TypeVisitable_Generic, TypeFoldable_Generic)] #[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable, HashStable_NoContext))] pub enum PredicateKind { /// Prove a clause @@ -167,69 +111,6 @@ pub enum PredicateKind { AliasRelate(I::Term, I::Term, AliasRelationDirection), } -impl TypeFoldable for PredicateKind -where - I::DefId: TypeFoldable, - I::Const: TypeFoldable, - I::GenericArgs: TypeFoldable, - I::Term: TypeFoldable, - I::CoercePredicate: TypeFoldable, - I::SubtypePredicate: TypeFoldable, - I::NormalizesTo: TypeFoldable, - ClauseKind: TypeFoldable, -{ - fn try_fold_with>(self, folder: &mut F) -> Result { - Ok(match self { - PredicateKind::Clause(c) => PredicateKind::Clause(c.try_fold_with(folder)?), - PredicateKind::ObjectSafe(d) => PredicateKind::ObjectSafe(d.try_fold_with(folder)?), - PredicateKind::Subtype(s) => PredicateKind::Subtype(s.try_fold_with(folder)?), - PredicateKind::Coerce(s) => PredicateKind::Coerce(s.try_fold_with(folder)?), - PredicateKind::ConstEquate(a, b) => { - PredicateKind::ConstEquate(a.try_fold_with(folder)?, b.try_fold_with(folder)?) - } - PredicateKind::Ambiguous => PredicateKind::Ambiguous, - PredicateKind::NormalizesTo(p) => PredicateKind::NormalizesTo(p.try_fold_with(folder)?), - PredicateKind::AliasRelate(a, b, d) => PredicateKind::AliasRelate( - a.try_fold_with(folder)?, - b.try_fold_with(folder)?, - d.try_fold_with(folder)?, - ), - }) - } -} - -impl TypeVisitable for PredicateKind -where - I::DefId: TypeVisitable, - I::Const: TypeVisitable, - I::GenericArgs: TypeVisitable, - I::Term: TypeVisitable, - I::CoercePredicate: TypeVisitable, - I::SubtypePredicate: TypeVisitable, - I::NormalizesTo: TypeVisitable, - ClauseKind: TypeVisitable, -{ - fn visit_with>(&self, visitor: &mut V) -> V::Result { - match self { - PredicateKind::Clause(p) => p.visit_with(visitor), - PredicateKind::ObjectSafe(d) => d.visit_with(visitor), - PredicateKind::Subtype(s) => s.visit_with(visitor), - PredicateKind::Coerce(s) => s.visit_with(visitor), - PredicateKind::ConstEquate(a, b) => { - try_visit!(a.visit_with(visitor)); - b.visit_with(visitor) - } - PredicateKind::Ambiguous => V::Result::output(), - PredicateKind::NormalizesTo(p) => p.visit_with(visitor), - PredicateKind::AliasRelate(a, b, d) => { - try_visit!(a.visit_with(visitor)); - try_visit!(b.visit_with(visitor)); - d.visit_with(visitor) - } - } - } -} - #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Copy)] #[cfg_attr(feature = "nightly", derive(HashStable_NoContext, Encodable, Decodable))] pub enum AliasRelationDirection { diff --git a/compiler/rustc_type_ir/src/region_kind.rs b/compiler/rustc_type_ir/src/region_kind.rs index d1b86b495e9d8..eaae4ee0130bf 100644 --- a/compiler/rustc_type_ir/src/region_kind.rs +++ b/compiler/rustc_type_ir/src/region_kind.rs @@ -115,7 +115,7 @@ use self::RegionKind::*; /// [2]: https://smallcultfollowing.com/babysteps/blog/2013/11/04/intermingled-parameter-lists/ /// [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/traits/hrtb.html #[derive(derivative::Derivative)] -#[derivative(Clone(bound = ""), Copy(bound = ""), Hash(bound = ""))] +#[derivative(Clone(bound = ""), Copy(bound = ""), Hash(bound = ""), Eq(bound = ""))] #[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable))] pub enum RegionKind { /// A region parameter; for example `'a` in `impl<'a> Trait for &'a ()`. @@ -208,9 +208,6 @@ impl PartialEq for RegionKind { } } -// This is manually implemented because a derive would require `I: Eq` -impl Eq for RegionKind {} - impl DebugWithInfcx for RegionKind { fn fmt>( this: WithInfcx<'_, Infcx, &Self>, diff --git a/compiler/rustc_type_ir/src/trait_ref.rs b/compiler/rustc_type_ir/src/trait_ref.rs index 4bd513ab7e195..3b37df5b39d90 100644 --- a/compiler/rustc_type_ir/src/trait_ref.rs +++ b/compiler/rustc_type_ir/src/trait_ref.rs @@ -1,9 +1,7 @@ use rustc_macros::{HashStable_NoContext, TyDecodable, TyEncodable}; +use rustc_type_ir_macros::{Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic}; -use crate::fold::{FallibleTypeFolder, TypeFoldable}; use crate::inherent::*; -use crate::lift::Lift; -use crate::visit::{TypeVisitable, TypeVisitor}; use crate::Interner; /// A complete reference to a trait. These take numerous guises in syntax, @@ -25,6 +23,7 @@ use crate::Interner; PartialEq(bound = ""), Eq(bound = "") )] +#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)] #[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))] pub struct TraitRef { pub def_id: I::DefId, @@ -68,42 +67,3 @@ impl TraitRef { self.args.type_at(0) } } - -// FIXME(compiler-errors): Make this into a `Lift_Generic` impl. -impl Lift for TraitRef -where - I::DefId: Lift, - I::GenericArgs: Lift, -{ - type Lifted = TraitRef; - - fn lift_to_tcx(self, tcx: U) -> Option { - Some(TraitRef { - def_id: self.def_id.lift_to_tcx(tcx)?, - args: self.args.lift_to_tcx(tcx)?, - _use_trait_ref_new_instead: (), - }) - } -} - -impl TypeVisitable for TraitRef -where - I::GenericArgs: TypeVisitable, -{ - fn visit_with>(&self, visitor: &mut V) -> V::Result { - self.args.visit_with(visitor) - } -} - -impl TypeFoldable for TraitRef -where - I::GenericArgs: TypeFoldable, -{ - fn try_fold_with>(self, folder: &mut F) -> Result { - Ok(TraitRef { - def_id: self.def_id, - args: self.args.try_fold_with(folder)?, - _use_trait_ref_new_instead: (), - }) - } -} diff --git a/compiler/rustc_type_ir/src/ty_kind.rs b/compiler/rustc_type_ir/src/ty_kind.rs index f2e4afecc4025..d67327926ff3b 100644 --- a/compiler/rustc_type_ir/src/ty_kind.rs +++ b/compiler/rustc_type_ir/src/ty_kind.rs @@ -1,14 +1,12 @@ -use rustc_ast_ir::try_visit; #[cfg(feature = "nightly")] use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; #[cfg(feature = "nightly")] use rustc_data_structures::unify::{EqUnifyValue, UnifyKey}; #[cfg(feature = "nightly")] use rustc_macros::{Decodable, Encodable, HashStable_NoContext, TyDecodable, TyEncodable}; +use rustc_type_ir_macros::{TypeFoldable_Generic, TypeVisitable_Generic}; use std::fmt; -use crate::fold::{FallibleTypeFolder, TypeFoldable}; -use crate::visit::{TypeVisitable, TypeVisitor}; use crate::Interner; use crate::{DebruijnIndex, DebugWithInfcx, InferCtxtLike, WithInfcx}; @@ -65,7 +63,7 @@ impl AliasKind { /// converted to this representation using `::lower_ty`. #[cfg_attr(feature = "nightly", rustc_diagnostic_item = "IrTyKind")] #[derive(derivative::Derivative)] -#[derivative(Clone(bound = ""), Copy(bound = ""), Hash(bound = ""))] +#[derivative(Clone(bound = ""), Copy(bound = ""), Hash(bound = ""), Eq(bound = ""))] #[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable, HashStable_NoContext))] pub enum TyKind { /// The primitive boolean type. Written as `bool`. @@ -341,9 +339,6 @@ impl PartialEq for TyKind { } } -// This is manually implemented because a derive would require `I: Eq` -impl Eq for TyKind {} - impl DebugWithInfcx for TyKind { fn fmt>( this: WithInfcx<'_, Infcx, &Self>, @@ -804,29 +799,8 @@ impl DebugWithInfcx for InferTy { Debug(bound = "") )] #[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable, HashStable_NoContext))] +#[derive(TypeVisitable_Generic, TypeFoldable_Generic)] pub struct TypeAndMut { pub ty: I::Ty, pub mutbl: Mutability, } - -impl TypeFoldable for TypeAndMut -where - I::Ty: TypeFoldable, -{ - fn try_fold_with>(self, folder: &mut F) -> Result { - Ok(TypeAndMut { - ty: self.ty.try_fold_with(folder)?, - mutbl: self.mutbl.try_fold_with(folder)?, - }) - } -} - -impl TypeVisitable for TypeAndMut -where - I::Ty: TypeVisitable, -{ - fn visit_with>(&self, visitor: &mut V) -> V::Result { - try_visit!(self.ty.visit_with(visitor)); - self.mutbl.visit_with(visitor) - } -} diff --git a/compiler/rustc_type_ir_macros/Cargo.toml b/compiler/rustc_type_ir_macros/Cargo.toml new file mode 100644 index 0000000000000..cb95ca6834623 --- /dev/null +++ b/compiler/rustc_type_ir_macros/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "rustc_type_ir_macros" +version = "0.0.0" +edition = "2021" + +[lib] +proc-macro = true + +[dependencies] +# tidy-alphabetical-start +proc-macro2 = "1" +quote = "1" +syn = { version = "2.0.9", features = ["full"] } +synstructure = "0.13.0" +# tidy-alphabetical-end diff --git a/compiler/rustc_type_ir_macros/src/lib.rs b/compiler/rustc_type_ir_macros/src/lib.rs new file mode 100644 index 0000000000000..eb45001cc676a --- /dev/null +++ b/compiler/rustc_type_ir_macros/src/lib.rs @@ -0,0 +1,159 @@ +use synstructure::decl_derive; +use quote::quote; +use syn::{parse_quote, visit_mut::VisitMut}; + +decl_derive!( + [TypeFoldable_Generic] => type_foldable_derive +); +decl_derive!( + [TypeVisitable_Generic] => type_visitable_derive +); +decl_derive!( + [Lift_Generic] => lift_derive +); + +fn type_foldable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream { + if let syn::Data::Union(_) = s.ast().data { + panic!("cannot derive on union") + } + + if !s.ast().generics.type_params().any(|ty| ty.ident == "I") { + s.add_impl_generic(parse_quote! { I }); + } + + s.add_where_predicate(parse_quote! { I: Interner }); + s.add_bounds(synstructure::AddBounds::Fields); + s.bind_with(|_| synstructure::BindStyle::Move); + let body_fold = s.each_variant(|vi| { + let bindings = vi.bindings(); + vi.construct(|_, index| { + let bind = &bindings[index]; + quote! { + ::rustc_type_ir::fold::TypeFoldable::try_fold_with(#bind, __folder)? + } + }) + }); + + s.bound_impl( + quote!(::rustc_type_ir::fold::TypeFoldable), + quote! { + fn try_fold_with<__F: ::rustc_type_ir::fold::FallibleTypeFolder>( + self, + __folder: &mut __F + ) -> Result { + Ok(match self { #body_fold }) + } + }, + ) +} + +fn lift_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream { + if let syn::Data::Union(_) = s.ast().data { + panic!("cannot derive on union") + } + + if !s.ast().generics.type_params().any(|ty| ty.ident == "I") { + s.add_impl_generic(parse_quote! { I }); + } + + s.add_bounds(synstructure::AddBounds::None); + s.add_where_predicate(parse_quote! { I: Interner }); + s.add_impl_generic(parse_quote! { J }); + s.add_where_predicate(parse_quote! { J: Interner }); + + let mut wc = vec![]; + s.bind_with(|_| synstructure::BindStyle::Move); + let body_fold = s.each_variant(|vi| { + let bindings = vi.bindings(); + vi.construct(|field, index| { + let ty = field.ty.clone(); + let lifted_ty = lift(ty.clone()); + wc.push(parse_quote! { #ty: ::rustc_type_ir::lift::Lift }); + let bind = &bindings[index]; + quote! { + #bind.lift_to_tcx(interner)? + } + }) + }); + for wc in wc { + s.add_where_predicate(wc); + } + + let (_, ty_generics, _) = s.ast().generics.split_for_impl(); + let name = s.ast().ident.clone(); + let self_ty: syn::Type = parse_quote! { #name #ty_generics }; + let lifted_ty = lift(self_ty); + + s.bound_impl( + quote!(::rustc_type_ir::lift::Lift), + quote! { + type Lifted = #lifted_ty; + + fn lift_to_tcx( + self, + interner: J, + ) -> Option { + Some(match self { #body_fold }) + } + }, + ) +} + +fn lift(mut ty: syn::Type) -> syn::Type { + struct ItoJ; + impl VisitMut for ItoJ { + fn visit_type_path_mut(&mut self, i: &mut syn::TypePath) { + if i.qself.is_none() { + if let Some(first) = i.path.segments.first_mut() { + if first.ident == "I" { + *first = parse_quote! { J }; + } + } + } + syn::visit_mut::visit_type_path_mut(self, i); + } + } + + ItoJ.visit_type_mut(&mut ty); + + ty +} + +fn type_visitable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream { + if let syn::Data::Union(_) = s.ast().data { + panic!("cannot derive on union") + } + + if !s.ast().generics.type_params().any(|ty| ty.ident == "I") { + s.add_impl_generic(parse_quote! { I }); + } + + s.add_where_predicate(parse_quote! { I: Interner }); + s.add_bounds(synstructure::AddBounds::Fields); + let body_visit = s.each(|bind| { + quote! { + match ::rustc_ast_ir::visit::VisitorResult::branch( + ::rustc_type_ir::visit::TypeVisitable::visit_with(#bind, __visitor) + ) { + ::core::ops::ControlFlow::Continue(()) => {}, + ::core::ops::ControlFlow::Break(r) => { + return ::rustc_ast_ir::visit::VisitorResult::from_residual(r); + }, + } + } + }); + s.bind_with(|_| synstructure::BindStyle::Move); + + s.bound_impl( + quote!(::rustc_type_ir::visit::TypeVisitable), + quote! { + fn visit_with<__V: ::rustc_type_ir::visit::TypeVisitor>( + &self, + __visitor: &mut __V + ) -> __V::Result { + match *self { #body_visit } + <__V::Result as ::rustc_ast_ir::visit::VisitorResult>::output() + } + }, + ) +} \ No newline at end of file From 204cde4564665301cb053e004b80b0673d28999f Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 11 May 2024 02:03:53 -0400 Subject: [PATCH 087/179] Uplift `TraitPredicate` --- .../src/opaque_hidden_inferred_bound.rs | 5 +- compiler/rustc_middle/src/ty/mod.rs | 31 -------- compiler/rustc_middle/src/ty/predicate.rs | 31 +------- compiler/rustc_middle/src/ty/print/pretty.rs | 21 ++--- .../rustc_middle/src/ty/structural_impls.rs | 7 -- .../src/traits/error_reporting/suggestions.rs | 4 +- .../error_reporting/type_err_ctxt_ext.rs | 3 +- compiler/rustc_type_ir/Cargo.toml | 4 +- compiler/rustc_type_ir/src/interner.rs | 4 +- compiler/rustc_type_ir/src/ir_print.rs | 12 ++- compiler/rustc_type_ir/src/macros.rs | 1 + compiler/rustc_type_ir/src/trait_ref.rs | 77 +++++++++++++++++++ compiler/rustc_type_ir_macros/src/lib.rs | 4 +- 13 files changed, 114 insertions(+), 90 deletions(-) diff --git a/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs b/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs index 1ea1f496e508e..1d2e12ec575b3 100644 --- a/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs +++ b/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs @@ -1,9 +1,8 @@ use rustc_hir as hir; use rustc_infer::infer::TyCtxtInferExt; use rustc_macros::{LintDiagnostic, Subdiagnostic}; -use rustc_middle::ty::{ - self, fold::BottomUpFolder, print::TraitPredPrintModifiersAndPath, Ty, TypeFoldable, -}; +use rustc_middle::ty::print::{PrintTraitPredicateExt as _, TraitPredPrintModifiersAndPath}; +use rustc_middle::ty::{self, fold::BottomUpFolder, Ty, TypeFoldable}; use rustc_session::{declare_lint, declare_lint_pass}; use rustc_span::{symbol::kw, Span}; use rustc_trait_selection::traits; diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 12cefc23233c0..28baa3348402e 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -299,37 +299,6 @@ impl fmt::Display for ImplPolarity { } } -/// Polarity for a trait predicate. May either be negative or positive. -/// Distinguished from [`ImplPolarity`] since we never compute goals with -/// "reservation" level. -#[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable, HashStable, Debug)] -#[derive(TypeFoldable, TypeVisitable)] -pub enum PredicatePolarity { - /// `Type: Trait` - Positive, - /// `Type: !Trait` - Negative, -} - -impl PredicatePolarity { - /// Flips polarity by turning `Positive` into `Negative` and `Negative` into `Positive`. - pub fn flip(&self) -> PredicatePolarity { - match self { - PredicatePolarity::Positive => PredicatePolarity::Negative, - PredicatePolarity::Negative => PredicatePolarity::Positive, - } - } -} - -impl fmt::Display for PredicatePolarity { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - Self::Positive => f.write_str("positive"), - Self::Negative => f.write_str("negative"), - } - } -} - #[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable, HashStable, Debug)] #[derive(TypeFoldable, TypeVisitable)] pub enum Asyncness { diff --git a/compiler/rustc_middle/src/ty/predicate.rs b/compiler/rustc_middle/src/ty/predicate.rs index 5387036d40912..80a9499e8620d 100644 --- a/compiler/rustc_middle/src/ty/predicate.rs +++ b/compiler/rustc_middle/src/ty/predicate.rs @@ -5,6 +5,7 @@ use rustc_hir::def_id::DefId; use rustc_macros::{HashStable, Lift, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable}; use rustc_type_ir::ClauseKind as IrClauseKind; use rustc_type_ir::PredicateKind as IrPredicateKind; +use rustc_type_ir::TraitPredicate as IrTraitPredicate; use rustc_type_ir::TraitRef as IrTraitRef; use std::cmp::Ordering; @@ -15,6 +16,7 @@ use crate::ty::{ }; pub type TraitRef<'tcx> = IrTraitRef>; +pub type TraitPredicate<'tcx> = IrTraitPredicate>; pub type ClauseKind<'tcx> = IrClauseKind>; pub type PredicateKind<'tcx> = IrPredicateKind>; @@ -578,37 +580,8 @@ impl<'tcx> Clause<'tcx> { } } -#[derive(Clone, Copy, PartialEq, Eq, Hash, TyEncodable, TyDecodable)] -#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)] -pub struct TraitPredicate<'tcx> { - pub trait_ref: TraitRef<'tcx>, - - /// If polarity is Positive: we are proving that the trait is implemented. - /// - /// If polarity is Negative: we are proving that a negative impl of this trait - /// exists. (Note that coherence also checks whether negative impls of supertraits - /// exist via a series of predicates.) - /// - /// If polarity is Reserved: that's a bug. - pub polarity: PredicatePolarity, -} - pub type PolyTraitPredicate<'tcx> = ty::Binder<'tcx, TraitPredicate<'tcx>>; -impl<'tcx> TraitPredicate<'tcx> { - pub fn with_self_ty(self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> Self { - Self { trait_ref: self.trait_ref.with_self_ty(tcx, self_ty), ..self } - } - - pub fn def_id(self) -> DefId { - self.trait_ref.def_id - } - - pub fn self_ty(self) -> Ty<'tcx> { - self.trait_ref.self_ty() - } -} - impl<'tcx> PolyTraitPredicate<'tcx> { pub fn def_id(self) -> DefId { // Ok to skip binder since trait `DefId` does not care about regions. diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 14a628ab064ea..fc42ba6fcd39f 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -2953,8 +2953,9 @@ impl<'tcx> fmt::Debug for TraitPredPrintModifiersAndPath<'tcx> { } } +#[extension(pub trait PrintTraitPredicateExt<'tcx>)] impl<'tcx> ty::TraitPredicate<'tcx> { - pub fn print_modifiers_and_trait_path(self) -> TraitPredPrintModifiersAndPath<'tcx> { + fn print_modifiers_and_trait_path(self) -> TraitPredPrintModifiersAndPath<'tcx> { TraitPredPrintModifiersAndPath(self) } } @@ -3037,6 +3038,15 @@ define_print! { p!(write("<{} as {}>", self.self_ty(), self.print_only_trait_path())) } + ty::TraitPredicate<'tcx> { + p!(print(self.trait_ref.self_ty()), ": "); + p!(pretty_print_bound_constness(self.trait_ref)); + if let ty::PredicatePolarity::Negative = self.polarity { + p!("!"); + } + p!(print(self.trait_ref.print_trait_sugared())) + } + ty::TypeAndMut<'tcx> { p!(write("{}", self.mutbl.prefix_str()), print(self.ty)) } @@ -3176,15 +3186,6 @@ define_print_and_forward_display! { p!(print(self.b)) } - ty::TraitPredicate<'tcx> { - p!(print(self.trait_ref.self_ty()), ": "); - p!(pretty_print_bound_constness(self.trait_ref)); - if let ty::PredicatePolarity::Negative = self.polarity { - p!("!"); - } - p!(print(self.trait_ref.print_trait_sugared())) - } - ty::ProjectionPredicate<'tcx> { p!(print(self.projection_ty), " == "); cx.reset_type_limit(); diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index a7770f719260a..e0fbcb1a7f099 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -158,13 +158,6 @@ impl fmt::Debug for ty::ParamConst { } } -impl<'tcx> fmt::Debug for ty::TraitPredicate<'tcx> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - // FIXME(effects) printing? - write!(f, "TraitPredicate({:?}, polarity:{:?})", self.trait_ref, self.polarity) - } -} - impl<'tcx> fmt::Debug for ty::ProjectionPredicate<'tcx> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "ProjectionPredicate({:?}, {:?})", self.projection_ty, self.term) diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index 51a4e910d621e..ea1752a6e982c 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -45,7 +45,9 @@ use std::iter; use crate::infer::InferCtxtExt as _; use crate::traits::error_reporting::type_err_ctxt_ext::InferCtxtPrivExt; use crate::traits::query::evaluate_obligation::InferCtxtExt as _; -use rustc_middle::ty::print::{with_forced_trimmed_paths, with_no_trimmed_paths}; +use rustc_middle::ty::print::{ + with_forced_trimmed_paths, with_no_trimmed_paths, PrintTraitPredicateExt as _, +}; use itertools::EitherOrBoth; use itertools::Itertools; diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs index 92fe50883d0fd..08ffe37b8b4d0 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs @@ -38,7 +38,8 @@ use rustc_middle::ty::abstract_const::NotConstEvaluatable; use rustc_middle::ty::error::{ExpectedFound, TypeError}; use rustc_middle::ty::fold::{BottomUpFolder, TypeFolder, TypeSuperFoldable}; use rustc_middle::ty::print::{ - with_forced_trimmed_paths, FmtPrinter, Print, PrintTraitRefExt as _, + with_forced_trimmed_paths, FmtPrinter, Print, PrintTraitPredicateExt as _, + PrintTraitRefExt as _, }; use rustc_middle::ty::{ self, SubtypePredicate, ToPolyTraitRef, ToPredicate, TraitRef, Ty, TyCtxt, TypeFoldable, diff --git a/compiler/rustc_type_ir/Cargo.toml b/compiler/rustc_type_ir/Cargo.toml index d12052625ea22..cef3f4e8ce05f 100644 --- a/compiler/rustc_type_ir/Cargo.toml +++ b/compiler/rustc_type_ir/Cargo.toml @@ -11,10 +11,10 @@ rustc_ast_ir = { path = "../rustc_ast_ir" } rustc_data_structures = { path = "../rustc_data_structures", optional = true } rustc_index = { path = "../rustc_index", default-features = false } rustc_macros = { path = "../rustc_macros", optional = true } -rustc_type_ir_macros = { path = "../rustc_type_ir_macros" } rustc_serialize = { path = "../rustc_serialize", optional = true } rustc_span = { path = "../rustc_span", optional = true } -smallvec = { version = "1.8.1" } +rustc_type_ir_macros = { path = "../rustc_type_ir_macros" } +smallvec = { version = "1.8.1", default-features = false } # tidy-alphabetical-end [features] diff --git a/compiler/rustc_type_ir/src/interner.rs b/compiler/rustc_type_ir/src/interner.rs index c8bd7fea11b9f..fe14836b1d52f 100644 --- a/compiler/rustc_type_ir/src/interner.rs +++ b/compiler/rustc_type_ir/src/interner.rs @@ -5,9 +5,9 @@ use std::hash::Hash; use crate::inherent::*; use crate::ir_print::IrPrint; use crate::visit::{Flags, TypeSuperVisitable, TypeVisitable}; -use crate::{CanonicalVarInfo, DebugWithInfcx, TraitRef}; +use crate::{CanonicalVarInfo, DebugWithInfcx, TraitPredicate, TraitRef}; -pub trait Interner: Sized + Copy + IrPrint> { +pub trait Interner: Sized + Copy + IrPrint> + IrPrint> { type DefId: Copy + Debug + Hash + Eq; type DefiningOpaqueTypes: Copy + Debug + Hash + Default + Eq + TypeVisitable; type AdtDef: Copy + Debug + Hash + Eq; diff --git a/compiler/rustc_type_ir/src/ir_print.rs b/compiler/rustc_type_ir/src/ir_print.rs index 84e889b486af1..715fb317669b0 100644 --- a/compiler/rustc_type_ir/src/ir_print.rs +++ b/compiler/rustc_type_ir/src/ir_print.rs @@ -1,6 +1,6 @@ use std::fmt; -use crate::{Interner, TraitRef}; +use crate::{Interner, TraitPredicate, TraitRef}; pub trait IrPrint { fn print(t: &T, fmt: &mut fmt::Formatter<'_>) -> fmt::Result; @@ -15,7 +15,13 @@ macro_rules! define_display_via_print { >>::print(self, fmt) } } + )* + } +} +macro_rules! define_debug_via_print { + ($($ty:ident),+ $(,)?) => { + $( impl fmt::Debug for $ty { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { >>::print_debug(self, fmt) @@ -25,4 +31,6 @@ macro_rules! define_display_via_print { } } -define_display_via_print!(TraitRef,); +define_display_via_print!(TraitRef, TraitPredicate,); + +define_debug_via_print!(TraitRef,); diff --git a/compiler/rustc_type_ir/src/macros.rs b/compiler/rustc_type_ir/src/macros.rs index 7dcc8851a43f2..f2f7b165de52f 100644 --- a/compiler/rustc_type_ir/src/macros.rs +++ b/compiler/rustc_type_ir/src/macros.rs @@ -53,4 +53,5 @@ TrivialTypeTraversalImpls! { crate::UniverseIndex, rustc_ast_ir::Mutability, rustc_ast_ir::Movability, + crate::PredicatePolarity, } diff --git a/compiler/rustc_type_ir/src/trait_ref.rs b/compiler/rustc_type_ir/src/trait_ref.rs index 3b37df5b39d90..0aae75ebf43d8 100644 --- a/compiler/rustc_type_ir/src/trait_ref.rs +++ b/compiler/rustc_type_ir/src/trait_ref.rs @@ -1,3 +1,5 @@ +use std::fmt; + use rustc_macros::{HashStable_NoContext, TyDecodable, TyEncodable}; use rustc_type_ir_macros::{Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic}; @@ -67,3 +69,78 @@ impl TraitRef { self.args.type_at(0) } } + +#[derive(derivative::Derivative)] +#[derivative( + Clone(bound = ""), + Copy(bound = ""), + Hash(bound = ""), + PartialEq(bound = ""), + Eq(bound = "") +)] +#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)] +#[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))] +pub struct TraitPredicate { + pub trait_ref: TraitRef, + + /// If polarity is Positive: we are proving that the trait is implemented. + /// + /// If polarity is Negative: we are proving that a negative impl of this trait + /// exists. (Note that coherence also checks whether negative impls of supertraits + /// exist via a series of predicates.) + /// + /// If polarity is Reserved: that's a bug. + pub polarity: PredicatePolarity, +} + +impl TraitPredicate { + pub fn with_self_ty(self, interner: I, self_ty: I::Ty) -> Self { + Self { trait_ref: self.trait_ref.with_self_ty(interner, self_ty), polarity: self.polarity } + } + + pub fn def_id(self) -> I::DefId { + self.trait_ref.def_id + } + + pub fn self_ty(self) -> I::Ty { + self.trait_ref.self_ty() + } +} + +impl fmt::Debug for TraitPredicate { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + // FIXME(effects) printing? + write!(f, "TraitPredicate({:?}, polarity:{:?})", self.trait_ref, self.polarity) + } +} + +/// Polarity for a trait predicate. May either be negative or positive. +/// Distinguished from [`ImplPolarity`] since we never compute goals with +/// "reservation" level. +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] +#[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))] +pub enum PredicatePolarity { + /// `Type: Trait` + Positive, + /// `Type: !Trait` + Negative, +} + +impl PredicatePolarity { + /// Flips polarity by turning `Positive` into `Negative` and `Negative` into `Positive`. + pub fn flip(&self) -> PredicatePolarity { + match self { + PredicatePolarity::Positive => PredicatePolarity::Negative, + PredicatePolarity::Negative => PredicatePolarity::Positive, + } + } +} + +impl fmt::Display for PredicatePolarity { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Self::Positive => f.write_str("positive"), + Self::Negative => f.write_str("negative"), + } + } +} diff --git a/compiler/rustc_type_ir_macros/src/lib.rs b/compiler/rustc_type_ir_macros/src/lib.rs index eb45001cc676a..000bcf2d3b27d 100644 --- a/compiler/rustc_type_ir_macros/src/lib.rs +++ b/compiler/rustc_type_ir_macros/src/lib.rs @@ -1,6 +1,6 @@ -use synstructure::decl_derive; use quote::quote; use syn::{parse_quote, visit_mut::VisitMut}; +use synstructure::decl_derive; decl_derive!( [TypeFoldable_Generic] => type_foldable_derive @@ -156,4 +156,4 @@ fn type_visitable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::Tok } }, ) -} \ No newline at end of file +} From 0d4dca2b8225a5ed9af715de5c2a07f63fadb26f Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 11 May 2024 12:46:11 -0400 Subject: [PATCH 088/179] Uplift `ExistentialTraitRef`, `ExistentialProjection`, `ProjectionPredicate` --- compiler/rustc_errors/src/diagnostic_impls.rs | 8 + compiler/rustc_middle/src/ty/context.rs | 14 +- compiler/rustc_middle/src/ty/predicate.rs | 147 +-------- compiler/rustc_middle/src/ty/print/pretty.rs | 28 +- .../rustc_middle/src/ty/structural_impls.rs | 12 - compiler/rustc_middle/src/ty/sty.rs | 30 ++ compiler/rustc_type_ir/src/inherent.rs | 28 +- compiler/rustc_type_ir/src/interner.rs | 23 +- compiler/rustc_type_ir/src/ir_print.rs | 15 +- compiler/rustc_type_ir/src/lib.rs | 4 +- compiler/rustc_type_ir/src/predicate.rs | 298 ++++++++++++++++++ compiler/rustc_type_ir/src/trait_ref.rs | 146 --------- 12 files changed, 428 insertions(+), 325 deletions(-) create mode 100644 compiler/rustc_type_ir/src/predicate.rs delete mode 100644 compiler/rustc_type_ir/src/trait_ref.rs diff --git a/compiler/rustc_errors/src/diagnostic_impls.rs b/compiler/rustc_errors/src/diagnostic_impls.rs index 40560a5ad7956..60a2f5469fe6c 100644 --- a/compiler/rustc_errors/src/diagnostic_impls.rs +++ b/compiler/rustc_errors/src/diagnostic_impls.rs @@ -100,6 +100,14 @@ impl IntoDiagArg for rustc_type_ir::TraitRef { } } + + +impl IntoDiagArg for rustc_type_ir::ExistentialTraitRef { + fn into_diag_arg(self) -> DiagArgValue { + self.to_string().into_diag_arg() + } +} + into_diag_arg_for_number!(i8, u8, i16, u16, i32, u32, i64, u64, i128, u128, isize, usize); impl IntoDiagArg for bool { diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 0464be2df0665..93fba3fbc8648 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -99,17 +99,17 @@ impl<'tcx> Interner for TyCtxt<'tcx> { type CanonicalVars = CanonicalVarInfos<'tcx>; type Ty = Ty<'tcx>; - type Pat = Pattern<'tcx>; type Tys = &'tcx List>; type AliasTy = ty::AliasTy<'tcx>; type ParamTy = ParamTy; type BoundTy = ty::BoundTy; type PlaceholderTy = ty::PlaceholderType; - type ErrorGuaranteed = ErrorGuaranteed; + type BoundExistentialPredicates = &'tcx List>; type PolyFnSig = PolyFnSig<'tcx>; type AllocId = crate::mir::interpret::AllocId; + type Pat = Pattern<'tcx>; type Const = ty::Const<'tcx>; type AliasConst = ty::UnevaluatedConst<'tcx>; @@ -121,8 +121,8 @@ impl<'tcx> Interner for TyCtxt<'tcx> { type Region = Region<'tcx>; type EarlyParamRegion = ty::EarlyParamRegion; - type BoundRegion = ty::BoundRegion; type LateParamRegion = ty::LateParamRegion; + type BoundRegion = ty::BoundRegion; type InferRegion = ty::RegionVid; type PlaceholderRegion = ty::PlaceholderRegion; @@ -146,6 +146,10 @@ impl<'tcx> Interner for TyCtxt<'tcx> { self.generics_of(def_id) } + fn mk_args(self, args: &[Self::GenericArg]) -> Self::GenericArgs { + self.mk_args(args) + } + fn check_and_mk_args( self, def_id: DefId, @@ -153,6 +157,10 @@ impl<'tcx> Interner for TyCtxt<'tcx> { ) -> ty::GenericArgsRef<'tcx> { self.check_and_mk_args(def_id, args) } + + fn parent(self, def_id: Self::DefId) -> Self::DefId { + self.parent(def_id) + } } type InternedSet<'tcx, T> = ShardedHashMap, ()>; diff --git a/compiler/rustc_middle/src/ty/predicate.rs b/compiler/rustc_middle/src/ty/predicate.rs index 80a9499e8620d..bc5f75f58c33e 100644 --- a/compiler/rustc_middle/src/ty/predicate.rs +++ b/compiler/rustc_middle/src/ty/predicate.rs @@ -1,21 +1,25 @@ use rustc_data_structures::captures::Captures; use rustc_data_structures::intern::Interned; -use rustc_errors::{DiagArgValue, IntoDiagArg}; use rustc_hir::def_id::DefId; use rustc_macros::{HashStable, Lift, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable}; use rustc_type_ir::ClauseKind as IrClauseKind; use rustc_type_ir::PredicateKind as IrPredicateKind; use rustc_type_ir::TraitPredicate as IrTraitPredicate; use rustc_type_ir::TraitRef as IrTraitRef; +use rustc_type_ir::ProjectionPredicate as IrProjectionPredicate; +use rustc_type_ir::ExistentialTraitRef as IrExistentialTraitRef; +use rustc_type_ir::ExistentialProjection as IrExistentialProjection; use std::cmp::Ordering; -use crate::ty::visit::TypeVisitableExt; use crate::ty::{ - self, AliasTy, Binder, DebruijnIndex, DebugWithInfcx, EarlyBinder, GenericArgsRef, + self, AliasTy, Binder, DebruijnIndex, DebugWithInfcx, EarlyBinder, PredicatePolarity, Term, Ty, TyCtxt, TypeFlags, WithCachedTypeInfo, }; pub type TraitRef<'tcx> = IrTraitRef>; +pub type ProjectionPredicate<'tcx> = IrProjectionPredicate>; +pub type ExistentialTraitRef<'tcx> = IrExistentialTraitRef>; +pub type ExistentialProjection<'tcx> = IrExistentialProjection>; pub type TraitPredicate<'tcx> = IrTraitPredicate>; pub type ClauseKind<'tcx> = IrClauseKind>; pub type PredicateKind<'tcx> = IrPredicateKind>; @@ -342,52 +346,6 @@ impl<'tcx> PolyTraitRef<'tcx> { } } -/// An existential reference to a trait, where `Self` is erased. -/// For example, the trait object `Trait<'a, 'b, X, Y>` is: -/// ```ignore (illustrative) -/// exists T. T: Trait<'a, 'b, X, Y> -/// ``` -/// The generic parameters don't include the erased `Self`, only trait -/// type and lifetime parameters (`[X, Y]` and `['a, 'b]` above). -#[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable)] -#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)] -pub struct ExistentialTraitRef<'tcx> { - pub def_id: DefId, - pub args: GenericArgsRef<'tcx>, -} - -impl<'tcx> ExistentialTraitRef<'tcx> { - pub fn erase_self_ty( - tcx: TyCtxt<'tcx>, - trait_ref: ty::TraitRef<'tcx>, - ) -> ty::ExistentialTraitRef<'tcx> { - // Assert there is a Self. - trait_ref.args.type_at(0); - - ty::ExistentialTraitRef { - def_id: trait_ref.def_id, - args: tcx.mk_args(&trait_ref.args[1..]), - } - } - - /// Object types don't have a self type specified. Therefore, when - /// we convert the principal trait-ref into a normal trait-ref, - /// you must give *some* self type. A common choice is `mk_err()` - /// or some placeholder type. - pub fn with_self_ty(&self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> ty::TraitRef<'tcx> { - // otherwise the escaping vars would be captured by the binder - // debug_assert!(!self_ty.has_escaping_bound_vars()); - - ty::TraitRef::new(tcx, self.def_id, [self_ty.into()].into_iter().chain(self.args.iter())) - } -} - -impl<'tcx> IntoDiagArg for ExistentialTraitRef<'tcx> { - fn into_diag_arg(self) -> DiagArgValue { - self.to_string().into_diag_arg() - } -} - pub type PolyExistentialTraitRef<'tcx> = ty::Binder<'tcx, ExistentialTraitRef<'tcx>>; impl<'tcx> PolyExistentialTraitRef<'tcx> { @@ -404,62 +362,8 @@ impl<'tcx> PolyExistentialTraitRef<'tcx> { } } -/// A `ProjectionPredicate` for an `ExistentialTraitRef`. -#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, TyEncodable, TyDecodable)] -#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)] -pub struct ExistentialProjection<'tcx> { - pub def_id: DefId, - pub args: GenericArgsRef<'tcx>, - pub term: Term<'tcx>, -} - pub type PolyExistentialProjection<'tcx> = ty::Binder<'tcx, ExistentialProjection<'tcx>>; -impl<'tcx> ExistentialProjection<'tcx> { - /// Extracts the underlying existential trait reference from this projection. - /// For example, if this is a projection of `exists T. ::Item == X`, - /// then this function would return an `exists T. T: Iterator` existential trait - /// reference. - pub fn trait_ref(&self, tcx: TyCtxt<'tcx>) -> ty::ExistentialTraitRef<'tcx> { - let def_id = tcx.parent(self.def_id); - let args_count = tcx.generics_of(def_id).count() - 1; - let args = tcx.mk_args(&self.args[..args_count]); - ty::ExistentialTraitRef { def_id, args } - } - - pub fn with_self_ty( - &self, - tcx: TyCtxt<'tcx>, - self_ty: Ty<'tcx>, - ) -> ty::ProjectionPredicate<'tcx> { - // otherwise the escaping regions would be captured by the binders - debug_assert!(!self_ty.has_escaping_bound_vars()); - - ty::ProjectionPredicate { - projection_ty: AliasTy::new( - tcx, - self.def_id, - [self_ty.into()].into_iter().chain(self.args), - ), - term: self.term, - } - } - - pub fn erase_self_ty( - tcx: TyCtxt<'tcx>, - projection_predicate: ty::ProjectionPredicate<'tcx>, - ) -> Self { - // Assert there is a Self. - projection_predicate.projection_ty.args.type_at(0); - - Self { - def_id: projection_predicate.projection_ty.def_id, - args: tcx.mk_args(&projection_predicate.projection_ty.args[1..]), - term: projection_predicate.term, - } - } -} - impl<'tcx> PolyExistentialProjection<'tcx> { pub fn with_self_ty( &self, @@ -628,43 +532,6 @@ pub struct CoercePredicate<'tcx> { } pub type PolyCoercePredicate<'tcx> = ty::Binder<'tcx, CoercePredicate<'tcx>>; -/// This kind of predicate has no *direct* correspondent in the -/// syntax, but it roughly corresponds to the syntactic forms: -/// -/// 1. `T: TraitRef<..., Item = Type>` -/// 2. `>::Item == Type` (NYI) -/// -/// In particular, form #1 is "desugared" to the combination of a -/// normal trait predicate (`T: TraitRef<...>`) and one of these -/// predicates. Form #2 is a broader form in that it also permits -/// equality between arbitrary types. Processing an instance of -/// Form #2 eventually yields one of these `ProjectionPredicate` -/// instances to normalize the LHS. -#[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable)] -#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)] -pub struct ProjectionPredicate<'tcx> { - pub projection_ty: AliasTy<'tcx>, - pub term: Term<'tcx>, -} - -impl<'tcx> ProjectionPredicate<'tcx> { - pub fn self_ty(self) -> Ty<'tcx> { - self.projection_ty.self_ty() - } - - pub fn with_self_ty(self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> ProjectionPredicate<'tcx> { - Self { projection_ty: self.projection_ty.with_self_ty(tcx, self_ty), ..self } - } - - pub fn trait_def_id(self, tcx: TyCtxt<'tcx>) -> DefId { - self.projection_ty.trait_def_id(tcx) - } - - pub fn def_id(self) -> DefId { - self.projection_ty.def_id - } -} - pub type PolyProjectionPredicate<'tcx> = Binder<'tcx, ProjectionPredicate<'tcx>>; impl<'tcx> PolyProjectionPredicate<'tcx> { diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index fc42ba6fcd39f..9e5edb97fe23c 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -3087,14 +3087,6 @@ define_print! { ty::PredicateKind::AliasRelate(t1, t2, dir) => p!(print(t1), write(" {} ", dir), print(t2)), } } -} - -define_print_and_forward_display! { - (self, cx): - - &'tcx ty::List> { - p!("{{", comma_sep(self.iter()), "}}") - } ty::ExistentialTraitRef<'tcx> { // Use a type that can't appear in defaults of type parameters. @@ -3108,6 +3100,20 @@ define_print_and_forward_display! { p!(write("{} = ", name), print(self.term)) } + ty::ProjectionPredicate<'tcx> { + p!(print(self.projection_ty), " == "); + cx.reset_type_limit(); + p!(print(self.term)) + } +} + +define_print_and_forward_display! { + (self, cx): + + &'tcx ty::List> { + p!("{{", comma_sep(self.iter()), "}}") + } + ty::ExistentialPredicate<'tcx> { match *self { ty::ExistentialPredicate::Trait(x) => p!(print(x)), @@ -3186,12 +3192,6 @@ define_print_and_forward_display! { p!(print(self.b)) } - ty::ProjectionPredicate<'tcx> { - p!(print(self.projection_ty), " == "); - cx.reset_type_limit(); - p!(print(self.term)) - } - ty::NormalizesTo<'tcx> { p!(print(self.alias), " normalizes-to "); cx.reset_type_limit(); diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index e0fbcb1a7f099..b08ae4e58909c 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -55,12 +55,6 @@ impl fmt::Debug for ty::UpvarId { } } -impl<'tcx> fmt::Debug for ty::ExistentialTraitRef<'tcx> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - with_no_trimmed_paths!(fmt::Display::fmt(self, f)) - } -} - impl<'tcx> fmt::Debug for ty::adjustment::Adjustment<'tcx> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{:?} -> {}", self.kind, self.target) @@ -158,12 +152,6 @@ impl fmt::Debug for ty::ParamConst { } } -impl<'tcx> fmt::Debug for ty::ProjectionPredicate<'tcx> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "ProjectionPredicate({:?}, {:?})", self.projection_ty, self.term) - } -} - impl<'tcx> fmt::Debug for ty::NormalizesTo<'tcx> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "NormalizesTo({:?}, {:?})", self.alias, self.term) diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index a97244dda9a87..1fc8eefd65fb1 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -1142,6 +1142,36 @@ pub struct AliasTy<'tcx> { _use_alias_ty_new_instead: (), } +impl<'tcx> rustc_type_ir::inherent::AliasTy> for AliasTy<'tcx> { + fn new( + interner: TyCtxt<'tcx>, + trait_def_id: DefId, + args: impl IntoIterator>>, + ) -> Self { + AliasTy::new(interner, trait_def_id, args) + } + + fn def_id(self) -> DefId { + self.def_id + } + + fn args(self) -> ty::GenericArgsRef<'tcx> { + self.args + } + + fn trait_def_id(self, interner: TyCtxt<'tcx>) -> DefId { + self.trait_def_id(interner) + } + + fn self_ty(self) -> Ty<'tcx> { + self.self_ty() + } + + fn with_self_ty(self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> Self { + self.with_self_ty(tcx, self_ty) + } +} + impl<'tcx> AliasTy<'tcx> { pub fn new( tcx: TyCtxt<'tcx>, diff --git a/compiler/rustc_type_ir/src/inherent.rs b/compiler/rustc_type_ir/src/inherent.rs index 0fd34e0a65f65..cf67f82efd7f0 100644 --- a/compiler/rustc_type_ir/src/inherent.rs +++ b/compiler/rustc_type_ir/src/inherent.rs @@ -1,5 +1,6 @@ use std::fmt::Debug; use std::hash::Hash; +use std::ops::Deref; use crate::fold::TypeSuperFoldable; use crate::visit::{Flags, TypeSuperVisitable}; @@ -50,7 +51,12 @@ pub trait GenericsOf> { } pub trait GenericArgs>: - Copy + DebugWithInfcx + Hash + Eq + IntoIterator + Copy + + DebugWithInfcx + + Hash + + Eq + + IntoIterator + + Deref> { fn type_at(self, i: usize) -> I::Ty; @@ -83,3 +89,23 @@ pub trait BoundVars { fn has_no_bound_vars(&self) -> bool; } + +// TODO: Uplift `AliasTy` +pub trait AliasTy: Copy + DebugWithInfcx + Hash + Eq + Sized { + fn new( + interner: I, + trait_def_id: I::DefId, + args: impl IntoIterator>, + ) -> Self; + + fn def_id(self) -> I::DefId; + + fn args(self) -> I::GenericArgs; + + fn trait_def_id(self, interner: I) -> I::DefId; + + fn self_ty(self) -> I::Ty; + + fn with_self_ty(self, tcx: I, self_ty: I::Ty) -> Self; + +} diff --git a/compiler/rustc_type_ir/src/interner.rs b/compiler/rustc_type_ir/src/interner.rs index fe14836b1d52f..bfa769237a193 100644 --- a/compiler/rustc_type_ir/src/interner.rs +++ b/compiler/rustc_type_ir/src/interner.rs @@ -5,9 +5,20 @@ use std::hash::Hash; use crate::inherent::*; use crate::ir_print::IrPrint; use crate::visit::{Flags, TypeSuperVisitable, TypeVisitable}; -use crate::{CanonicalVarInfo, DebugWithInfcx, TraitPredicate, TraitRef}; - -pub trait Interner: Sized + Copy + IrPrint> + IrPrint> { +use crate::{ + CanonicalVarInfo, DebugWithInfcx, ExistentialProjection, ExistentialTraitRef, + ProjectionPredicate, TraitPredicate, TraitRef, +}; + +pub trait Interner: + Sized + + Copy + + IrPrint> + + IrPrint> + + IrPrint> + + IrPrint> + + IrPrint> +{ type DefId: Copy + Debug + Hash + Eq; type DefiningOpaqueTypes: Copy + Debug + Hash + Default + Eq + TypeVisitable; type AdtDef: Copy + Debug + Hash + Eq; @@ -25,7 +36,7 @@ pub trait Interner: Sized + Copy + IrPrint> + IrPrint; type Tys: Copy + Debug + Hash + Eq + IntoIterator; - type AliasTy: Copy + DebugWithInfcx + Hash + Eq; + type AliasTy: AliasTy; type ParamTy: Copy + Debug + Hash + Eq; type BoundTy: Copy + Debug + Hash + Eq; type PlaceholderTy: PlaceholderLike; @@ -71,11 +82,15 @@ pub trait Interner: Sized + Copy + IrPrint> + IrPrint; fn generics_of(self, def_id: Self::DefId) -> Self::GenericsOf; + fn mk_args(self, args: &[Self::GenericArg]) -> Self::GenericArgs; + fn check_and_mk_args( self, def_id: Self::DefId, args: impl IntoIterator>, ) -> Self::GenericArgs; + + fn parent(self, def_id: Self::DefId) -> Self::DefId; } /// Imagine you have a function `F: FnOnce(&[T]) -> R`, plus an iterator `iter` diff --git a/compiler/rustc_type_ir/src/ir_print.rs b/compiler/rustc_type_ir/src/ir_print.rs index 715fb317669b0..9b72764b4d1fa 100644 --- a/compiler/rustc_type_ir/src/ir_print.rs +++ b/compiler/rustc_type_ir/src/ir_print.rs @@ -1,6 +1,9 @@ use std::fmt; -use crate::{Interner, TraitPredicate, TraitRef}; +use crate::{ + ExistentialProjection, ExistentialTraitRef, Interner, ProjectionPredicate, TraitPredicate, + TraitRef, +}; pub trait IrPrint { fn print(t: &T, fmt: &mut fmt::Formatter<'_>) -> fmt::Result; @@ -31,6 +34,12 @@ macro_rules! define_debug_via_print { } } -define_display_via_print!(TraitRef, TraitPredicate,); +define_display_via_print!( + TraitRef, + TraitPredicate, + ExistentialTraitRef, + ExistentialProjection, + ProjectionPredicate +); -define_debug_via_print!(TraitRef,); +define_debug_via_print!(TraitRef, ExistentialTraitRef, ExistentialProjection); diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs index 62efa32c9f2fc..184b882c2b75f 100644 --- a/compiler/rustc_type_ir/src/lib.rs +++ b/compiler/rustc_type_ir/src/lib.rs @@ -39,7 +39,7 @@ mod infcx; mod interner; mod predicate_kind; mod region_kind; -mod trait_ref; +mod predicate; pub use canonical::*; #[cfg(feature = "nightly")] @@ -51,7 +51,7 @@ pub use infcx::InferCtxtLike; pub use interner::*; pub use predicate_kind::*; pub use region_kind::*; -pub use trait_ref::*; +pub use predicate::*; pub use ty_info::*; pub use ty_kind::*; pub use AliasKind::*; diff --git a/compiler/rustc_type_ir/src/predicate.rs b/compiler/rustc_type_ir/src/predicate.rs new file mode 100644 index 0000000000000..9cd9319a1b1c1 --- /dev/null +++ b/compiler/rustc_type_ir/src/predicate.rs @@ -0,0 +1,298 @@ +use std::fmt; + +use rustc_macros::{HashStable_NoContext, TyDecodable, TyEncodable}; +use rustc_type_ir_macros::{Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic}; + +use crate::inherent::*; +use crate::visit::TypeVisitableExt as _; +use crate::Interner; + +/// A complete reference to a trait. These take numerous guises in syntax, +/// but perhaps the most recognizable form is in a where-clause: +/// ```ignore (illustrative) +/// T: Foo +/// ``` +/// This would be represented by a trait-reference where the `DefId` is the +/// `DefId` for the trait `Foo` and the args define `T` as parameter 0, +/// and `U` as parameter 1. +/// +/// Trait references also appear in object types like `Foo`, but in +/// that case the `Self` parameter is absent from the generic parameters. +#[derive(derivative::Derivative)] +#[derivative( + Clone(bound = ""), + Copy(bound = ""), + Hash(bound = ""), + PartialEq(bound = ""), + Eq(bound = "") +)] +#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)] +#[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))] +pub struct TraitRef { + pub def_id: I::DefId, + pub args: I::GenericArgs, + /// This field exists to prevent the creation of `TraitRef` without + /// calling [`TraitRef::new`]. + _use_trait_ref_new_instead: (), +} + +impl TraitRef { + pub fn new( + interner: I, + trait_def_id: I::DefId, + args: impl IntoIterator>, + ) -> Self { + let args = interner.check_and_mk_args(trait_def_id, args); + Self { def_id: trait_def_id, args, _use_trait_ref_new_instead: () } + } + + pub fn from_method(interner: I, trait_id: I::DefId, args: I::GenericArgs) -> TraitRef { + let generics = interner.generics_of(trait_id); + TraitRef::new(interner, trait_id, args.into_iter().take(generics.count())) + } + + /// Returns a `TraitRef` of the form `P0: Foo` where `Pi` + /// are the parameters defined on trait. + pub fn identity(interner: I, def_id: I::DefId) -> TraitRef { + TraitRef::new(interner, def_id, I::GenericArgs::identity_for_item(interner, def_id)) + } + + pub fn with_self_ty(self, interner: I, self_ty: I::Ty) -> Self { + TraitRef::new( + interner, + self.def_id, + [self_ty.into()].into_iter().chain(self.args.into_iter().skip(1)), + ) + } + + #[inline] + pub fn self_ty(&self) -> I::Ty { + self.args.type_at(0) + } +} + +#[derive(derivative::Derivative)] +#[derivative( + Clone(bound = ""), + Copy(bound = ""), + Hash(bound = ""), + PartialEq(bound = ""), + Eq(bound = "") +)] +#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)] +#[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))] +pub struct TraitPredicate { + pub trait_ref: TraitRef, + + /// If polarity is Positive: we are proving that the trait is implemented. + /// + /// If polarity is Negative: we are proving that a negative impl of this trait + /// exists. (Note that coherence also checks whether negative impls of supertraits + /// exist via a series of predicates.) + /// + /// If polarity is Reserved: that's a bug. + pub polarity: PredicatePolarity, +} + +impl TraitPredicate { + pub fn with_self_ty(self, interner: I, self_ty: I::Ty) -> Self { + Self { trait_ref: self.trait_ref.with_self_ty(interner, self_ty), polarity: self.polarity } + } + + pub fn def_id(self) -> I::DefId { + self.trait_ref.def_id + } + + pub fn self_ty(self) -> I::Ty { + self.trait_ref.self_ty() + } +} + +impl fmt::Debug for TraitPredicate { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + // FIXME(effects) printing? + write!(f, "TraitPredicate({:?}, polarity:{:?})", self.trait_ref, self.polarity) + } +} + +/// Polarity for a trait predicate. May either be negative or positive. +/// Distinguished from [`ImplPolarity`] since we never compute goals with +/// "reservation" level. +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] +#[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))] +pub enum PredicatePolarity { + /// `Type: Trait` + Positive, + /// `Type: !Trait` + Negative, +} + +impl PredicatePolarity { + /// Flips polarity by turning `Positive` into `Negative` and `Negative` into `Positive`. + pub fn flip(&self) -> PredicatePolarity { + match self { + PredicatePolarity::Positive => PredicatePolarity::Negative, + PredicatePolarity::Negative => PredicatePolarity::Positive, + } + } +} + +impl fmt::Display for PredicatePolarity { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Self::Positive => f.write_str("positive"), + Self::Negative => f.write_str("negative"), + } + } +} + +/// An existential reference to a trait, where `Self` is erased. +/// For example, the trait object `Trait<'a, 'b, X, Y>` is: +/// ```ignore (illustrative) +/// exists T. T: Trait<'a, 'b, X, Y> +/// ``` +/// The generic parameters don't include the erased `Self`, only trait +/// type and lifetime parameters (`[X, Y]` and `['a, 'b]` above). +#[derive(derivative::Derivative)] +#[derivative( + Clone(bound = ""), + Copy(bound = ""), + Hash(bound = ""), + PartialEq(bound = ""), + Eq(bound = "") +)] +#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)] +#[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))] +pub struct ExistentialTraitRef { + pub def_id: I::DefId, + pub args: I::GenericArgs, +} + +impl ExistentialTraitRef { + pub fn erase_self_ty(interner: I, trait_ref: TraitRef) -> ExistentialTraitRef { + // Assert there is a Self. + trait_ref.args.type_at(0); + + ExistentialTraitRef { + def_id: trait_ref.def_id, + args: interner.mk_args(&trait_ref.args[1..]), + } + } + + /// Object types don't have a self type specified. Therefore, when + /// we convert the principal trait-ref into a normal trait-ref, + /// you must give *some* self type. A common choice is `mk_err()` + /// or some placeholder type. + pub fn with_self_ty(self, interner: I, self_ty: I::Ty) -> TraitRef { + // otherwise the escaping vars would be captured by the binder + // debug_assert!(!self_ty.has_escaping_bound_vars()); + + TraitRef::new(interner, self.def_id, [self_ty.into()].into_iter().chain(self.args.into_iter())) + } +} + +/// A `ProjectionPredicate` for an `ExistentialTraitRef`. +#[derive(derivative::Derivative)] +#[derivative( + Clone(bound = ""), + Copy(bound = ""), + Hash(bound = ""), + PartialEq(bound = ""), + Eq(bound = "") +)] +#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)] +#[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))] +pub struct ExistentialProjection { + pub def_id: I::DefId, + pub args: I::GenericArgs, + pub term: I::Term, +} + +impl ExistentialProjection { + /// Extracts the underlying existential trait reference from this projection. + /// For example, if this is a projection of `exists T. ::Item == X`, + /// then this function would return an `exists T. T: Iterator` existential trait + /// reference. + pub fn trait_ref(&self, tcx: I) -> ExistentialTraitRef { + let def_id = tcx.parent(self.def_id); + let args_count = tcx.generics_of(def_id).count() - 1; + let args = tcx.mk_args(&self.args[..args_count]); + ExistentialTraitRef { def_id, args } + } + + pub fn with_self_ty(&self, tcx: I, self_ty: I::Ty) -> ProjectionPredicate { + // otherwise the escaping regions would be captured by the binders + debug_assert!(!self_ty.has_escaping_bound_vars()); + + ProjectionPredicate { + projection_ty: I::AliasTy::new( + tcx, + self.def_id, + [self_ty.into()].into_iter().chain(self.args), + ), + term: self.term, + } + } + + pub fn erase_self_ty(tcx: I, projection_predicate: ProjectionPredicate) -> Self { + // Assert there is a Self. + projection_predicate.projection_ty.args().type_at(0); + + Self { + def_id: projection_predicate.projection_ty.def_id(), + args: tcx.mk_args(&projection_predicate.projection_ty.args()[1..]), + term: projection_predicate.term, + } + } +} + +/// This kind of predicate has no *direct* correspondent in the +/// syntax, but it roughly corresponds to the syntactic forms: +/// +/// 1. `T: TraitRef<..., Item = Type>` +/// 2. `>::Item == Type` (NYI) +/// +/// In particular, form #1 is "desugared" to the combination of a +/// normal trait predicate (`T: TraitRef<...>`) and one of these +/// predicates. Form #2 is a broader form in that it also permits +/// equality between arbitrary types. Processing an instance of +/// Form #2 eventually yields one of these `ProjectionPredicate` +/// instances to normalize the LHS. +#[derive(derivative::Derivative)] +#[derivative( + Clone(bound = ""), + Copy(bound = ""), + Hash(bound = ""), + PartialEq(bound = ""), + Eq(bound = "") +)] +#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)] +#[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))] +pub struct ProjectionPredicate { + pub projection_ty: I::AliasTy, + pub term: I::Term, +} + +impl ProjectionPredicate { + pub fn self_ty(self) -> I::Ty { + self.projection_ty.self_ty() + } + + pub fn with_self_ty(self, tcx: I, self_ty: I::Ty) -> ProjectionPredicate { + Self { projection_ty: self.projection_ty.with_self_ty(tcx, self_ty), ..self } + } + + pub fn trait_def_id(self, tcx: I) -> I::DefId { + self.projection_ty.trait_def_id(tcx) + } + + pub fn def_id(self) -> I::DefId { + self.projection_ty.def_id() + } +} + +impl fmt::Debug for ProjectionPredicate { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "ProjectionPredicate({:?}, {:?})", self.projection_ty, self.term) + } +} diff --git a/compiler/rustc_type_ir/src/trait_ref.rs b/compiler/rustc_type_ir/src/trait_ref.rs deleted file mode 100644 index 0aae75ebf43d8..0000000000000 --- a/compiler/rustc_type_ir/src/trait_ref.rs +++ /dev/null @@ -1,146 +0,0 @@ -use std::fmt; - -use rustc_macros::{HashStable_NoContext, TyDecodable, TyEncodable}; -use rustc_type_ir_macros::{Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic}; - -use crate::inherent::*; -use crate::Interner; - -/// A complete reference to a trait. These take numerous guises in syntax, -/// but perhaps the most recognizable form is in a where-clause: -/// ```ignore (illustrative) -/// T: Foo -/// ``` -/// This would be represented by a trait-reference where the `DefId` is the -/// `DefId` for the trait `Foo` and the args define `T` as parameter 0, -/// and `U` as parameter 1. -/// -/// Trait references also appear in object types like `Foo`, but in -/// that case the `Self` parameter is absent from the generic parameters. -#[derive(derivative::Derivative)] -#[derivative( - Clone(bound = ""), - Copy(bound = ""), - Hash(bound = ""), - PartialEq(bound = ""), - Eq(bound = "") -)] -#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)] -#[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))] -pub struct TraitRef { - pub def_id: I::DefId, - pub args: I::GenericArgs, - /// This field exists to prevent the creation of `TraitRef` without - /// calling [`TraitRef::new`]. - _use_trait_ref_new_instead: (), -} - -impl TraitRef { - pub fn new( - interner: I, - trait_def_id: I::DefId, - args: impl IntoIterator>, - ) -> Self { - let args = interner.check_and_mk_args(trait_def_id, args); - Self { def_id: trait_def_id, args, _use_trait_ref_new_instead: () } - } - - pub fn from_method(interner: I, trait_id: I::DefId, args: I::GenericArgs) -> TraitRef { - let generics = interner.generics_of(trait_id); - TraitRef::new(interner, trait_id, args.into_iter().take(generics.count())) - } - - /// Returns a `TraitRef` of the form `P0: Foo` where `Pi` - /// are the parameters defined on trait. - pub fn identity(interner: I, def_id: I::DefId) -> TraitRef { - TraitRef::new(interner, def_id, I::GenericArgs::identity_for_item(interner, def_id)) - } - - pub fn with_self_ty(self, interner: I, self_ty: I::Ty) -> Self { - TraitRef::new( - interner, - self.def_id, - [self_ty.into()].into_iter().chain(self.args.into_iter().skip(1)), - ) - } - - #[inline] - pub fn self_ty(&self) -> I::Ty { - self.args.type_at(0) - } -} - -#[derive(derivative::Derivative)] -#[derivative( - Clone(bound = ""), - Copy(bound = ""), - Hash(bound = ""), - PartialEq(bound = ""), - Eq(bound = "") -)] -#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)] -#[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))] -pub struct TraitPredicate { - pub trait_ref: TraitRef, - - /// If polarity is Positive: we are proving that the trait is implemented. - /// - /// If polarity is Negative: we are proving that a negative impl of this trait - /// exists. (Note that coherence also checks whether negative impls of supertraits - /// exist via a series of predicates.) - /// - /// If polarity is Reserved: that's a bug. - pub polarity: PredicatePolarity, -} - -impl TraitPredicate { - pub fn with_self_ty(self, interner: I, self_ty: I::Ty) -> Self { - Self { trait_ref: self.trait_ref.with_self_ty(interner, self_ty), polarity: self.polarity } - } - - pub fn def_id(self) -> I::DefId { - self.trait_ref.def_id - } - - pub fn self_ty(self) -> I::Ty { - self.trait_ref.self_ty() - } -} - -impl fmt::Debug for TraitPredicate { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - // FIXME(effects) printing? - write!(f, "TraitPredicate({:?}, polarity:{:?})", self.trait_ref, self.polarity) - } -} - -/// Polarity for a trait predicate. May either be negative or positive. -/// Distinguished from [`ImplPolarity`] since we never compute goals with -/// "reservation" level. -#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] -#[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))] -pub enum PredicatePolarity { - /// `Type: Trait` - Positive, - /// `Type: !Trait` - Negative, -} - -impl PredicatePolarity { - /// Flips polarity by turning `Positive` into `Negative` and `Negative` into `Positive`. - pub fn flip(&self) -> PredicatePolarity { - match self { - PredicatePolarity::Positive => PredicatePolarity::Negative, - PredicatePolarity::Negative => PredicatePolarity::Positive, - } - } -} - -impl fmt::Display for PredicatePolarity { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - Self::Positive => f.write_str("positive"), - Self::Negative => f.write_str("negative"), - } - } -} From 0a8f33830c1ff5607ab731bc40b07fd0a15edfd8 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 11 May 2024 13:51:25 -0400 Subject: [PATCH 089/179] Uplift `NormalizesTo`, `CoercePredicate`, and `SubtypePredicate` --- compiler/rustc_errors/src/diagnostic_impls.rs | 2 - compiler/rustc_middle/src/ty/context.rs | 4 +- compiler/rustc_middle/src/ty/predicate.rs | 60 +++---------- compiler/rustc_middle/src/ty/print/pretty.rs | 36 ++++---- .../rustc_middle/src/ty/structural_impls.rs | 6 -- compiler/rustc_type_ir/src/inherent.rs | 3 +- compiler/rustc_type_ir/src/interner.rs | 7 +- compiler/rustc_type_ir/src/ir_print.rs | 9 +- compiler/rustc_type_ir/src/lib.rs | 4 +- compiler/rustc_type_ir/src/predicate.rs | 84 ++++++++++++++++++- 10 files changed, 128 insertions(+), 87 deletions(-) diff --git a/compiler/rustc_errors/src/diagnostic_impls.rs b/compiler/rustc_errors/src/diagnostic_impls.rs index 60a2f5469fe6c..2cc0167dbaa6e 100644 --- a/compiler/rustc_errors/src/diagnostic_impls.rs +++ b/compiler/rustc_errors/src/diagnostic_impls.rs @@ -100,8 +100,6 @@ impl IntoDiagArg for rustc_type_ir::TraitRef { } } - - impl IntoDiagArg for rustc_type_ir::ExistentialTraitRef { fn into_diag_arg(self) -> DiagArgValue { self.to_string().into_diag_arg() diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 93fba3fbc8648..70fb937cae7ad 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -149,7 +149,7 @@ impl<'tcx> Interner for TyCtxt<'tcx> { fn mk_args(self, args: &[Self::GenericArg]) -> Self::GenericArgs { self.mk_args(args) } - + fn check_and_mk_args( self, def_id: DefId, @@ -157,7 +157,7 @@ impl<'tcx> Interner for TyCtxt<'tcx> { ) -> ty::GenericArgsRef<'tcx> { self.check_and_mk_args(def_id, args) } - + fn parent(self, def_id: Self::DefId) -> Self::DefId { self.parent(def_id) } diff --git a/compiler/rustc_middle/src/ty/predicate.rs b/compiler/rustc_middle/src/ty/predicate.rs index bc5f75f58c33e..dbbb86cb28e1c 100644 --- a/compiler/rustc_middle/src/ty/predicate.rs +++ b/compiler/rustc_middle/src/ty/predicate.rs @@ -3,17 +3,20 @@ use rustc_data_structures::intern::Interned; use rustc_hir::def_id::DefId; use rustc_macros::{HashStable, Lift, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable}; use rustc_type_ir::ClauseKind as IrClauseKind; +use rustc_type_ir::CoercePredicate as IrCoercePredicate; +use rustc_type_ir::ExistentialProjection as IrExistentialProjection; +use rustc_type_ir::ExistentialTraitRef as IrExistentialTraitRef; +use rustc_type_ir::NormalizesTo as IrNormalizesTo; use rustc_type_ir::PredicateKind as IrPredicateKind; +use rustc_type_ir::ProjectionPredicate as IrProjectionPredicate; +use rustc_type_ir::SubtypePredicate as IrSubtypePredicate; use rustc_type_ir::TraitPredicate as IrTraitPredicate; use rustc_type_ir::TraitRef as IrTraitRef; -use rustc_type_ir::ProjectionPredicate as IrProjectionPredicate; -use rustc_type_ir::ExistentialTraitRef as IrExistentialTraitRef; -use rustc_type_ir::ExistentialProjection as IrExistentialProjection; use std::cmp::Ordering; use crate::ty::{ - self, AliasTy, Binder, DebruijnIndex, DebugWithInfcx, EarlyBinder, - PredicatePolarity, Term, Ty, TyCtxt, TypeFlags, WithCachedTypeInfo, + self, Binder, DebruijnIndex, DebugWithInfcx, EarlyBinder, PredicatePolarity, Term, Ty, TyCtxt, + TypeFlags, WithCachedTypeInfo, }; pub type TraitRef<'tcx> = IrTraitRef>; @@ -23,6 +26,9 @@ pub type ExistentialProjection<'tcx> = IrExistentialProjection>; pub type TraitPredicate<'tcx> = IrTraitPredicate>; pub type ClauseKind<'tcx> = IrClauseKind>; pub type PredicateKind<'tcx> = IrPredicateKind>; +pub type NormalizesTo<'tcx> = IrNormalizesTo>; +pub type CoercePredicate<'tcx> = IrCoercePredicate>; +pub type SubtypePredicate<'tcx> = IrSubtypePredicate>; /// A statement that can be proven by a trait solver. This includes things that may /// show up in where clauses, such as trait predicates and projection predicates, @@ -511,25 +517,8 @@ pub type TypeOutlivesPredicate<'tcx> = OutlivesPredicate, ty::Region<'t pub type PolyRegionOutlivesPredicate<'tcx> = ty::Binder<'tcx, RegionOutlivesPredicate<'tcx>>; pub type PolyTypeOutlivesPredicate<'tcx> = ty::Binder<'tcx, TypeOutlivesPredicate<'tcx>>; -/// Encodes that `a` must be a subtype of `b`. The `a_is_expected` flag indicates -/// whether the `a` type is the type that we should label as "expected" when -/// presenting user diagnostics. -#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, TyEncodable, TyDecodable)] -#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)] -pub struct SubtypePredicate<'tcx> { - pub a_is_expected: bool, - pub a: Ty<'tcx>, - pub b: Ty<'tcx>, -} pub type PolySubtypePredicate<'tcx> = ty::Binder<'tcx, SubtypePredicate<'tcx>>; -/// Encodes that we have to coerce *from* the `a` type to the `b` type. -#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, TyEncodable, TyDecodable)] -#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)] -pub struct CoercePredicate<'tcx> { - pub a: Ty<'tcx>, - pub b: Ty<'tcx>, -} pub type PolyCoercePredicate<'tcx> = ty::Binder<'tcx, CoercePredicate<'tcx>>; pub type PolyProjectionPredicate<'tcx> = Binder<'tcx, ProjectionPredicate<'tcx>>; @@ -568,33 +557,6 @@ impl<'tcx> PolyProjectionPredicate<'tcx> { } } -/// Used by the new solver. Unlike a `ProjectionPredicate` this can only be -/// proven by actually normalizing `alias`. -#[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable)] -#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)] -pub struct NormalizesTo<'tcx> { - pub alias: AliasTy<'tcx>, - pub term: Term<'tcx>, -} - -impl<'tcx> NormalizesTo<'tcx> { - pub fn self_ty(self) -> Ty<'tcx> { - self.alias.self_ty() - } - - pub fn with_self_ty(self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> NormalizesTo<'tcx> { - Self { alias: self.alias.with_self_ty(tcx, self_ty), ..self } - } - - pub fn trait_def_id(self, tcx: TyCtxt<'tcx>) -> DefId { - self.alias.trait_def_id(tcx) - } - - pub fn def_id(self) -> DefId { - self.alias.def_id - } -} - pub trait ToPolyTraitRef<'tcx> { fn to_poly_trait_ref(&self) -> PolyTraitRef<'tcx>; } diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 9e5edb97fe23c..6137a5fd48a80 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -3105,6 +3105,24 @@ define_print! { cx.reset_type_limit(); p!(print(self.term)) } + + ty::SubtypePredicate<'tcx> { + p!(print(self.a), " <: "); + cx.reset_type_limit(); + p!(print(self.b)) + } + + ty::CoercePredicate<'tcx> { + p!(print(self.a), " -> "); + cx.reset_type_limit(); + p!(print(self.b)) + } + + ty::NormalizesTo<'tcx> { + p!(print(self.alias), " normalizes-to "); + cx.reset_type_limit(); + p!(print(self.term)) + } } define_print_and_forward_display! { @@ -3180,24 +3198,6 @@ define_print_and_forward_display! { p!(write("{}", self.name)) } - ty::SubtypePredicate<'tcx> { - p!(print(self.a), " <: "); - cx.reset_type_limit(); - p!(print(self.b)) - } - - ty::CoercePredicate<'tcx> { - p!(print(self.a), " -> "); - cx.reset_type_limit(); - p!(print(self.b)) - } - - ty::NormalizesTo<'tcx> { - p!(print(self.alias), " normalizes-to "); - cx.reset_type_limit(); - p!(print(self.term)) - } - ty::Term<'tcx> { match self.unpack() { ty::TermKind::Ty(ty) => p!(print(ty)), diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index b08ae4e58909c..dc071b295aad3 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -152,12 +152,6 @@ impl fmt::Debug for ty::ParamConst { } } -impl<'tcx> fmt::Debug for ty::NormalizesTo<'tcx> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "NormalizesTo({:?}, {:?})", self.alias, self.term) - } -} - impl<'tcx> fmt::Debug for ty::Predicate<'tcx> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{:?}", self.kind()) diff --git a/compiler/rustc_type_ir/src/inherent.rs b/compiler/rustc_type_ir/src/inherent.rs index cf67f82efd7f0..a50967a3b182a 100644 --- a/compiler/rustc_type_ir/src/inherent.rs +++ b/compiler/rustc_type_ir/src/inherent.rs @@ -90,7 +90,7 @@ pub trait BoundVars { fn has_no_bound_vars(&self) -> bool; } -// TODO: Uplift `AliasTy` +// FIXME: Uplift `AliasTy` pub trait AliasTy: Copy + DebugWithInfcx + Hash + Eq + Sized { fn new( interner: I, @@ -107,5 +107,4 @@ pub trait AliasTy: Copy + DebugWithInfcx + Hash + Eq + Sized { fn self_ty(self) -> I::Ty; fn with_self_ty(self, tcx: I, self_ty: I::Ty) -> Self; - } diff --git a/compiler/rustc_type_ir/src/interner.rs b/compiler/rustc_type_ir/src/interner.rs index bfa769237a193..17d9f4242fdfa 100644 --- a/compiler/rustc_type_ir/src/interner.rs +++ b/compiler/rustc_type_ir/src/interner.rs @@ -6,8 +6,8 @@ use crate::inherent::*; use crate::ir_print::IrPrint; use crate::visit::{Flags, TypeSuperVisitable, TypeVisitable}; use crate::{ - CanonicalVarInfo, DebugWithInfcx, ExistentialProjection, ExistentialTraitRef, - ProjectionPredicate, TraitPredicate, TraitRef, + CanonicalVarInfo, CoercePredicate, DebugWithInfcx, ExistentialProjection, ExistentialTraitRef, + NormalizesTo, ProjectionPredicate, SubtypePredicate, TraitPredicate, TraitRef, }; pub trait Interner: @@ -18,6 +18,9 @@ pub trait Interner: + IrPrint> + IrPrint> + IrPrint> + + IrPrint> + + IrPrint> + + IrPrint> { type DefId: Copy + Debug + Hash + Eq; type DefiningOpaqueTypes: Copy + Debug + Hash + Default + Eq + TypeVisitable; diff --git a/compiler/rustc_type_ir/src/ir_print.rs b/compiler/rustc_type_ir/src/ir_print.rs index 9b72764b4d1fa..5885139754afe 100644 --- a/compiler/rustc_type_ir/src/ir_print.rs +++ b/compiler/rustc_type_ir/src/ir_print.rs @@ -1,8 +1,8 @@ use std::fmt; use crate::{ - ExistentialProjection, ExistentialTraitRef, Interner, ProjectionPredicate, TraitPredicate, - TraitRef, + CoercePredicate, ExistentialProjection, ExistentialTraitRef, Interner, NormalizesTo, + ProjectionPredicate, SubtypePredicate, TraitPredicate, TraitRef, }; pub trait IrPrint { @@ -39,7 +39,10 @@ define_display_via_print!( TraitPredicate, ExistentialTraitRef, ExistentialProjection, - ProjectionPredicate + ProjectionPredicate, + NormalizesTo, + SubtypePredicate, + CoercePredicate, ); define_debug_via_print!(TraitRef, ExistentialTraitRef, ExistentialProjection); diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs index 184b882c2b75f..04cacd987d098 100644 --- a/compiler/rustc_type_ir/src/lib.rs +++ b/compiler/rustc_type_ir/src/lib.rs @@ -37,9 +37,9 @@ mod debug; mod flags; mod infcx; mod interner; +mod predicate; mod predicate_kind; mod region_kind; -mod predicate; pub use canonical::*; #[cfg(feature = "nightly")] @@ -49,9 +49,9 @@ pub use debug::{DebugWithInfcx, WithInfcx}; pub use flags::*; pub use infcx::InferCtxtLike; pub use interner::*; +pub use predicate::*; pub use predicate_kind::*; pub use region_kind::*; -pub use predicate::*; pub use ty_info::*; pub use ty_kind::*; pub use AliasKind::*; diff --git a/compiler/rustc_type_ir/src/predicate.rs b/compiler/rustc_type_ir/src/predicate.rs index 9cd9319a1b1c1..b16227ee10f74 100644 --- a/compiler/rustc_type_ir/src/predicate.rs +++ b/compiler/rustc_type_ir/src/predicate.rs @@ -187,7 +187,11 @@ impl ExistentialTraitRef { // otherwise the escaping vars would be captured by the binder // debug_assert!(!self_ty.has_escaping_bound_vars()); - TraitRef::new(interner, self.def_id, [self_ty.into()].into_iter().chain(self.args.into_iter())) + TraitRef::new( + interner, + self.def_id, + [self_ty.into()].into_iter().chain(self.args.into_iter()), + ) } } @@ -296,3 +300,81 @@ impl fmt::Debug for ProjectionPredicate { write!(f, "ProjectionPredicate({:?}, {:?})", self.projection_ty, self.term) } } + +/// Used by the new solver. Unlike a `ProjectionPredicate` this can only be +/// proven by actually normalizing `alias`. +#[derive(derivative::Derivative)] +#[derivative( + Clone(bound = ""), + Copy(bound = ""), + Hash(bound = ""), + PartialEq(bound = ""), + Eq(bound = "") +)] +#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)] +#[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))] +pub struct NormalizesTo { + pub alias: I::AliasTy, + pub term: I::Term, +} + +impl NormalizesTo { + pub fn self_ty(self) -> I::Ty { + self.alias.self_ty() + } + + pub fn with_self_ty(self, tcx: I, self_ty: I::Ty) -> NormalizesTo { + Self { alias: self.alias.with_self_ty(tcx, self_ty), ..self } + } + + pub fn trait_def_id(self, tcx: I) -> I::DefId { + self.alias.trait_def_id(tcx) + } + + pub fn def_id(self) -> I::DefId { + self.alias.def_id() + } +} + +impl fmt::Debug for NormalizesTo { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "NormalizesTo({:?}, {:?})", self.alias, self.term) + } +} + +/// Encodes that `a` must be a subtype of `b`. The `a_is_expected` flag indicates +/// whether the `a` type is the type that we should label as "expected" when +/// presenting user diagnostics. +#[derive(derivative::Derivative)] +#[derivative( + Clone(bound = ""), + Copy(bound = ""), + Hash(bound = ""), + PartialEq(bound = ""), + Eq(bound = ""), + Debug(bound = "") +)] +#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)] +#[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))] +pub struct SubtypePredicate { + pub a_is_expected: bool, + pub a: I::Ty, + pub b: I::Ty, +} + +/// Encodes that we have to coerce *from* the `a` type to the `b` type. +#[derive(derivative::Derivative)] +#[derivative( + Clone(bound = ""), + Copy(bound = ""), + Hash(bound = ""), + PartialEq(bound = ""), + Eq(bound = ""), + Debug(bound = "") +)] +#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)] +#[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))] +pub struct CoercePredicate { + pub a: I::Ty, + pub b: I::Ty, +} From 905f5658246ae2f108dee3620ace203c0d5286e1 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 11 May 2024 18:14:44 -0400 Subject: [PATCH 090/179] Apply nits, uplift ExistentialPredicate too --- .../src/hir_ty_lowering/object_safety.rs | 2 +- compiler/rustc_middle/src/ty/context.rs | 1 + compiler/rustc_middle/src/ty/mod.rs | 14 ++-- compiler/rustc_middle/src/ty/predicate.rs | 80 +++++++------------ compiler/rustc_middle/src/ty/print/pretty.rs | 20 ++--- compiler/rustc_middle/src/ty/relate.rs | 27 ++++--- .../cfi/typeid/itanium_cxx_abi/transform.rs | 3 +- .../src/traits/object_safety.rs | 3 +- compiler/rustc_type_ir/src/predicate.rs | 32 +++++++- 9 files changed, 100 insertions(+), 82 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/object_safety.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/object_safety.rs index 297cfe7027ec5..37d4d4ec35581 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/object_safety.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/object_safety.rs @@ -7,7 +7,7 @@ use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::DefId; use rustc_lint_defs::builtin::UNUSED_ASSOCIATED_TYPE_BOUNDS; use rustc_middle::ty::fold::BottomUpFolder; -use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable}; +use rustc_middle::ty::{self, ExistentialPredicateStableCmpExt as _, Ty, TyCtxt, TypeFoldable}; use rustc_middle::ty::{DynKind, ToPredicate}; use rustc_span::{ErrorGuaranteed, Span}; use rustc_trait_selection::traits::error_reporting::report_object_safety_error; diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 70fb937cae7ad..f9d1a77c3d960 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -26,6 +26,7 @@ use crate::traits::solve; use crate::traits::solve::{ ExternalConstraints, ExternalConstraintsData, PredefinedOpaques, PredefinedOpaquesData, }; +use crate::ty::predicate::ExistentialPredicateStableCmpExt as _; use crate::ty::{ self, AdtDef, AdtDefData, AdtKind, Binder, Clause, Clauses, Const, ConstData, GenericParamDefKind, ImplPolarity, List, ListWithCachedTypeInfo, ParamConst, ParamTy, Pattern, diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 28baa3348402e..2b0d879696866 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -96,13 +96,13 @@ pub use self::list::{List, ListWithCachedTypeInfo}; pub use self::parameterized::ParameterizedOverTcx; pub use self::pattern::{Pattern, PatternKind}; pub use self::predicate::{ - Clause, ClauseKind, CoercePredicate, ExistentialPredicate, ExistentialProjection, - ExistentialTraitRef, NormalizesTo, OutlivesPredicate, PolyCoercePredicate, - PolyExistentialPredicate, PolyExistentialProjection, PolyExistentialTraitRef, - PolyProjectionPredicate, PolyRegionOutlivesPredicate, PolySubtypePredicate, PolyTraitPredicate, - PolyTraitRef, PolyTypeOutlivesPredicate, Predicate, PredicateKind, ProjectionPredicate, - RegionOutlivesPredicate, SubtypePredicate, ToPolyTraitRef, ToPredicate, TraitPredicate, - TraitRef, TypeOutlivesPredicate, + Clause, ClauseKind, CoercePredicate, ExistentialPredicate, ExistentialPredicateStableCmpExt, + ExistentialProjection, ExistentialTraitRef, NormalizesTo, OutlivesPredicate, + PolyCoercePredicate, PolyExistentialPredicate, PolyExistentialProjection, + PolyExistentialTraitRef, PolyProjectionPredicate, PolyRegionOutlivesPredicate, + PolySubtypePredicate, PolyTraitPredicate, PolyTraitRef, PolyTypeOutlivesPredicate, Predicate, + PredicateKind, ProjectionPredicate, RegionOutlivesPredicate, SubtypePredicate, ToPolyTraitRef, + ToPredicate, TraitPredicate, TraitRef, TypeOutlivesPredicate, }; pub use self::region::{ BoundRegion, BoundRegionKind, BoundRegionKind::*, EarlyParamRegion, LateParamRegion, Region, diff --git a/compiler/rustc_middle/src/ty/predicate.rs b/compiler/rustc_middle/src/ty/predicate.rs index dbbb86cb28e1c..c1de23b249864 100644 --- a/compiler/rustc_middle/src/ty/predicate.rs +++ b/compiler/rustc_middle/src/ty/predicate.rs @@ -1,34 +1,28 @@ use rustc_data_structures::captures::Captures; use rustc_data_structures::intern::Interned; use rustc_hir::def_id::DefId; -use rustc_macros::{HashStable, Lift, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable}; -use rustc_type_ir::ClauseKind as IrClauseKind; -use rustc_type_ir::CoercePredicate as IrCoercePredicate; -use rustc_type_ir::ExistentialProjection as IrExistentialProjection; -use rustc_type_ir::ExistentialTraitRef as IrExistentialTraitRef; -use rustc_type_ir::NormalizesTo as IrNormalizesTo; -use rustc_type_ir::PredicateKind as IrPredicateKind; -use rustc_type_ir::ProjectionPredicate as IrProjectionPredicate; -use rustc_type_ir::SubtypePredicate as IrSubtypePredicate; -use rustc_type_ir::TraitPredicate as IrTraitPredicate; -use rustc_type_ir::TraitRef as IrTraitRef; +use rustc_macros::{ + extension, HashStable, Lift, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable, +}; +use rustc_type_ir as ir; use std::cmp::Ordering; use crate::ty::{ - self, Binder, DebruijnIndex, DebugWithInfcx, EarlyBinder, PredicatePolarity, Term, Ty, TyCtxt, - TypeFlags, WithCachedTypeInfo, + self, Binder, DebruijnIndex, EarlyBinder, PredicatePolarity, Term, Ty, TyCtxt, TypeFlags, + WithCachedTypeInfo, }; -pub type TraitRef<'tcx> = IrTraitRef>; -pub type ProjectionPredicate<'tcx> = IrProjectionPredicate>; -pub type ExistentialTraitRef<'tcx> = IrExistentialTraitRef>; -pub type ExistentialProjection<'tcx> = IrExistentialProjection>; -pub type TraitPredicate<'tcx> = IrTraitPredicate>; -pub type ClauseKind<'tcx> = IrClauseKind>; -pub type PredicateKind<'tcx> = IrPredicateKind>; -pub type NormalizesTo<'tcx> = IrNormalizesTo>; -pub type CoercePredicate<'tcx> = IrCoercePredicate>; -pub type SubtypePredicate<'tcx> = IrSubtypePredicate>; +pub type TraitRef<'tcx> = ir::TraitRef>; +pub type ProjectionPredicate<'tcx> = ir::ProjectionPredicate>; +pub type ExistentialPredicate<'tcx> = ir::ExistentialPredicate>; +pub type ExistentialTraitRef<'tcx> = ir::ExistentialTraitRef>; +pub type ExistentialProjection<'tcx> = ir::ExistentialProjection>; +pub type TraitPredicate<'tcx> = ir::TraitPredicate>; +pub type ClauseKind<'tcx> = ir::ClauseKind>; +pub type PredicateKind<'tcx> = ir::PredicateKind>; +pub type NormalizesTo<'tcx> = ir::NormalizesTo>; +pub type CoercePredicate<'tcx> = ir::CoercePredicate>; +pub type SubtypePredicate<'tcx> = ir::SubtypePredicate>; /// A statement that can be proven by a trait solver. This includes things that may /// show up in where clauses, such as trait predicates and projection predicates, @@ -207,43 +201,25 @@ impl<'tcx> Clause<'tcx> { } } -#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable)] -#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)] -pub enum ExistentialPredicate<'tcx> { - /// E.g., `Iterator`. - Trait(ExistentialTraitRef<'tcx>), - /// E.g., `Iterator::Item = T`. - Projection(ExistentialProjection<'tcx>), - /// E.g., `Send`. - AutoTrait(DefId), -} - -impl<'tcx> DebugWithInfcx> for ExistentialPredicate<'tcx> { - fn fmt>>( - this: rustc_type_ir::WithInfcx<'_, Infcx, &Self>, - f: &mut std::fmt::Formatter<'_>, - ) -> std::fmt::Result { - std::fmt::Debug::fmt(&this.data, f) - } -} - +#[extension(pub trait ExistentialPredicateStableCmpExt<'tcx>)] impl<'tcx> ExistentialPredicate<'tcx> { /// Compares via an ordering that will not change if modules are reordered or other changes are /// made to the tree. In particular, this ordering is preserved across incremental compilations. - pub fn stable_cmp(&self, tcx: TyCtxt<'tcx>, other: &Self) -> Ordering { - use self::ExistentialPredicate::*; + fn stable_cmp(&self, tcx: TyCtxt<'tcx>, other: &Self) -> Ordering { match (*self, *other) { - (Trait(_), Trait(_)) => Ordering::Equal, - (Projection(ref a), Projection(ref b)) => { + (ExistentialPredicate::Trait(_), ExistentialPredicate::Trait(_)) => Ordering::Equal, + (ExistentialPredicate::Projection(ref a), ExistentialPredicate::Projection(ref b)) => { tcx.def_path_hash(a.def_id).cmp(&tcx.def_path_hash(b.def_id)) } - (AutoTrait(ref a), AutoTrait(ref b)) => { + (ExistentialPredicate::AutoTrait(ref a), ExistentialPredicate::AutoTrait(ref b)) => { tcx.def_path_hash(*a).cmp(&tcx.def_path_hash(*b)) } - (Trait(_), _) => Ordering::Less, - (Projection(_), Trait(_)) => Ordering::Greater, - (Projection(_), _) => Ordering::Less, - (AutoTrait(_), _) => Ordering::Greater, + (ExistentialPredicate::Trait(_), _) => Ordering::Less, + (ExistentialPredicate::Projection(_), ExistentialPredicate::Trait(_)) => { + Ordering::Greater + } + (ExistentialPredicate::Projection(_), _) => Ordering::Less, + (ExistentialPredicate::AutoTrait(_), _) => Ordering::Greater, } } } diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 6137a5fd48a80..be9525a083ce5 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -3088,6 +3088,16 @@ define_print! { } } + ty::ExistentialPredicate<'tcx> { + match *self { + ty::ExistentialPredicate::Trait(x) => p!(print(x)), + ty::ExistentialPredicate::Projection(x) => p!(print(x)), + ty::ExistentialPredicate::AutoTrait(def_id) => { + p!(print_def_path(def_id, &[])); + } + } + } + ty::ExistentialTraitRef<'tcx> { // Use a type that can't appear in defaults of type parameters. let dummy_self = Ty::new_fresh(cx.tcx(), 0); @@ -3132,16 +3142,6 @@ define_print_and_forward_display! { p!("{{", comma_sep(self.iter()), "}}") } - ty::ExistentialPredicate<'tcx> { - match *self { - ty::ExistentialPredicate::Trait(x) => p!(print(x)), - ty::ExistentialPredicate::Projection(x) => p!(print(x)), - ty::ExistentialPredicate::AutoTrait(def_id) => { - p!(print_def_path(def_id, &[])); - } - } - } - ty::FnSig<'tcx> { p!(write("{}", self.unsafety.prefix_str())); diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs index 7063ef07201bb..417edda10caeb 100644 --- a/compiler/rustc_middle/src/ty/relate.rs +++ b/compiler/rustc_middle/src/ty/relate.rs @@ -5,8 +5,10 @@ //! subtyping, type equality, etc. use crate::ty::error::{ExpectedFound, TypeError}; -use crate::ty::{self, Expr, ImplSubject, Term, TermKind, Ty, TyCtxt, TypeFoldable}; -use crate::ty::{GenericArg, GenericArgKind, GenericArgsRef}; +use crate::ty::{ + self, ExistentialPredicate, ExistentialPredicateStableCmpExt as _, Expr, GenericArg, + GenericArgKind, GenericArgsRef, ImplSubject, Term, TermKind, Ty, TyCtxt, TypeFoldable, +}; use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_hir::def_id::DefId; @@ -702,14 +704,21 @@ impl<'tcx> Relate<'tcx> for &'tcx ty::List> { } let v = iter::zip(a_v, b_v).map(|(ep_a, ep_b)| { - use crate::ty::ExistentialPredicate::*; match (ep_a.skip_binder(), ep_b.skip_binder()) { - (Trait(a), Trait(b)) => Ok(ep_a - .rebind(Trait(relation.relate(ep_a.rebind(a), ep_b.rebind(b))?.skip_binder()))), - (Projection(a), Projection(b)) => Ok(ep_a.rebind(Projection( - relation.relate(ep_a.rebind(a), ep_b.rebind(b))?.skip_binder(), - ))), - (AutoTrait(a), AutoTrait(b)) if a == b => Ok(ep_a.rebind(AutoTrait(a))), + (ExistentialPredicate::Trait(a), ExistentialPredicate::Trait(b)) => Ok(ep_a + .rebind(ExistentialPredicate::Trait( + relation.relate(ep_a.rebind(a), ep_b.rebind(b))?.skip_binder(), + ))), + (ExistentialPredicate::Projection(a), ExistentialPredicate::Projection(b)) => { + Ok(ep_a.rebind(ExistentialPredicate::Projection( + relation.relate(ep_a.rebind(a), ep_b.rebind(b))?.skip_binder(), + ))) + } + (ExistentialPredicate::AutoTrait(a), ExistentialPredicate::AutoTrait(b)) + if a == b => + { + Ok(ep_a.rebind(ExistentialPredicate::AutoTrait(a))) + } _ => Err(TypeError::ExistentialMismatch(expected_found(a, b))), } }); diff --git a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs index 7141c6c9bb0c3..21433cfdb613e 100644 --- a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs +++ b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs @@ -8,7 +8,8 @@ use rustc_hir::LangItem; use rustc_middle::bug; use rustc_middle::ty::fold::{TypeFolder, TypeSuperFoldable}; use rustc_middle::ty::{ - self, Instance, IntTy, List, Ty, TyCtxt, TypeFoldable, TypeVisitableExt, UintTy, + self, ExistentialPredicateStableCmpExt as _, Instance, IntTy, List, Ty, TyCtxt, TypeFoldable, + TypeVisitableExt, UintTy, }; use rustc_span::sym; use rustc_trait_selection::traits; diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs index 5cb61dff83141..75e43bc8f5d9e 100644 --- a/compiler/rustc_trait_selection/src/traits/object_safety.rs +++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs @@ -18,7 +18,8 @@ use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_middle::query::Providers; use rustc_middle::ty::{ - self, EarlyBinder, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor, + self, EarlyBinder, ExistentialPredicateStableCmpExt as _, Ty, TyCtxt, TypeSuperVisitable, + TypeVisitable, TypeVisitor, }; use rustc_middle::ty::{GenericArg, GenericArgs}; use rustc_middle::ty::{ToPredicate, TypeVisitableExt}; diff --git a/compiler/rustc_type_ir/src/predicate.rs b/compiler/rustc_type_ir/src/predicate.rs index b16227ee10f74..b2510cb01df38 100644 --- a/compiler/rustc_type_ir/src/predicate.rs +++ b/compiler/rustc_type_ir/src/predicate.rs @@ -5,7 +5,7 @@ use rustc_type_ir_macros::{Lift_Generic, TypeFoldable_Generic, TypeVisitable_Gen use crate::inherent::*; use crate::visit::TypeVisitableExt as _; -use crate::Interner; +use crate::{DebugWithInfcx, Interner}; /// A complete reference to a trait. These take numerous guises in syntax, /// but perhaps the most recognizable form is in a where-clause: @@ -146,6 +146,36 @@ impl fmt::Display for PredicatePolarity { } } +#[derive(derivative::Derivative)] +#[derivative( + Clone(bound = ""), + Copy(bound = ""), + Hash(bound = ""), + PartialEq(bound = ""), + Eq(bound = ""), + Debug(bound = "") +)] +#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)] +#[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))] +pub enum ExistentialPredicate { + /// E.g., `Iterator`. + Trait(ExistentialTraitRef), + /// E.g., `Iterator::Item = T`. + Projection(ExistentialProjection), + /// E.g., `Send`. + AutoTrait(I::DefId), +} + +// FIXME: Implement this the right way after +impl DebugWithInfcx for ExistentialPredicate { + fn fmt>( + this: rustc_type_ir::WithInfcx<'_, Infcx, &Self>, + f: &mut fmt::Formatter<'_>, + ) -> fmt::Result { + fmt::Debug::fmt(&this.data, f) + } +} + /// An existential reference to a trait, where `Self` is erased. /// For example, the trait object `Trait<'a, 'b, X, Y>` is: /// ```ignore (illustrative) From b431eec6f28d64cd3852584f9a59736c6c09ee68 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Wed, 27 Dec 2023 18:45:58 -0800 Subject: [PATCH 091/179] Expand on expr_requires_semi_to_be_stmt documentation --- compiler/rustc_ast/src/util/classify.rs | 51 ++++++++++++++++++++----- 1 file changed, 41 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_ast/src/util/classify.rs b/compiler/rustc_ast/src/util/classify.rs index f21a9cabb81be..7f9775a8e0cb7 100644 --- a/compiler/rustc_ast/src/util/classify.rs +++ b/compiler/rustc_ast/src/util/classify.rs @@ -1,16 +1,47 @@ -//! Routines the parser uses to classify AST nodes - -// Predicates on exprs and stmts that the pretty-printer and parser use +//! Routines the parser and pretty-printer use to classify AST nodes. use crate::{ast, token::Delimiter}; -/// Does this expression require a semicolon to be treated -/// as a statement? The negation of this: 'can this expression -/// be used as a statement without a semicolon' -- is used -/// as an early-bail-out in the parser so that, for instance, -/// if true {...} else {...} -/// |x| 5 -/// isn't parsed as (if true {...} else {...} | x) | 5 +/// Does this expression require a semicolon to be treated as a statement? +/// +/// The negation of this: "can this expression be used as a statement without a +/// semicolon" -- is used as an early bail-out in the parser so that, for +/// instance, +/// +/// ```ignore (illustrative) +/// if true {...} else {...} +/// |x| 5 +/// ``` +/// +/// isn't parsed as `(if true {...} else {...} | x) | 5`. +/// +/// Nearly the same early bail-out also occurs in the right-hand side of match +/// arms: +/// +/// ```ignore (illustrative) +/// match i { +/// 0 => if true {...} else {...} +/// | x => {} +/// } +/// ``` +/// +/// Here the `|` is a leading vert in a second match arm. It is not a binary +/// operator with the If as its left operand. If the first arm were some other +/// expression for which `expr_requires_semi_to_be_stmt` returns true, then the +/// `|` on the next line would be a binary operator (leading to a parse error). +/// +/// The statement case and the match-arm case are "nearly" the same early +/// bail-out because of 1 edge case. Macro calls with brace delimiter terminate +/// a statement without a semicolon, but do not terminate a match-arm without +/// comma. +/// +/// ```ignore (illustrative) +/// m! {} - 1; // two statements: a macro call followed by -1 literal +/// +/// match () { +/// _ => m! {} - 1, // binary subtraction operator +/// } +/// ``` pub fn expr_requires_semi_to_be_stmt(e: &ast::Expr) -> bool { !matches!( e.kind, From cbb8714a3f8a04cce698719df338fb095c40f479 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Fri, 29 Dec 2023 16:28:47 -0800 Subject: [PATCH 092/179] Mark expr_requires_semi_to_be_stmt call sites For each of these, we need to decide whether they need to be using `expr_requires_semi_to_be_stmt`, or `expr_requires_comma_to_be_match_arm`, which are supposed to be 2 different behaviors. Previously they were conflated into one, causing either too much or too little parenthesization. --- compiler/rustc_ast/src/util/classify.rs | 3 ++- compiler/rustc_ast_pretty/src/pprust/state.rs | 2 +- compiler/rustc_ast_pretty/src/pprust/state/fixup.rs | 2 +- compiler/rustc_lint/src/unused.rs | 2 +- compiler/rustc_parse/src/parser/expr.rs | 6 +++--- compiler/rustc_parse/src/parser/stmt.rs | 5 +++-- 6 files changed, 11 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_ast/src/util/classify.rs b/compiler/rustc_ast/src/util/classify.rs index 7f9775a8e0cb7..5ed8d95b12d3a 100644 --- a/compiler/rustc_ast/src/util/classify.rs +++ b/compiler/rustc_ast/src/util/classify.rs @@ -42,7 +42,8 @@ use crate::{ast, token::Delimiter}; /// _ => m! {} - 1, // binary subtraction operator /// } /// ``` -pub fn expr_requires_semi_to_be_stmt(e: &ast::Expr) -> bool { +#[allow(non_snake_case)] +pub fn expr_requires_semi_to_be_stmt_FIXME(e: &ast::Expr) -> bool { !matches!( e.kind, ast::ExprKind::If(..) diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index 2c176828c841f..be98b7d37d4aa 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -1253,7 +1253,7 @@ impl<'a> State<'a> { ast::StmtKind::Expr(expr) => { self.space_if_not_bol(); self.print_expr_outer_attr_style(expr, false, FixupContext::new_stmt()); - if classify::expr_requires_semi_to_be_stmt(expr) { + if classify::expr_requires_semi_to_be_stmt_FIXME(expr) { self.word(";"); } } diff --git a/compiler/rustc_ast_pretty/src/pprust/state/fixup.rs b/compiler/rustc_ast_pretty/src/pprust/state/fixup.rs index d21cb82f83b28..363243215a370 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state/fixup.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state/fixup.rs @@ -128,7 +128,7 @@ impl FixupContext { /// The documentation on `FixupContext::leftmost_subexpression_in_stmt` has /// examples. pub fn would_cause_statement_boundary(self, expr: &Expr) -> bool { - self.leftmost_subexpression_in_stmt && !classify::expr_requires_semi_to_be_stmt(expr) + self.leftmost_subexpression_in_stmt && !classify::expr_requires_semi_to_be_stmt_FIXME(expr) } /// Determine whether parentheses are needed around the given `let` diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs index 2b147e052ae0f..7dca701795038 100644 --- a/compiler/rustc_lint/src/unused.rs +++ b/compiler/rustc_lint/src/unused.rs @@ -688,7 +688,7 @@ trait UnusedDelimLint { ExprKind::Index(base, _subscript, _) => base, _ => break, }; - if !classify::expr_requires_semi_to_be_stmt(innermost) { + if !classify::expr_requires_semi_to_be_stmt_FIXME(innermost) { return true; } } diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 577003e94fb28..951c3495995c2 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -498,7 +498,7 @@ impl<'a> Parser<'a> { /// Checks if this expression is a successfully parsed statement. fn expr_is_complete(&self, e: &Expr) -> bool { self.restrictions.contains(Restrictions::STMT_EXPR) - && !classify::expr_requires_semi_to_be_stmt(e) + && !classify::expr_requires_semi_to_be_stmt_FIXME(e) } /// Parses `x..y`, `x..=y`, and `x..`/`x..=`. @@ -2694,7 +2694,7 @@ impl<'a> Parser<'a> { // If it's not a free-standing expression, and is followed by a block, // then it's very likely the condition to an `else if`. if self.check(&TokenKind::OpenDelim(Delimiter::Brace)) - && classify::expr_requires_semi_to_be_stmt(&cond) => + && classify::expr_requires_semi_to_be_stmt_FIXME(&cond) => { self.dcx().emit_err(errors::ExpectedElseBlock { first_tok_span, @@ -3136,7 +3136,7 @@ impl<'a> Parser<'a> { err })?; - let require_comma = classify::expr_requires_semi_to_be_stmt(&expr) + let require_comma = classify::expr_requires_semi_to_be_stmt_FIXME(&expr) && this.token != token::CloseDelim(Delimiter::Brace); if !require_comma { diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs index d70afebf1b2da..f64a480a18c32 100644 --- a/compiler/rustc_parse/src/parser/stmt.rs +++ b/compiler/rustc_parse/src/parser/stmt.rs @@ -648,7 +648,7 @@ impl<'a> Parser<'a> { match &mut stmt.kind { // Expression without semicolon. StmtKind::Expr(expr) - if classify::expr_requires_semi_to_be_stmt(expr) + if classify::expr_requires_semi_to_be_stmt_FIXME(expr) && !expr.attrs.is_empty() && ![token::Eof, token::Semi, token::CloseDelim(Delimiter::Brace)] .contains(&self.token.kind) => @@ -662,7 +662,8 @@ impl<'a> Parser<'a> { // Expression without semicolon. StmtKind::Expr(expr) - if self.token != token::Eof && classify::expr_requires_semi_to_be_stmt(expr) => + if self.token != token::Eof + && classify::expr_requires_semi_to_be_stmt_FIXME(expr) => { // Just check for errors and recover; do not eat semicolon yet. From 9e1cf2098d68356bccf7112bbff1d9b565e80a02 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Fri, 29 Dec 2023 16:30:34 -0800 Subject: [PATCH 093/179] Macro call with braces does not require semicolon to be statement This commit by itself is supposed to have no effect on behavior. All of the call sites are updated to preserve their previous behavior. The behavior changes are in the commits that follow. --- compiler/rustc_ast/src/util/classify.rs | 30 +++++++++++-------- compiler/rustc_ast_pretty/src/pprust/state.rs | 5 +++- .../src/pprust/state/fixup.rs | 6 +++- compiler/rustc_lint/src/unused.rs | 5 +++- compiler/rustc_parse/src/parser/expr.rs | 16 +++++++--- compiler/rustc_parse/src/parser/stmt.rs | 11 +++++-- 6 files changed, 50 insertions(+), 23 deletions(-) diff --git a/compiler/rustc_ast/src/util/classify.rs b/compiler/rustc_ast/src/util/classify.rs index 5ed8d95b12d3a..86383af1f7c83 100644 --- a/compiler/rustc_ast/src/util/classify.rs +++ b/compiler/rustc_ast/src/util/classify.rs @@ -42,19 +42,23 @@ use crate::{ast, token::Delimiter}; /// _ => m! {} - 1, // binary subtraction operator /// } /// ``` -#[allow(non_snake_case)] -pub fn expr_requires_semi_to_be_stmt_FIXME(e: &ast::Expr) -> bool { - !matches!( - e.kind, - ast::ExprKind::If(..) - | ast::ExprKind::Match(..) - | ast::ExprKind::Block(..) - | ast::ExprKind::While(..) - | ast::ExprKind::Loop(..) - | ast::ExprKind::ForLoop { .. } - | ast::ExprKind::TryBlock(..) - | ast::ExprKind::ConstBlock(..) - ) +pub fn expr_requires_semi_to_be_stmt(e: &ast::Expr) -> bool { + use ast::ExprKind::*; + + match &e.kind { + If(..) + | Match(..) + | Block(..) + | While(..) + | Loop(..) + | ForLoop { .. } + | TryBlock(..) + | ConstBlock(..) => false, + + MacCall(mac_call) => mac_call.args.delim != Delimiter::Brace, + + _ => true, + } } /// If an expression ends with `}`, returns the innermost expression ending in the `}` diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index be98b7d37d4aa..fe17ff41bc34d 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -1253,7 +1253,10 @@ impl<'a> State<'a> { ast::StmtKind::Expr(expr) => { self.space_if_not_bol(); self.print_expr_outer_attr_style(expr, false, FixupContext::new_stmt()); - if classify::expr_requires_semi_to_be_stmt_FIXME(expr) { + if match expr.kind { + ast::ExprKind::MacCall(_) => true, + _ => classify::expr_requires_semi_to_be_stmt(expr), + } { self.word(";"); } } diff --git a/compiler/rustc_ast_pretty/src/pprust/state/fixup.rs b/compiler/rustc_ast_pretty/src/pprust/state/fixup.rs index 363243215a370..9934f972f9bfd 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state/fixup.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state/fixup.rs @@ -128,7 +128,11 @@ impl FixupContext { /// The documentation on `FixupContext::leftmost_subexpression_in_stmt` has /// examples. pub fn would_cause_statement_boundary(self, expr: &Expr) -> bool { - self.leftmost_subexpression_in_stmt && !classify::expr_requires_semi_to_be_stmt_FIXME(expr) + self.leftmost_subexpression_in_stmt + && match expr.kind { + ExprKind::MacCall(_) => false, + _ => !classify::expr_requires_semi_to_be_stmt(expr), + } } /// Determine whether parentheses are needed around the given `let` diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs index 7dca701795038..19b71564e2ebb 100644 --- a/compiler/rustc_lint/src/unused.rs +++ b/compiler/rustc_lint/src/unused.rs @@ -688,7 +688,10 @@ trait UnusedDelimLint { ExprKind::Index(base, _subscript, _) => base, _ => break, }; - if !classify::expr_requires_semi_to_be_stmt_FIXME(innermost) { + if match innermost.kind { + ExprKind::MacCall(_) => false, + _ => !classify::expr_requires_semi_to_be_stmt(innermost), + } { return true; } } diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 951c3495995c2..5f7bd0835d3d6 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -498,7 +498,10 @@ impl<'a> Parser<'a> { /// Checks if this expression is a successfully parsed statement. fn expr_is_complete(&self, e: &Expr) -> bool { self.restrictions.contains(Restrictions::STMT_EXPR) - && !classify::expr_requires_semi_to_be_stmt_FIXME(e) + && match e.kind { + ExprKind::MacCall(_) => false, + _ => !classify::expr_requires_semi_to_be_stmt(e), + } } /// Parses `x..y`, `x..=y`, and `x..`/`x..=`. @@ -2694,7 +2697,10 @@ impl<'a> Parser<'a> { // If it's not a free-standing expression, and is followed by a block, // then it's very likely the condition to an `else if`. if self.check(&TokenKind::OpenDelim(Delimiter::Brace)) - && classify::expr_requires_semi_to_be_stmt_FIXME(&cond) => + && match cond.kind { + ExprKind::MacCall(_) => true, + _ => classify::expr_requires_semi_to_be_stmt(&cond), + } => { self.dcx().emit_err(errors::ExpectedElseBlock { first_tok_span, @@ -3136,8 +3142,10 @@ impl<'a> Parser<'a> { err })?; - let require_comma = classify::expr_requires_semi_to_be_stmt_FIXME(&expr) - && this.token != token::CloseDelim(Delimiter::Brace); + let require_comma = match expr.kind { + ExprKind::MacCall(_) => true, + _ => classify::expr_requires_semi_to_be_stmt(&expr), + } && this.token != token::CloseDelim(Delimiter::Brace); if !require_comma { arm_body = Some(expr); diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs index f64a480a18c32..684799eb6a78d 100644 --- a/compiler/rustc_parse/src/parser/stmt.rs +++ b/compiler/rustc_parse/src/parser/stmt.rs @@ -648,8 +648,10 @@ impl<'a> Parser<'a> { match &mut stmt.kind { // Expression without semicolon. StmtKind::Expr(expr) - if classify::expr_requires_semi_to_be_stmt_FIXME(expr) - && !expr.attrs.is_empty() + if match expr.kind { + ExprKind::MacCall(_) => true, + _ => classify::expr_requires_semi_to_be_stmt(expr), + } && !expr.attrs.is_empty() && ![token::Eof, token::Semi, token::CloseDelim(Delimiter::Brace)] .contains(&self.token.kind) => { @@ -663,7 +665,10 @@ impl<'a> Parser<'a> { // Expression without semicolon. StmtKind::Expr(expr) if self.token != token::Eof - && classify::expr_requires_semi_to_be_stmt_FIXME(expr) => + && match expr.kind { + ExprKind::MacCall(_) => true, + _ => classify::expr_requires_semi_to_be_stmt(expr), + } => { // Just check for errors and recover; do not eat semicolon yet. From c5a0eb12466b6591bc3a3d373c51fabd19735533 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Wed, 27 Dec 2023 17:29:52 -0800 Subject: [PATCH 094/179] Add ExprKind::MacCall statement boundary tests --- tests/ui/macros/stringify.rs | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/tests/ui/macros/stringify.rs b/tests/ui/macros/stringify.rs index 492bd2450b1bf..df1cf5d8a9102 100644 --- a/tests/ui/macros/stringify.rs +++ b/tests/ui/macros/stringify.rs @@ -213,6 +213,21 @@ fn test_expr() { "match () { _ => ({ 1 }) - 1, }", "match () { _ => { 1 } - 1 }", ); + c2_match_arm!( + [ m!() - 1 ], + "match () { _ => m!() - 1, }", + "match () { _ => m!() - 1 }", + ); + c2_match_arm!( + [ m![] - 1 ], + "match () { _ => m![] - 1, }", + "match () { _ => m![] - 1 }", + ); + c2_match_arm!( + [ m! {} - 1 ], + "match () { _ => m! {} - 1, }", + "match () { _ => m! {} - 1 }", + ); // ExprKind::Closure c1!(expr, [ || {} ], "|| {}"); @@ -720,6 +735,21 @@ fn test_stmt() { "(loop { break 1; }) - 1;", "loop { break 1; } - 1", ); + c2_minus_one!( + [ m!() ], + "m!() - 1;", + "m!() - 1" + ); + c2_minus_one!( + [ m![] ], + "m![] - 1;", + "m![] - 1" + ); + c2_minus_one!( + [ m! {} ], + "m! {} - 1;", // FIXME(dtolnay): needs parens, otherwise this is 2 separate statements + "m! {} - 1" + ); // StmtKind::Empty c1!(stmt, [ ; ], ";"); From 7f2ffbdbc6c0d5e1c7fabe0bef56ec49d10bfeab Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Wed, 27 Dec 2023 17:30:54 -0800 Subject: [PATCH 095/179] Fix pretty printer statement boundaries after braced macro call --- compiler/rustc_ast_pretty/src/pprust/state/fixup.rs | 6 +----- tests/ui/macros/stringify.rs | 4 ++-- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_ast_pretty/src/pprust/state/fixup.rs b/compiler/rustc_ast_pretty/src/pprust/state/fixup.rs index 9934f972f9bfd..d21cb82f83b28 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state/fixup.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state/fixup.rs @@ -128,11 +128,7 @@ impl FixupContext { /// The documentation on `FixupContext::leftmost_subexpression_in_stmt` has /// examples. pub fn would_cause_statement_boundary(self, expr: &Expr) -> bool { - self.leftmost_subexpression_in_stmt - && match expr.kind { - ExprKind::MacCall(_) => false, - _ => !classify::expr_requires_semi_to_be_stmt(expr), - } + self.leftmost_subexpression_in_stmt && !classify::expr_requires_semi_to_be_stmt(expr) } /// Determine whether parentheses are needed around the given `let` diff --git a/tests/ui/macros/stringify.rs b/tests/ui/macros/stringify.rs index df1cf5d8a9102..a66a5513ffae3 100644 --- a/tests/ui/macros/stringify.rs +++ b/tests/ui/macros/stringify.rs @@ -225,7 +225,7 @@ fn test_expr() { ); c2_match_arm!( [ m! {} - 1 ], - "match () { _ => m! {} - 1, }", + "match () { _ => (m! {}) - 1, }", // parenthesis is redundant "match () { _ => m! {} - 1 }", ); @@ -747,7 +747,7 @@ fn test_stmt() { ); c2_minus_one!( [ m! {} ], - "m! {} - 1;", // FIXME(dtolnay): needs parens, otherwise this is 2 separate statements + "(m! {}) - 1;", "m! {} - 1" ); From d9bb73331eff4bbcfb5610b96d2411ef751db20d Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Wed, 27 Dec 2023 19:32:49 -0800 Subject: [PATCH 096/179] Delete MacCall case from pretty-printing semicolon after StmtKind::Expr I didn't figure out how to reach this condition with `expr` containing `ExprKind::MacCall`. All the approaches I tried ended up with the macro call ending up in the `StmtKind::MacCall` case below instead. In any case, from visual inspection this is a bugfix. If we do end up with a `StmtKind::Expr` containing `ExprKind::MacCall` with brace delimiter, it would not need ";" printed after it. --- compiler/rustc_ast_pretty/src/pprust/state.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index fe17ff41bc34d..2c176828c841f 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -1253,10 +1253,7 @@ impl<'a> State<'a> { ast::StmtKind::Expr(expr) => { self.space_if_not_bol(); self.print_expr_outer_attr_style(expr, false, FixupContext::new_stmt()); - if match expr.kind { - ast::ExprKind::MacCall(_) => true, - _ => classify::expr_requires_semi_to_be_stmt(expr), - } { + if classify::expr_requires_semi_to_be_stmt(expr) { self.word(";"); } } From 0ca322c774144ea023561bc0ab556a73c7fc7337 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Wed, 27 Dec 2023 19:49:31 -0800 Subject: [PATCH 097/179] Add test of unused_parens lint involving macro calls --- tests/ui/lint/lint-unnecessary-parens.fixed | 31 ++++++++ tests/ui/lint/lint-unnecessary-parens.rs | 31 ++++++++ tests/ui/lint/lint-unnecessary-parens.stderr | 74 +++++++++++++++----- 3 files changed, 117 insertions(+), 19 deletions(-) diff --git a/tests/ui/lint/lint-unnecessary-parens.fixed b/tests/ui/lint/lint-unnecessary-parens.fixed index 973bbd70f257f..760897c5143f1 100644 --- a/tests/ui/lint/lint-unnecessary-parens.fixed +++ b/tests/ui/lint/lint-unnecessary-parens.fixed @@ -46,6 +46,28 @@ pub fn parens_with_keyword(e: &[()]) -> i32 { macro_rules! baz { ($($foo:expr),+) => { ($($foo),*) + }; +} + +macro_rules! unit { + () => { + () + }; +} + +struct One; + +impl std::ops::Sub for () { + type Output = i32; + fn sub(self, _: One) -> Self::Output { + -1 + } +} + +impl std::ops::Neg for One { + type Output = i32; + fn neg(self) -> Self::Output { + -1 } } @@ -94,4 +116,13 @@ fn main() { let _a = baz!(3, 4); let _b = baz!(3); + + let _ = { + unit!() - One //~ ERROR unnecessary parentheses around block return value + } + { + unit![] - One //~ ERROR unnecessary parentheses around block return value + } + { + // FIXME: false positive. This parenthesis is required. + unit! {} - One //~ ERROR unnecessary parentheses around block return value + }; } diff --git a/tests/ui/lint/lint-unnecessary-parens.rs b/tests/ui/lint/lint-unnecessary-parens.rs index 40cd61fcc2c0e..7cbaac8ae5403 100644 --- a/tests/ui/lint/lint-unnecessary-parens.rs +++ b/tests/ui/lint/lint-unnecessary-parens.rs @@ -46,6 +46,28 @@ pub fn parens_with_keyword(e: &[()]) -> i32 { macro_rules! baz { ($($foo:expr),+) => { ($($foo),*) + }; +} + +macro_rules! unit { + () => { + () + }; +} + +struct One; + +impl std::ops::Sub for () { + type Output = i32; + fn sub(self, _: One) -> Self::Output { + -1 + } +} + +impl std::ops::Neg for One { + type Output = i32; + fn neg(self) -> Self::Output { + -1 } } @@ -94,4 +116,13 @@ fn main() { let _a = baz!(3, 4); let _b = baz!(3); + + let _ = { + (unit!() - One) //~ ERROR unnecessary parentheses around block return value + } + { + (unit![] - One) //~ ERROR unnecessary parentheses around block return value + } + { + // FIXME: false positive. This parenthesis is required. + (unit! {} - One) //~ ERROR unnecessary parentheses around block return value + }; } diff --git a/tests/ui/lint/lint-unnecessary-parens.stderr b/tests/ui/lint/lint-unnecessary-parens.stderr index ba7a78b8da1a9..755dd5fc3094b 100644 --- a/tests/ui/lint/lint-unnecessary-parens.stderr +++ b/tests/ui/lint/lint-unnecessary-parens.stderr @@ -124,7 +124,7 @@ LL + return 1; | error: unnecessary parentheses around assigned value - --> $DIR/lint-unnecessary-parens.rs:52:31 + --> $DIR/lint-unnecessary-parens.rs:74:31 | LL | pub const CONST_ITEM: usize = (10); | ^ ^ @@ -136,7 +136,7 @@ LL + pub const CONST_ITEM: usize = 10; | error: unnecessary parentheses around assigned value - --> $DIR/lint-unnecessary-parens.rs:53:33 + --> $DIR/lint-unnecessary-parens.rs:75:33 | LL | pub static STATIC_ITEM: usize = (10); | ^ ^ @@ -148,7 +148,7 @@ LL + pub static STATIC_ITEM: usize = 10; | error: unnecessary parentheses around function argument - --> $DIR/lint-unnecessary-parens.rs:57:9 + --> $DIR/lint-unnecessary-parens.rs:79:9 | LL | bar((true)); | ^ ^ @@ -160,7 +160,7 @@ LL + bar(true); | error: unnecessary parentheses around `if` condition - --> $DIR/lint-unnecessary-parens.rs:59:8 + --> $DIR/lint-unnecessary-parens.rs:81:8 | LL | if (true) {} | ^ ^ @@ -172,7 +172,7 @@ LL + if true {} | error: unnecessary parentheses around `while` condition - --> $DIR/lint-unnecessary-parens.rs:60:11 + --> $DIR/lint-unnecessary-parens.rs:82:11 | LL | while (true) {} | ^ ^ @@ -184,7 +184,7 @@ LL + while true {} | error: unnecessary parentheses around `match` scrutinee expression - --> $DIR/lint-unnecessary-parens.rs:61:11 + --> $DIR/lint-unnecessary-parens.rs:83:11 | LL | match (true) { | ^ ^ @@ -196,7 +196,7 @@ LL + match true { | error: unnecessary parentheses around `let` scrutinee expression - --> $DIR/lint-unnecessary-parens.rs:64:16 + --> $DIR/lint-unnecessary-parens.rs:86:16 | LL | if let 1 = (1) {} | ^ ^ @@ -208,7 +208,7 @@ LL + if let 1 = 1 {} | error: unnecessary parentheses around `let` scrutinee expression - --> $DIR/lint-unnecessary-parens.rs:65:19 + --> $DIR/lint-unnecessary-parens.rs:87:19 | LL | while let 1 = (2) {} | ^ ^ @@ -220,7 +220,7 @@ LL + while let 1 = 2 {} | error: unnecessary parentheses around method argument - --> $DIR/lint-unnecessary-parens.rs:81:24 + --> $DIR/lint-unnecessary-parens.rs:103:24 | LL | X { y: false }.foo((true)); | ^ ^ @@ -232,7 +232,7 @@ LL + X { y: false }.foo(true); | error: unnecessary parentheses around assigned value - --> $DIR/lint-unnecessary-parens.rs:83:18 + --> $DIR/lint-unnecessary-parens.rs:105:18 | LL | let mut _a = (0); | ^ ^ @@ -244,7 +244,7 @@ LL + let mut _a = 0; | error: unnecessary parentheses around assigned value - --> $DIR/lint-unnecessary-parens.rs:84:10 + --> $DIR/lint-unnecessary-parens.rs:106:10 | LL | _a = (0); | ^ ^ @@ -256,7 +256,7 @@ LL + _a = 0; | error: unnecessary parentheses around assigned value - --> $DIR/lint-unnecessary-parens.rs:85:11 + --> $DIR/lint-unnecessary-parens.rs:107:11 | LL | _a += (1); | ^ ^ @@ -268,7 +268,7 @@ LL + _a += 1; | error: unnecessary parentheses around pattern - --> $DIR/lint-unnecessary-parens.rs:87:8 + --> $DIR/lint-unnecessary-parens.rs:109:8 | LL | let(mut _a) = 3; | ^ ^ @@ -280,7 +280,7 @@ LL + let mut _a = 3; | error: unnecessary parentheses around pattern - --> $DIR/lint-unnecessary-parens.rs:88:9 + --> $DIR/lint-unnecessary-parens.rs:110:9 | LL | let (mut _a) = 3; | ^ ^ @@ -292,7 +292,7 @@ LL + let mut _a = 3; | error: unnecessary parentheses around pattern - --> $DIR/lint-unnecessary-parens.rs:89:8 + --> $DIR/lint-unnecessary-parens.rs:111:8 | LL | let( mut _a) = 3; | ^^ ^ @@ -304,7 +304,7 @@ LL + let mut _a = 3; | error: unnecessary parentheses around pattern - --> $DIR/lint-unnecessary-parens.rs:91:8 + --> $DIR/lint-unnecessary-parens.rs:113:8 | LL | let(_a) = 3; | ^ ^ @@ -316,7 +316,7 @@ LL + let _a = 3; | error: unnecessary parentheses around pattern - --> $DIR/lint-unnecessary-parens.rs:92:9 + --> $DIR/lint-unnecessary-parens.rs:114:9 | LL | let (_a) = 3; | ^ ^ @@ -328,7 +328,7 @@ LL + let _a = 3; | error: unnecessary parentheses around pattern - --> $DIR/lint-unnecessary-parens.rs:93:8 + --> $DIR/lint-unnecessary-parens.rs:115:8 | LL | let( _a) = 3; | ^^ ^ @@ -339,5 +339,41 @@ LL - let( _a) = 3; LL + let _a = 3; | -error: aborting due to 28 previous errors +error: unnecessary parentheses around block return value + --> $DIR/lint-unnecessary-parens.rs:121:9 + | +LL | (unit!() - One) + | ^ ^ + | +help: remove these parentheses + | +LL - (unit!() - One) +LL + unit!() - One + | + +error: unnecessary parentheses around block return value + --> $DIR/lint-unnecessary-parens.rs:123:9 + | +LL | (unit![] - One) + | ^ ^ + | +help: remove these parentheses + | +LL - (unit![] - One) +LL + unit![] - One + | + +error: unnecessary parentheses around block return value + --> $DIR/lint-unnecessary-parens.rs:126:9 + | +LL | (unit! {} - One) + | ^ ^ + | +help: remove these parentheses + | +LL - (unit! {} - One) +LL + unit! {} - One + | + +error: aborting due to 31 previous errors From c6c18a0151a374e9376952aa7ef62110b14055d5 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Wed, 27 Dec 2023 20:11:00 -0800 Subject: [PATCH 098/179] Document the situation with unused_parens lint and braced macro calls --- compiler/rustc_lint/src/unused.rs | 32 +++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs index 19b71564e2ebb..8866b2be07847 100644 --- a/compiler/rustc_lint/src/unused.rs +++ b/compiler/rustc_lint/src/unused.rs @@ -677,6 +677,33 @@ trait UnusedDelimLint { } // Check if LHS needs parens to prevent false-positives in cases like `fn x() -> u8 { ({ 0 } + 1) }`. + // + // FIXME: https://github.com/rust-lang/rust/issues/119426 + // The syntax tree in this code is from after macro expansion, so the + // current implementation has both false negatives and false positives + // related to expressions containing macros. + // + // macro_rules! m1 { + // () => { + // 1 + // }; + // } + // + // fn f1() -> u8 { + // // Lint says parens are not needed, but they are. + // (m1! {} + 1) + // } + // + // macro_rules! m2 { + // () => { + // loop { break 1; } + // }; + // } + // + // fn f2() -> u8 { + // // Lint says parens are needed, but they are not. + // (m2!() + 1) + // } { let mut innermost = inner; loop { @@ -688,10 +715,7 @@ trait UnusedDelimLint { ExprKind::Index(base, _subscript, _) => base, _ => break, }; - if match innermost.kind { - ExprKind::MacCall(_) => false, - _ => !classify::expr_requires_semi_to_be_stmt(innermost), - } { + if !classify::expr_requires_semi_to_be_stmt(innermost) { return true; } } From 4a80865437f03e918225ed13ce692122e32c8045 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Fri, 29 Dec 2023 15:25:34 -0800 Subject: [PATCH 099/179] Add parser tests for statement boundary insertion --- tests/ui/parser/macro/statement-boundaries.rs | 104 ++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100644 tests/ui/parser/macro/statement-boundaries.rs diff --git a/tests/ui/parser/macro/statement-boundaries.rs b/tests/ui/parser/macro/statement-boundaries.rs new file mode 100644 index 0000000000000..67a6aa30f0c5e --- /dev/null +++ b/tests/ui/parser/macro/statement-boundaries.rs @@ -0,0 +1,104 @@ +//@ run-pass +//@ edition:2021 + +// This is a test of several uses of rustc_ast::util::classify::expr_requires_semi_to_be_stmt +// by the Rust parser, which relates to the insertion of statement boundaries +// after certain kinds of expressions if they appear at the head of a statement. + +#![allow(unused_braces, unused_unsafe)] + +macro_rules! unit { + () => { + { () } + }; +} + +#[derive(Copy, Clone)] +struct X; + +fn main() { + let x = X; + + // There is a statement boundary before `|x| x`, so it's a closure. + let _: fn(X) -> X = { if true {} |x| x }; + let _: fn(X) -> X = { if true {} else {} |x| x }; + let _: fn(X) -> X = { match () { () => {} } |x| x }; + let _: fn(X) -> X = { { () } |x| x }; + let _: fn(X) -> X = { unsafe {} |x| x }; + let _: fn(X) -> X = { while false {} |x| x }; + let _: fn(X) -> X = { loop { break; } |x| x }; + let _: fn(X) -> X = { for _ in 0..0 {} |x| x }; + let _: fn(X) -> X = { const {} |x| x }; + let _: fn(X) -> X = { unit! {} |x| x }; + + // No statement boundary, so `|x| x` is 2× BitOr operation. + () = { "" |x| x }; + () = { ("") |x| x }; + () = { [""] |x| x }; + () = { unit!() |x| x }; + () = { unit![] |x| x }; + + // All the same cases, but as a match arm. + () = match x { + // Statement boundary before `| X`, which becomes a new arm with leading vert. + X if false => if true {} | X if false => {} + X if false => if true {} else {} | X if false => {} + X if false => match () { () => {} } | X if false => {} + X if false => { () } | X if false => {} + X if false => unsafe {} | X if false => {} + X if false => while false {} | X if false => {} + X if false => loop { break; } | X if false => {} + X if false => for _ in 0..0 {} | X if false => {} + X if false => const {} | X if false => {} + + // No statement boundary, so `| X` is BitOr. + X if false => "" | X, + X if false => ("") | X, + X if false => [""] | X, + X if false => unit! {} | X, // !! inconsistent with braced mac call in statement position + X if false => unit!() | X, + X if false => unit![] | X, + + X => {} + }; + + // Test how the statement boundary logic interacts with macro metavariables / + // "invisible delimiters". + macro_rules! assert_statement_boundary { + ($expr:expr) => { + let _: fn(X) -> X = { $expr |x| x }; + + () = match X { + X if false => $expr | X if false => {} + X => {} + }; + }; + } + macro_rules! assert_no_statement_boundary { + ($expr:expr) => { + () = { $expr |x| x }; + + () = match x { + X if false => $expr | X, + X => {} + }; + }; + } + assert_statement_boundary!(if true {}); + assert_no_statement_boundary!(""); +} + +impl std::ops::BitOr for () { + type Output = (); + fn bitor(self, _: X) {} +} + +impl std::ops::BitOr for &str { + type Output = (); + fn bitor(self, _: X) {} +} + +impl std::ops::BitOr for [T; N] { + type Output = (); + fn bitor(self, _: X) {} +} From 8adcaf5df27ac63b5e83612bd08cae12d3d1725e Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Fri, 29 Dec 2023 16:13:55 -0800 Subject: [PATCH 100/179] Mark Parser::expr_is_complete call sites --- compiler/rustc_parse/src/parser/expr.rs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 5f7bd0835d3d6..602dbbb572502 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -190,7 +190,7 @@ impl<'a> Parser<'a> { } }; - if !self.should_continue_as_assoc_expr(&lhs) { + if !self.should_continue_as_assoc_expr_FIXME(&lhs) { return Ok(lhs); } @@ -383,8 +383,9 @@ impl<'a> Parser<'a> { Ok(lhs) } - fn should_continue_as_assoc_expr(&mut self, lhs: &Expr) -> bool { - match (self.expr_is_complete(lhs), AssocOp::from_token(&self.token)) { + #[allow(non_snake_case)] + fn should_continue_as_assoc_expr_FIXME(&mut self, lhs: &Expr) -> bool { + match (self.expr_is_complete_FIXME(lhs), AssocOp::from_token(&self.token)) { // Semi-statement forms are odd: // See https://github.com/rust-lang/rust/issues/29071 (true, None) => false, @@ -496,7 +497,8 @@ impl<'a> Parser<'a> { } /// Checks if this expression is a successfully parsed statement. - fn expr_is_complete(&self, e: &Expr) -> bool { + #[allow(non_snake_case)] + fn expr_is_complete_FIXME(&self, e: &Expr) -> bool { self.restrictions.contains(Restrictions::STMT_EXPR) && match e.kind { ExprKind::MacCall(_) => false, @@ -1012,7 +1014,7 @@ impl<'a> Parser<'a> { e = self.parse_dot_suffix_expr(lo, e)?; continue; } - if self.expr_is_complete(&e) { + if self.expr_is_complete_FIXME(&e) { return Ok(e); } e = match self.token.kind { From 9dbe33d256e6b3919d2fc0a6561b78d2ed3c628c Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Fri, 29 Dec 2023 16:41:25 -0800 Subject: [PATCH 101/179] Document MacCall special case in Parser::expr_is_complete --- compiler/rustc_parse/src/parser/expr.rs | 51 +++++++++++++++++++++---- 1 file changed, 44 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 602dbbb572502..98b41013a2c65 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -190,7 +190,7 @@ impl<'a> Parser<'a> { } }; - if !self.should_continue_as_assoc_expr_FIXME(&lhs) { + if !self.should_continue_as_assoc_expr(&lhs) { return Ok(lhs); } @@ -383,9 +383,8 @@ impl<'a> Parser<'a> { Ok(lhs) } - #[allow(non_snake_case)] - fn should_continue_as_assoc_expr_FIXME(&mut self, lhs: &Expr) -> bool { - match (self.expr_is_complete_FIXME(lhs), AssocOp::from_token(&self.token)) { + fn should_continue_as_assoc_expr(&mut self, lhs: &Expr) -> bool { + match (self.expr_is_complete(lhs), AssocOp::from_token(&self.token)) { // Semi-statement forms are odd: // See https://github.com/rust-lang/rust/issues/29071 (true, None) => false, @@ -497,10 +496,48 @@ impl<'a> Parser<'a> { } /// Checks if this expression is a successfully parsed statement. - #[allow(non_snake_case)] - fn expr_is_complete_FIXME(&self, e: &Expr) -> bool { + /// + /// This determines whether to continue parsing more of an expression in a + /// match arm (false) vs continue to the next arm (true). + /// + /// ```ignore (illustrative) + /// match ... { + /// // Is this calling $e as a function, or is it the start of a new arm + /// // with a tuple pattern? + /// _ => $e ( + /// ^ ) + /// + /// // Is this an Index operation, or new arm with a slice pattern? + /// _ => $e [ + /// ^ ] + /// + /// // Is this a binary operator, or leading vert in a new arm? Same for + /// // other punctuation which can either be a binary operator in + /// // expression or unary operator in pattern, such as `&` and `-`. + /// _ => $e | + /// ^ + /// } + /// ``` + /// + /// If $e is something like `path::to` or `(…)`, continue parsing the same + /// arm. + /// + /// If $e is something like `{}` or `if … {}`, then terminate the current + /// arm and parse a new arm. + fn expr_is_complete(&self, e: &Expr) -> bool { self.restrictions.contains(Restrictions::STMT_EXPR) && match e.kind { + // Surprising special case: even though braced macro calls like + // `m! {}` normally introduce a statement boundary when found at + // the head of a statement, in match arms they do not terminate + // the arm. + // + // let _ = { m! {} () }; // macro call followed by unit + // + // match ... { + // _ => m! {} (), // macro that expands to a function, which is then called + // } + // ExprKind::MacCall(_) => false, _ => !classify::expr_requires_semi_to_be_stmt(e), } @@ -1014,7 +1051,7 @@ impl<'a> Parser<'a> { e = self.parse_dot_suffix_expr(lo, e)?; continue; } - if self.expr_is_complete_FIXME(&e) { + if self.expr_is_complete(&e) { return Ok(e); } e = match self.token.kind { From 728e117166e1dab6f8333d61e1315172c558fce5 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Fri, 29 Dec 2023 17:15:34 -0800 Subject: [PATCH 102/179] Document MacCall special case in Parser::parse_arm --- compiler/rustc_parse/src/parser/expr.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 98b41013a2c65..bb0873a814dfa 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -3182,6 +3182,17 @@ impl<'a> Parser<'a> { })?; let require_comma = match expr.kind { + // Special case: braced macro calls require comma in a match + // arm, even though they do not require semicolon in a + // statement. + // + // m! {} // okay without semicolon + // + // match ... { + // _ => m! {}, // requires comma + // _ => ... + // } + // ExprKind::MacCall(_) => true, _ => classify::expr_requires_semi_to_be_stmt(&expr), } && this.token != token::CloseDelim(Delimiter::Brace); From 0f6a51d4958dff5a29c121801bcdd619d71db541 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Fri, 29 Dec 2023 17:34:50 -0800 Subject: [PATCH 103/179] Add macro calls to else-no-if parser test --- tests/ui/parser/else-no-if.rs | 30 ++++++++++++++++ tests/ui/parser/else-no-if.stderr | 58 ++++++++++++++++++++++++++++--- 2 files changed, 83 insertions(+), 5 deletions(-) diff --git a/tests/ui/parser/else-no-if.rs b/tests/ui/parser/else-no-if.rs index f0b40ecde6660..ad5262cd2cc93 100644 --- a/tests/ui/parser/else-no-if.rs +++ b/tests/ui/parser/else-no-if.rs @@ -1,3 +1,7 @@ +macro_rules! falsy { + () => { false }; +} + fn foo() { if true { } else false { @@ -25,6 +29,32 @@ fn foo4() { {} } +fn foo5() { + if true { + } else falsy!() { + //~^ ERROR expected `{`, found `falsy` + } +} + +fn foo6() { + if true { + } else falsy!(); + //~^ ERROR expected `{`, found `falsy` +} + +fn foo7() { + if true { + } else falsy! {} { + //~^ ERROR expected `{`, found `falsy` + } +} + +fn foo8() { + if true { + } else falsy! {}; + //~^ ERROR expected `{`, found `falsy` +} + fn falsy() -> bool { false } diff --git a/tests/ui/parser/else-no-if.stderr b/tests/ui/parser/else-no-if.stderr index b9c1a75276c1f..9954505e7c8d4 100644 --- a/tests/ui/parser/else-no-if.stderr +++ b/tests/ui/parser/else-no-if.stderr @@ -1,5 +1,5 @@ error: expected `{`, found keyword `false` - --> $DIR/else-no-if.rs:3:12 + --> $DIR/else-no-if.rs:7:12 | LL | } else false { | ---- ^^^^^ @@ -12,7 +12,7 @@ LL | } else if false { | ++ error: expected `{`, found `falsy` - --> $DIR/else-no-if.rs:10:12 + --> $DIR/else-no-if.rs:14:12 | LL | } else falsy() { | ---- ^^^^^ @@ -25,7 +25,7 @@ LL | } else if falsy() { | ++ error: expected `{`, found `falsy` - --> $DIR/else-no-if.rs:17:12 + --> $DIR/else-no-if.rs:21:12 | LL | } else falsy(); | ^^^^^ expected `{` @@ -36,7 +36,7 @@ LL | } else { falsy() }; | + + error: expected `{`, found keyword `loop` - --> $DIR/else-no-if.rs:23:12 + --> $DIR/else-no-if.rs:27:12 | LL | } else loop{} | ^^^^ expected `{` @@ -46,5 +46,53 @@ help: try placing this code inside a block LL | } else { loop{} } | + + -error: aborting due to 4 previous errors +error: expected `{`, found `falsy` + --> $DIR/else-no-if.rs:34:12 + | +LL | } else falsy!() { + | ---- ^^^^^ + | | + | expected an `if` or a block after this `else` + | +help: add an `if` if this is the condition of a chained `else if` statement + | +LL | } else if falsy!() { + | ++ + +error: expected `{`, found `falsy` + --> $DIR/else-no-if.rs:41:12 + | +LL | } else falsy!(); + | ^^^^^ expected `{` + | +help: try placing this code inside a block + | +LL | } else { falsy!() }; + | + + + +error: expected `{`, found `falsy` + --> $DIR/else-no-if.rs:47:12 + | +LL | } else falsy! {} { + | ---- ^^^^^ + | | + | expected an `if` or a block after this `else` + | +help: add an `if` if this is the condition of a chained `else if` statement + | +LL | } else if falsy! {} { + | ++ + +error: expected `{`, found `falsy` + --> $DIR/else-no-if.rs:54:12 + | +LL | } else falsy! {}; + | ^^^^^ expected `{` + | +help: try placing this code inside a block + | +LL | } else { falsy! {} }; + | + + + +error: aborting due to 8 previous errors From aedc1b6ad4845242d06a3f7cfb9b57db227b3511 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Fri, 29 Dec 2023 17:37:32 -0800 Subject: [PATCH 104/179] Remove MacCall special case from recovery after missing 'if' after 'else' The change to the test is a little goofy because the compiler was guessing "correctly" before that `falsy! {}` is the condition as opposed to the else body. But I believe this change is fundamentally correct. Braced macro invocations in statement position are most often item-like (`thread_local! {...}`) as opposed to parenthesized macro invocations which are condition-like (`cfg!(...)`). --- compiler/rustc_parse/src/parser/expr.rs | 34 ++++++++++++++++++++----- tests/ui/parser/else-no-if.stderr | 10 +++----- 2 files changed, 32 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index bb0873a814dfa..52e3e33691a13 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -2733,13 +2733,35 @@ impl<'a> Parser<'a> { let first_tok_span = self.token.span; match self.parse_expr() { Ok(cond) - // If it's not a free-standing expression, and is followed by a block, - // then it's very likely the condition to an `else if`. + // Try to guess the difference between a "condition-like" vs + // "statement-like" expression. + // + // We are seeing the following code, in which $cond is neither + // ExprKind::Block nor ExprKind::If (the 2 cases wherein this + // would be valid syntax). + // + // if ... { + // } else $cond + // + // If $cond is "condition-like" such as ExprKind::Binary, we + // want to suggest inserting `if`. + // + // if ... { + // } else if a == b { + // ^^ + // } + // + // If $cond is "statement-like" such as ExprKind::While then we + // want to suggest wrapping in braces. + // + // if ... { + // } else { + // ^ + // while true {} + // } + // ^ if self.check(&TokenKind::OpenDelim(Delimiter::Brace)) - && match cond.kind { - ExprKind::MacCall(_) => true, - _ => classify::expr_requires_semi_to_be_stmt(&cond), - } => + && classify::expr_requires_semi_to_be_stmt(&cond) => { self.dcx().emit_err(errors::ExpectedElseBlock { first_tok_span, diff --git a/tests/ui/parser/else-no-if.stderr b/tests/ui/parser/else-no-if.stderr index 9954505e7c8d4..2e3e8f6b50e95 100644 --- a/tests/ui/parser/else-no-if.stderr +++ b/tests/ui/parser/else-no-if.stderr @@ -74,14 +74,12 @@ error: expected `{`, found `falsy` --> $DIR/else-no-if.rs:47:12 | LL | } else falsy! {} { - | ---- ^^^^^ - | | - | expected an `if` or a block after this `else` + | ^^^^^ expected `{` | -help: add an `if` if this is the condition of a chained `else if` statement +help: try placing this code inside a block | -LL | } else if falsy! {} { - | ++ +LL | } else { falsy! {} } { + | + + error: expected `{`, found `falsy` --> $DIR/else-no-if.rs:54:12 From 53521faf06cb5ada4df7984fcd53b602b4ee2dd0 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Fri, 29 Dec 2023 18:04:04 -0800 Subject: [PATCH 105/179] Remove MacCall special cases from Parser::parse_full_stmt It is impossible for expr here to be a braced macro call. Expr comes from `parse_stmt_without_recovery`, in which macro calls are parsed by `parse_stmt_mac`. See this part: let kind = if (style == MacStmtStyle::Braces && self.token != token::Dot && self.token != token::Question) || self.token == token::Semi || self.token == token::Eof { StmtKind::MacCall(P(MacCallStmt { mac, style, attrs, tokens: None })) } else { // Since none of the above applied, this is an expression statement macro. let e = self.mk_expr(lo.to(hi), ExprKind::MacCall(mac)); let e = self.maybe_recover_from_bad_qpath(e)?; let e = self.parse_expr_dot_or_call_with(e, lo, attrs)?; let e = self.parse_expr_assoc_with( 0, LhsExpr::AlreadyParsed { expr: e, starts_statement: false }, )?; StmtKind::Expr(e) }; A braced macro call at the head of a statement is always either extended into ExprKind::Field / MethodCall / Await / Try / Binary, or else returned as StmtKind::MacCall. We can never get a StmtKind::Expr containing ExprKind::MacCall containing brace delimiter. --- compiler/rustc_parse/src/parser/stmt.rs | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs index 684799eb6a78d..d70afebf1b2da 100644 --- a/compiler/rustc_parse/src/parser/stmt.rs +++ b/compiler/rustc_parse/src/parser/stmt.rs @@ -648,10 +648,8 @@ impl<'a> Parser<'a> { match &mut stmt.kind { // Expression without semicolon. StmtKind::Expr(expr) - if match expr.kind { - ExprKind::MacCall(_) => true, - _ => classify::expr_requires_semi_to_be_stmt(expr), - } && !expr.attrs.is_empty() + if classify::expr_requires_semi_to_be_stmt(expr) + && !expr.attrs.is_empty() && ![token::Eof, token::Semi, token::CloseDelim(Delimiter::Brace)] .contains(&self.token.kind) => { @@ -664,11 +662,7 @@ impl<'a> Parser<'a> { // Expression without semicolon. StmtKind::Expr(expr) - if self.token != token::Eof - && match expr.kind { - ExprKind::MacCall(_) => true, - _ => classify::expr_requires_semi_to_be_stmt(expr), - } => + if self.token != token::Eof && classify::expr_requires_semi_to_be_stmt(expr) => { // Just check for errors and recover; do not eat semicolon yet. From 923cdb35aa7099a20e06662ddc871e384c49cbc9 Mon Sep 17 00:00:00 2001 From: Federico Maria Morrone Date: Sun, 12 May 2024 01:25:11 +0200 Subject: [PATCH 106/179] test: Add assembly tests for x86_64-unknown-linux-none target --- tests/assembly/targets/targets-elf.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/assembly/targets/targets-elf.rs b/tests/assembly/targets/targets-elf.rs index 3563aec6d8078..0db2a35800269 100644 --- a/tests/assembly/targets/targets-elf.rs +++ b/tests/assembly/targets/targets-elf.rs @@ -555,6 +555,9 @@ //@ revisions: x86_64_unknown_linux_ohos //@ [x86_64_unknown_linux_ohos] compile-flags: --target x86_64-unknown-linux-ohos //@ [x86_64_unknown_linux_ohos] needs-llvm-components: x86 +//@ revisions: x86_64_unknown_linux_none +//@ [x86_64_unknown_linux_none] compile-flags: --target x86_64-unknown-linux-none +//@ [x86_64_unknown_linux_none] needs-llvm-components: x86 //@ revisions: x86_64_unknown_netbsd //@ [x86_64_unknown_netbsd] compile-flags: --target x86_64-unknown-netbsd //@ [x86_64_unknown_netbsd] needs-llvm-components: x86 From d13e5c483dcdfed9724d03dbb2c28827fda4c365 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 11 May 2024 19:28:58 -0400 Subject: [PATCH 107/179] And `ImplPolarity` too --- compiler/rustc_middle/src/ty/mod.rs | 24 ------------------------ compiler/rustc_type_ir/src/predicate.rs | 24 ++++++++++++++++++++++++ 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 2b0d879696866..4d3b92bf2affd 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -275,30 +275,6 @@ pub enum ImplSubject<'tcx> { Inherent(Ty<'tcx>), } -#[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable, HashStable, Debug)] -#[derive(TypeFoldable, TypeVisitable)] -pub enum ImplPolarity { - /// `impl Trait for Type` - Positive, - /// `impl !Trait for Type` - Negative, - /// `#[rustc_reservation_impl] impl Trait for Type` - /// - /// This is a "stability hack", not a real Rust feature. - /// See #64631 for details. - Reservation, -} - -impl fmt::Display for ImplPolarity { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - Self::Positive => f.write_str("positive"), - Self::Negative => f.write_str("negative"), - Self::Reservation => f.write_str("reservation"), - } - } -} - #[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable, HashStable, Debug)] #[derive(TypeFoldable, TypeVisitable)] pub enum Asyncness { diff --git a/compiler/rustc_type_ir/src/predicate.rs b/compiler/rustc_type_ir/src/predicate.rs index b2510cb01df38..f84f8f47c6767 100644 --- a/compiler/rustc_type_ir/src/predicate.rs +++ b/compiler/rustc_type_ir/src/predicate.rs @@ -115,6 +115,30 @@ impl fmt::Debug for TraitPredicate { } } +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] +#[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))] +pub enum ImplPolarity { + /// `impl Trait for Type` + Positive, + /// `impl !Trait for Type` + Negative, + /// `#[rustc_reservation_impl] impl Trait for Type` + /// + /// This is a "stability hack", not a real Rust feature. + /// See #64631 for details. + Reservation, +} + +impl fmt::Display for ImplPolarity { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Self::Positive => f.write_str("positive"), + Self::Negative => f.write_str("negative"), + Self::Reservation => f.write_str("reservation"), + } + } +} + /// Polarity for a trait predicate. May either be negative or positive. /// Distinguished from [`ImplPolarity`] since we never compute goals with /// "reservation" level. From f11bd7e955e93b994d6e3f2c991be95a9614a51b Mon Sep 17 00:00:00 2001 From: Ben Kimock Date: Sat, 11 May 2024 19:29:07 -0400 Subject: [PATCH 108/179] Fix some minor issues from the ui-test auto-porting --- tests/codegen-units/partitioning/extern-drop-glue.rs | 5 +---- tests/codegen-units/partitioning/extern-generic.rs | 4 +--- tests/codegen-units/partitioning/incremental-merging.rs | 3 +-- .../codegen-units/partitioning/inlining-from-extern-crate.rs | 4 +--- tests/codegen-units/partitioning/local-drop-glue.rs | 4 +--- tests/codegen-units/partitioning/local-generic.rs | 3 +-- .../codegen-units/partitioning/local-inlining-but-not-all.rs | 4 +--- tests/codegen-units/partitioning/local-inlining.rs | 4 +--- .../codegen-units/partitioning/local-transitive-inlining.rs | 4 +--- .../codegen-units/partitioning/methods-are-with-self-type.rs | 4 +--- tests/codegen-units/partitioning/regular-modules.rs | 3 +-- tests/codegen-units/partitioning/shared-generics.rs | 1 - tests/codegen-units/partitioning/statics.rs | 3 +-- tests/codegen-units/partitioning/vtable-through-const.rs | 5 +---- 14 files changed, 13 insertions(+), 38 deletions(-) diff --git a/tests/codegen-units/partitioning/extern-drop-glue.rs b/tests/codegen-units/partitioning/extern-drop-glue.rs index 84eb802f264b8..d3bce7b4223cc 100644 --- a/tests/codegen-units/partitioning/extern-drop-glue.rs +++ b/tests/codegen-units/partitioning/extern-drop-glue.rs @@ -1,7 +1,4 @@ -// - -// We specify incremental here because we want to test the partitioning for -//@ incremental compilation +// We specify incremental here because we want to test the partitioning for incremental compilation // We specify opt-level=0 because `drop_in_place` is `Internal` when optimizing //@ incremental //@ compile-flags:-Zprint-mono-items=lazy diff --git a/tests/codegen-units/partitioning/extern-generic.rs b/tests/codegen-units/partitioning/extern-generic.rs index abd3918094d74..0e4b6a37f7122 100644 --- a/tests/codegen-units/partitioning/extern-generic.rs +++ b/tests/codegen-units/partitioning/extern-generic.rs @@ -1,6 +1,4 @@ -// -// We specify incremental here because we want to test the partitioning for -//@ incremental compilation +// We specify incremental here because we want to test the partitioning for incremental compilation //@ incremental //@ compile-flags:-Zprint-mono-items=eager -Zshare-generics=y diff --git a/tests/codegen-units/partitioning/incremental-merging.rs b/tests/codegen-units/partitioning/incremental-merging.rs index b44090c866a0f..6834bb2bebf5c 100644 --- a/tests/codegen-units/partitioning/incremental-merging.rs +++ b/tests/codegen-units/partitioning/incremental-merging.rs @@ -1,5 +1,4 @@ -// We specify incremental here because we want to test the partitioning for -//@ incremental compilation +// We specify incremental here because we want to test the partitioning for incremental compilation //@ incremental //@ compile-flags:-Zprint-mono-items=lazy //@ compile-flags:-Ccodegen-units=3 diff --git a/tests/codegen-units/partitioning/inlining-from-extern-crate.rs b/tests/codegen-units/partitioning/inlining-from-extern-crate.rs index 74734d3cf38a1..d021f467f1f98 100644 --- a/tests/codegen-units/partitioning/inlining-from-extern-crate.rs +++ b/tests/codegen-units/partitioning/inlining-from-extern-crate.rs @@ -1,6 +1,4 @@ -// -// We specify incremental here because we want to test the partitioning for -//@ incremental compilation +// We specify incremental here because we want to test the partitioning for incremental compilation //@ incremental //@ compile-flags:-Zprint-mono-items=lazy //@ compile-flags:-Zinline-in-all-cgus diff --git a/tests/codegen-units/partitioning/local-drop-glue.rs b/tests/codegen-units/partitioning/local-drop-glue.rs index 0974187ade0dd..5fa1df95cbc82 100644 --- a/tests/codegen-units/partitioning/local-drop-glue.rs +++ b/tests/codegen-units/partitioning/local-drop-glue.rs @@ -1,6 +1,4 @@ -// -// We specify incremental here because we want to test the partitioning for -//@ incremental compilation +// We specify incremental here because we want to test the partitioning for incremental compilation // We specify opt-level=0 because `drop_in_place` is `Internal` when optimizing //@ incremental //@ compile-flags:-Zprint-mono-items=lazy diff --git a/tests/codegen-units/partitioning/local-generic.rs b/tests/codegen-units/partitioning/local-generic.rs index 2cfdc27ccb149..06f46b23db6ae 100644 --- a/tests/codegen-units/partitioning/local-generic.rs +++ b/tests/codegen-units/partitioning/local-generic.rs @@ -1,5 +1,4 @@ -// We specify incremental here because we want to test the partitioning for -//@ incremental compilation +// We specify incremental here because we want to test the partitioning for incremental compilation //@ incremental //@ compile-flags:-Zprint-mono-items=eager diff --git a/tests/codegen-units/partitioning/local-inlining-but-not-all.rs b/tests/codegen-units/partitioning/local-inlining-but-not-all.rs index 49a2ce7c5d9d4..2f9cbe83f1d56 100644 --- a/tests/codegen-units/partitioning/local-inlining-but-not-all.rs +++ b/tests/codegen-units/partitioning/local-inlining-but-not-all.rs @@ -1,6 +1,4 @@ -// -// We specify incremental here because we want to test the partitioning for -//@ incremental compilation +// We specify incremental here because we want to test the partitioning for incremental compilation //@ incremental //@ compile-flags:-Zprint-mono-items=lazy //@ compile-flags:-Zinline-in-all-cgus=no diff --git a/tests/codegen-units/partitioning/local-inlining.rs b/tests/codegen-units/partitioning/local-inlining.rs index 726cf2b87d268..2329a876c960f 100644 --- a/tests/codegen-units/partitioning/local-inlining.rs +++ b/tests/codegen-units/partitioning/local-inlining.rs @@ -1,6 +1,4 @@ -// -// We specify incremental here because we want to test the partitioning for -//@ incremental compilation +// We specify incremental here because we want to test the partitioning for incremental compilation //@ incremental //@ compile-flags:-Zprint-mono-items=lazy //@ compile-flags:-Zinline-in-all-cgus diff --git a/tests/codegen-units/partitioning/local-transitive-inlining.rs b/tests/codegen-units/partitioning/local-transitive-inlining.rs index 355eb6cf3954b..4ccc53aea1d12 100644 --- a/tests/codegen-units/partitioning/local-transitive-inlining.rs +++ b/tests/codegen-units/partitioning/local-transitive-inlining.rs @@ -1,6 +1,4 @@ -// -// We specify incremental here because we want to test the partitioning for -//@ incremental compilation +// We specify incremental here because we want to test the partitioning for incremental compilation //@ incremental //@ compile-flags:-Zprint-mono-items=lazy //@ compile-flags:-Zinline-in-all-cgus diff --git a/tests/codegen-units/partitioning/methods-are-with-self-type.rs b/tests/codegen-units/partitioning/methods-are-with-self-type.rs index 2e54725ff2850..3ba53334cc907 100644 --- a/tests/codegen-units/partitioning/methods-are-with-self-type.rs +++ b/tests/codegen-units/partitioning/methods-are-with-self-type.rs @@ -3,9 +3,7 @@ // much sense at the moment. //@ ignore-test -// -// We specify incremental here because we want to test the partitioning for -//@ incremental compilation +// We specify incremental here because we want to test the partitioning for incremental compilation //@ incremental //@ compile-flags:-Zprint-mono-items=lazy diff --git a/tests/codegen-units/partitioning/regular-modules.rs b/tests/codegen-units/partitioning/regular-modules.rs index 0eb0848e45446..68601975d0627 100644 --- a/tests/codegen-units/partitioning/regular-modules.rs +++ b/tests/codegen-units/partitioning/regular-modules.rs @@ -1,5 +1,4 @@ -// We specify incremental here because we want to test the partitioning for -//@ incremental compilation +// We specify incremental here because we want to test the partitioning for incremental compilation //@ incremental //@ compile-flags:-Zprint-mono-items=eager diff --git a/tests/codegen-units/partitioning/shared-generics.rs b/tests/codegen-units/partitioning/shared-generics.rs index 25ea7fab7355c..5b78794316c68 100644 --- a/tests/codegen-units/partitioning/shared-generics.rs +++ b/tests/codegen-units/partitioning/shared-generics.rs @@ -1,4 +1,3 @@ -// //@ no-prefer-dynamic // NOTE: We always compile this test with -Copt-level=0 because higher opt-levels // prevent drop-glue from participating in share-generics. diff --git a/tests/codegen-units/partitioning/statics.rs b/tests/codegen-units/partitioning/statics.rs index 9503a91b0ab4b..c7eef1f3789d9 100644 --- a/tests/codegen-units/partitioning/statics.rs +++ b/tests/codegen-units/partitioning/statics.rs @@ -1,5 +1,4 @@ -// We specify incremental here because we want to test the partitioning for -//@ incremental compilation +// We specify incremental here because we want to test the partitioning for incremental compilation //@ incremental //@ compile-flags:-Zprint-mono-items=lazy diff --git a/tests/codegen-units/partitioning/vtable-through-const.rs b/tests/codegen-units/partitioning/vtable-through-const.rs index 111b4fa1b9ac2..ca4d3822b5491 100644 --- a/tests/codegen-units/partitioning/vtable-through-const.rs +++ b/tests/codegen-units/partitioning/vtable-through-const.rs @@ -1,7 +1,4 @@ -// - -// We specify incremental here because we want to test the partitioning for -//@ incremental compilation +// We specify incremental here because we want to test the partitioning for incremental compilation //@ incremental //@ compile-flags:-Zprint-mono-items=lazy //@ compile-flags:-Zinline-in-all-cgus From 10227eaee70fb9e042bb0b317ad562677c81661d Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Fri, 19 Apr 2024 18:46:16 -0700 Subject: [PATCH 109/179] Add classify::expr_is_complete --- compiler/rustc_ast/src/util/classify.rs | 96 +++++++++++++++---------- compiler/rustc_parse/src/parser/expr.rs | 62 +--------------- 2 files changed, 60 insertions(+), 98 deletions(-) diff --git a/compiler/rustc_ast/src/util/classify.rs b/compiler/rustc_ast/src/util/classify.rs index 86383af1f7c83..f6e9e1a87c4bb 100644 --- a/compiler/rustc_ast/src/util/classify.rs +++ b/compiler/rustc_ast/src/util/classify.rs @@ -1,12 +1,60 @@ //! Routines the parser and pretty-printer use to classify AST nodes. +use crate::ast::ExprKind::*; use crate::{ast, token::Delimiter}; +/// This classification determines whether various syntactic positions break out +/// of parsing the current expression (true) or continue parsing more of the +/// same expression (false). +/// +/// For example, it's relevant in the parsing of match arms: +/// +/// ```ignore (illustrative) +/// match ... { +/// // Is this calling $e as a function, or is it the start of a new arm +/// // with a tuple pattern? +/// _ => $e ( +/// ^ ) +/// +/// // Is this an Index operation, or new arm with a slice pattern? +/// _ => $e [ +/// ^ ] +/// +/// // Is this a binary operator, or leading vert in a new arm? Same for +/// // other punctuation which can either be a binary operator in +/// // expression or unary operator in pattern, such as `&` and `-`. +/// _ => $e | +/// ^ +/// } +/// ``` +/// +/// If $e is something like `{}` or `if … {}`, then terminate the current +/// arm and parse a new arm. +/// +/// If $e is something like `path::to` or `(…)`, continue parsing the same +/// arm. +/// +/// *Almost* the same classification is used as an early bail-out for parsing +/// statements. See `expr_requires_semi_to_be_stmt`. +pub fn expr_is_complete(e: &ast::Expr) -> bool { + matches!( + e.kind, + If(..) + | Match(..) + | Block(..) + | While(..) + | Loop(..) + | ForLoop { .. } + | TryBlock(..) + | ConstBlock(..) + ) +} + /// Does this expression require a semicolon to be treated as a statement? /// /// The negation of this: "can this expression be used as a statement without a -/// semicolon" -- is used as an early bail-out in the parser so that, for -/// instance, +/// semicolon" -- is used as an early bail-out when parsing statements so that, +/// for instance, /// /// ```ignore (illustrative) /// if true {...} else {...} @@ -15,56 +63,26 @@ use crate::{ast, token::Delimiter}; /// /// isn't parsed as `(if true {...} else {...} | x) | 5`. /// -/// Nearly the same early bail-out also occurs in the right-hand side of match -/// arms: +/// Surprising special case: even though braced macro calls like `m! {}` +/// normally do not introduce a boundary when found at the head of a match arm, +/// they do terminate the parsing of a statement. /// /// ```ignore (illustrative) -/// match i { -/// 0 => if true {...} else {...} -/// | x => {} +/// match ... { +/// _ => m! {} (), // macro that expands to a function, which is then called /// } -/// ``` -/// -/// Here the `|` is a leading vert in a second match arm. It is not a binary -/// operator with the If as its left operand. If the first arm were some other -/// expression for which `expr_requires_semi_to_be_stmt` returns true, then the -/// `|` on the next line would be a binary operator (leading to a parse error). /// -/// The statement case and the match-arm case are "nearly" the same early -/// bail-out because of 1 edge case. Macro calls with brace delimiter terminate -/// a statement without a semicolon, but do not terminate a match-arm without -/// comma. -/// -/// ```ignore (illustrative) -/// m! {} - 1; // two statements: a macro call followed by -1 literal -/// -/// match () { -/// _ => m! {} - 1, // binary subtraction operator -/// } +/// let _ = { m! {} () }; // macro call followed by unit /// ``` pub fn expr_requires_semi_to_be_stmt(e: &ast::Expr) -> bool { - use ast::ExprKind::*; - match &e.kind { - If(..) - | Match(..) - | Block(..) - | While(..) - | Loop(..) - | ForLoop { .. } - | TryBlock(..) - | ConstBlock(..) => false, - MacCall(mac_call) => mac_call.args.delim != Delimiter::Brace, - - _ => true, + _ => !expr_is_complete(e), } } /// If an expression ends with `}`, returns the innermost expression ending in the `}` pub fn expr_trailing_brace(mut expr: &ast::Expr) -> Option<&ast::Expr> { - use ast::ExprKind::*; - loop { match &expr.kind { AddrOf(_, _, e) diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 52e3e33691a13..441aa5b0806da 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -496,51 +496,8 @@ impl<'a> Parser<'a> { } /// Checks if this expression is a successfully parsed statement. - /// - /// This determines whether to continue parsing more of an expression in a - /// match arm (false) vs continue to the next arm (true). - /// - /// ```ignore (illustrative) - /// match ... { - /// // Is this calling $e as a function, or is it the start of a new arm - /// // with a tuple pattern? - /// _ => $e ( - /// ^ ) - /// - /// // Is this an Index operation, or new arm with a slice pattern? - /// _ => $e [ - /// ^ ] - /// - /// // Is this a binary operator, or leading vert in a new arm? Same for - /// // other punctuation which can either be a binary operator in - /// // expression or unary operator in pattern, such as `&` and `-`. - /// _ => $e | - /// ^ - /// } - /// ``` - /// - /// If $e is something like `path::to` or `(…)`, continue parsing the same - /// arm. - /// - /// If $e is something like `{}` or `if … {}`, then terminate the current - /// arm and parse a new arm. fn expr_is_complete(&self, e: &Expr) -> bool { - self.restrictions.contains(Restrictions::STMT_EXPR) - && match e.kind { - // Surprising special case: even though braced macro calls like - // `m! {}` normally introduce a statement boundary when found at - // the head of a statement, in match arms they do not terminate - // the arm. - // - // let _ = { m! {} () }; // macro call followed by unit - // - // match ... { - // _ => m! {} (), // macro that expands to a function, which is then called - // } - // - ExprKind::MacCall(_) => false, - _ => !classify::expr_requires_semi_to_be_stmt(e), - } + self.restrictions.contains(Restrictions::STMT_EXPR) && classify::expr_is_complete(e) } /// Parses `x..y`, `x..=y`, and `x..`/`x..=`. @@ -3203,21 +3160,8 @@ impl<'a> Parser<'a> { err })?; - let require_comma = match expr.kind { - // Special case: braced macro calls require comma in a match - // arm, even though they do not require semicolon in a - // statement. - // - // m! {} // okay without semicolon - // - // match ... { - // _ => m! {}, // requires comma - // _ => ... - // } - // - ExprKind::MacCall(_) => true, - _ => classify::expr_requires_semi_to_be_stmt(&expr), - } && this.token != token::CloseDelim(Delimiter::Brace); + let require_comma = !classify::expr_is_complete(&expr) + && this.token != token::CloseDelim(Delimiter::Brace); if !require_comma { arm_body = Some(expr); From 78c8dc123495f19b2da8e655cd5b95fff161c8c1 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Sat, 20 Apr 2024 11:23:01 -0700 Subject: [PATCH 110/179] Fix redundant parens around braced macro call in match arms --- .../rustc_ast_pretty/src/pprust/state/expr.rs | 2 +- .../src/pprust/state/fixup.rs | 57 +++++++++++++++++-- tests/ui/macros/stringify.rs | 2 +- 3 files changed, 54 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs index 93400c67949d9..1e117c46b6e29 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs @@ -780,7 +780,7 @@ impl<'a> State<'a> { } _ => { self.end(); // Close the ibox for the pattern. - self.print_expr(body, FixupContext::new_stmt()); + self.print_expr(body, FixupContext::new_match_arm()); self.word(","); } } diff --git a/compiler/rustc_ast_pretty/src/pprust/state/fixup.rs b/compiler/rustc_ast_pretty/src/pprust/state/fixup.rs index d21cb82f83b28..86d4796e9ce3b 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state/fixup.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state/fixup.rs @@ -49,6 +49,38 @@ pub(crate) struct FixupContext { /// No parentheses required. leftmost_subexpression_in_stmt: bool, + /// Print expression such that it can be parsed as a match arm. + /// + /// This is almost equivalent to `stmt`, but the grammar diverges a tiny bit + /// between statements and match arms when it comes to braced macro calls. + /// Macro calls with brace delimiter terminate a statement without a + /// semicolon, but do not terminate a match-arm without comma. + /// + /// ```ignore (illustrative) + /// m! {} - 1; // two statements: a macro call followed by -1 literal + /// + /// match () { + /// _ => m! {} - 1, // binary subtraction operator + /// } + /// ``` + match_arm: bool, + + /// This is almost equivalent to `leftmost_subexpression_in_stmt`, other + /// than for braced macro calls. + /// + /// If we have `m! {} - 1` as an expression, the leftmost subexpression + /// `m! {}` will need to be parenthesized in the statement case but not the + /// match-arm case. + /// + /// ```ignore (illustrative) + /// (m! {}) - 1; // subexpression needs parens + /// + /// match () { + /// _ => m! {} - 1, // no parens + /// } + /// ``` + leftmost_subexpression_in_match_arm: bool, + /// This is the difference between: /// /// ```ignore (illustrative) @@ -68,6 +100,8 @@ impl Default for FixupContext { FixupContext { stmt: false, leftmost_subexpression_in_stmt: false, + match_arm: false, + leftmost_subexpression_in_match_arm: false, parenthesize_exterior_struct_lit: false, } } @@ -76,13 +110,16 @@ impl Default for FixupContext { impl FixupContext { /// Create the initial fixup for printing an expression in statement /// position. - /// - /// This is currently also used for printing an expression as a match-arm, - /// but this is incorrect and leads to over-parenthesizing. pub fn new_stmt() -> Self { FixupContext { stmt: true, ..FixupContext::default() } } + /// Create the initial fixup for printing an expression as the right-hand + /// side of a match arm. + pub fn new_match_arm() -> Self { + FixupContext { match_arm: true, ..FixupContext::default() } + } + /// Create the initial fixup for printing an expression as the "condition" /// of an `if` or `while`. There are a few other positions which are /// grammatically equivalent and also use this, such as the iterator @@ -106,6 +143,9 @@ impl FixupContext { FixupContext { stmt: false, leftmost_subexpression_in_stmt: self.stmt || self.leftmost_subexpression_in_stmt, + match_arm: false, + leftmost_subexpression_in_match_arm: self.match_arm + || self.leftmost_subexpression_in_match_arm, ..self } } @@ -119,7 +159,13 @@ impl FixupContext { /// example the `$b` in `$a + $b` and `-$b`, but not the one in `[$b]` or /// `$a.f($b)`. pub fn subsequent_subexpression(self) -> Self { - FixupContext { stmt: false, leftmost_subexpression_in_stmt: false, ..self } + FixupContext { + stmt: false, + leftmost_subexpression_in_stmt: false, + match_arm: false, + leftmost_subexpression_in_match_arm: false, + ..self + } } /// Determine whether parentheses are needed around the given expression to @@ -128,7 +174,8 @@ impl FixupContext { /// The documentation on `FixupContext::leftmost_subexpression_in_stmt` has /// examples. pub fn would_cause_statement_boundary(self, expr: &Expr) -> bool { - self.leftmost_subexpression_in_stmt && !classify::expr_requires_semi_to_be_stmt(expr) + (self.leftmost_subexpression_in_stmt && !classify::expr_requires_semi_to_be_stmt(expr)) + || (self.leftmost_subexpression_in_match_arm && classify::expr_is_complete(expr)) } /// Determine whether parentheses are needed around the given `let` diff --git a/tests/ui/macros/stringify.rs b/tests/ui/macros/stringify.rs index a66a5513ffae3..472cb4d417be8 100644 --- a/tests/ui/macros/stringify.rs +++ b/tests/ui/macros/stringify.rs @@ -225,7 +225,7 @@ fn test_expr() { ); c2_match_arm!( [ m! {} - 1 ], - "match () { _ => (m! {}) - 1, }", // parenthesis is redundant + "match () { _ => m! {} - 1, }", "match () { _ => m! {} - 1 }", ); From 41ebd16266423ea3038be34112c80eceed5b9e94 Mon Sep 17 00:00:00 2001 From: lcnr Date: Sun, 12 May 2024 03:29:50 +0000 Subject: [PATCH 111/179] solve: replace all `debug` with `trace` --- .../src/solve/alias_relate.rs | 4 +-- .../src/solve/assembly/mod.rs | 24 +++++++------- .../src/solve/assembly/structural_traits.rs | 6 ++-- .../src/solve/eval_ctxt/canonical.rs | 10 +++--- .../src/solve/eval_ctxt/mod.rs | 32 +++++++++---------- .../src/solve/fulfill.rs | 2 +- .../rustc_trait_selection/src/solve/mod.rs | 22 ++++++------- .../src/solve/normalize.rs | 4 +-- .../src/solve/normalizes_to/anon_const.rs | 2 +- .../src/solve/normalizes_to/mod.rs | 8 ++--- .../src/solve/project_goals.rs | 2 +- .../src/solve/search_graph.rs | 6 ++-- .../src/solve/trait_goals.rs | 4 +-- 13 files changed, 63 insertions(+), 63 deletions(-) diff --git a/compiler/rustc_trait_selection/src/solve/alias_relate.rs b/compiler/rustc_trait_selection/src/solve/alias_relate.rs index f2c441dcbeda6..e079809aecc99 100644 --- a/compiler/rustc_trait_selection/src/solve/alias_relate.rs +++ b/compiler/rustc_trait_selection/src/solve/alias_relate.rs @@ -20,7 +20,7 @@ use rustc_middle::traits::solve::{Certainty, Goal, QueryResult}; use rustc_middle::ty; impl<'tcx> EvalCtxt<'_, 'tcx> { - #[instrument(level = "debug", skip(self), ret)] + #[instrument(level = "trace", skip(self), ret)] pub(super) fn compute_alias_relate_goal( &mut self, goal: Goal<'tcx, (ty::Term<'tcx>, ty::Term<'tcx>, ty::AliasRelationDirection)>, @@ -50,7 +50,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { self.try_evaluate_added_goals()?; let lhs = self.resolve_vars_if_possible(lhs); let rhs = self.resolve_vars_if_possible(rhs); - debug!(?lhs, ?rhs); + trace!(?lhs, ?rhs); let variance = match direction { ty::AliasRelationDirection::Equate => ty::Variance::Invariant, diff --git a/compiler/rustc_trait_selection/src/solve/assembly/mod.rs b/compiler/rustc_trait_selection/src/solve/assembly/mod.rs index f2ca42a0be91e..ebd633b236712 100644 --- a/compiler/rustc_trait_selection/src/solve/assembly/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/assembly/mod.rs @@ -282,7 +282,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { }; if normalized_self_ty.is_ty_var() { - debug!("self type has been normalized to infer"); + trace!("self type has been normalized to infer"); return self.forced_ambiguity(MaybeCause::Ambiguity).into_iter().collect(); } @@ -331,7 +331,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { .enter(|this| this.evaluate_added_goals_and_make_canonical_response(certainty)) } - #[instrument(level = "debug", skip_all)] + #[instrument(level = "trace", skip_all)] fn assemble_non_blanket_impl_candidates>( &mut self, goal: Goal<'tcx, G>, @@ -447,7 +447,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { } } - #[instrument(level = "debug", skip_all)] + #[instrument(level = "trace", skip_all)] fn assemble_blanket_impl_candidates>( &mut self, goal: Goal<'tcx, G>, @@ -470,7 +470,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { } } - #[instrument(level = "debug", skip_all)] + #[instrument(level = "trace", skip_all)] fn assemble_builtin_impl_candidates>( &mut self, goal: Goal<'tcx, G>, @@ -544,7 +544,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { } } - #[instrument(level = "debug", skip_all)] + #[instrument(level = "trace", skip_all)] fn assemble_param_env_candidates>( &mut self, goal: Goal<'tcx, G>, @@ -561,7 +561,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { } } - #[instrument(level = "debug", skip_all)] + #[instrument(level = "trace", skip_all)] fn assemble_alias_bound_candidates>( &mut self, goal: Goal<'tcx, G>, @@ -665,7 +665,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { } } - #[instrument(level = "debug", skip_all)] + #[instrument(level = "trace", skip_all)] fn assemble_object_bound_candidates>( &mut self, goal: Goal<'tcx, G>, @@ -756,7 +756,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { /// /// To do so we add an ambiguous candidate in case such an unknown impl could /// apply to the current goal. - #[instrument(level = "debug", skip_all)] + #[instrument(level = "trace", skip_all)] fn assemble_coherence_unknowable_candidates>( &mut self, goal: Goal<'tcx, G>, @@ -785,7 +785,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { // FIXME(@lcnr): The current structure here makes me unhappy and feels ugly. idk how // to improve this however. However, this should make it fairly straightforward to refine // the filtering going forward, so it seems alright-ish for now. - #[instrument(level = "debug", skip(self, goal))] + #[instrument(level = "trace", skip(self, goal))] fn discard_impls_shadowed_by_env>( &mut self, goal: Goal<'tcx, G>, @@ -814,7 +814,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { Certainty::Yes => { candidates.retain(|c| match c.source { CandidateSource::Impl(_) | CandidateSource::BuiltinImpl(_) => { - debug!(?c, "discard impl candidate"); + trace!(?c, "discard impl candidate"); false } CandidateSource::ParamEnv(_) | CandidateSource::AliasBound => true, @@ -825,7 +825,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { // to be ambig and wait for inference constraints. See // tests/ui/traits/next-solver/env-shadows-impls/ambig-env-no-shadow.rs Certainty::Maybe(cause) => { - debug!(?cause, "force ambiguity"); + trace!(?cause, "force ambiguity"); *candidates = self.forced_ambiguity(cause).into_iter().collect(); } } @@ -836,7 +836,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { /// If there are multiple ways to prove a trait or projection goal, we have /// to somehow try to merge the candidates into one. If that fails, we return /// ambiguity. - #[instrument(level = "debug", skip(self), ret)] + #[instrument(level = "trace", skip(self), ret)] pub(super) fn merge_candidates( &mut self, candidates: Vec>, diff --git a/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs b/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs index a8b1a182d3c23..eeaef028cdb4d 100644 --- a/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs +++ b/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs @@ -17,7 +17,7 @@ use crate::solve::EvalCtxt; // // For types with an "existential" binder, i.e. coroutine witnesses, we also // instantiate the binder with placeholders eagerly. -#[instrument(level = "debug", skip(ecx), ret)] +#[instrument(level = "trace", skip(ecx), ret)] pub(in crate::solve) fn instantiate_constituent_tys_for_auto_trait<'tcx>( ecx: &EvalCtxt<'_, 'tcx>, ty: Ty<'tcx>, @@ -96,7 +96,7 @@ pub(in crate::solve) fn instantiate_constituent_tys_for_auto_trait<'tcx>( } } -#[instrument(level = "debug", skip(ecx), ret)] +#[instrument(level = "trace", skip(ecx), ret)] pub(in crate::solve) fn instantiate_constituent_tys_for_sized_trait<'tcx>( ecx: &EvalCtxt<'_, 'tcx>, ty: Ty<'tcx>, @@ -160,7 +160,7 @@ pub(in crate::solve) fn instantiate_constituent_tys_for_sized_trait<'tcx>( } } -#[instrument(level = "debug", skip(ecx), ret)] +#[instrument(level = "trace", skip(ecx), ret)] pub(in crate::solve) fn instantiate_constituent_tys_for_copy_clone_trait<'tcx>( ecx: &EvalCtxt<'_, 'tcx>, ty: Ty<'tcx>, diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs index d6010242e4cec..d5176dc321c08 100644 --- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs +++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs @@ -83,7 +83,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { /// the values inferred while solving the instantiated goal. /// - `external_constraints`: additional constraints which aren't expressible /// using simple unification of inference variables. - #[instrument(level = "debug", skip(self), ret)] + #[instrument(level = "trace", skip(self), ret)] pub(in crate::solve) fn evaluate_added_goals_and_make_canonical_response( &mut self, certainty: Certainty, @@ -166,7 +166,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { /// external constraints do not need to record that opaque, since if it is /// further constrained by inference, that will be passed back in the var /// values. - #[instrument(level = "debug", skip(self), ret)] + #[instrument(level = "trace", skip(self), ret)] fn compute_external_query_constraints( &self, normalization_nested_goals: NestedNormalizationGoals<'tcx>, @@ -174,7 +174,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { // We only check for leaks from universes which were entered inside // of the query. self.infcx.leak_check(self.max_input_universe, None).map_err(|e| { - debug!(?e, "failed the leak check"); + trace!(?e, "failed the leak check"); NoSolution })?; @@ -334,7 +334,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { /// whether an alias is rigid by using the trait solver. When instantiating a response /// from the solver we assume that the solver correctly handled aliases and therefore /// always relate them structurally here. - #[instrument(level = "debug", skip(infcx))] + #[instrument(level = "trace", skip(infcx))] fn unify_query_var_values( infcx: &InferCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, @@ -407,7 +407,7 @@ pub(in crate::solve) fn make_canonical_state<'tcx, T: TypeFoldable> /// This currently assumes that unifying the var values trivially succeeds. /// Adding any inference constraints which weren't present when originally /// computing the canonical query can result in bugs. -#[instrument(level = "debug", skip(infcx, span, param_env))] +#[instrument(level = "trace", skip(infcx, span, param_env))] pub(in crate::solve) fn instantiate_canonical_state<'tcx, T: TypeFoldable>>( infcx: &InferCtxt<'tcx>, span: Span, diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs index 9cd1841051ddd..1faf52232b6c5 100644 --- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs @@ -137,7 +137,7 @@ impl<'tcx> InferCtxt<'tcx> { /// /// Using this while inside of the solver is wrong as it uses a new /// search graph which would break cycle detection. - #[instrument(level = "debug", skip(self))] + #[instrument(level = "trace", skip(self))] fn evaluate_root_goal( &self, goal: Goal<'tcx, ty::Predicate<'tcx>>, @@ -276,7 +276,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> { /// Instead of calling this function directly, use either [EvalCtxt::evaluate_goal] /// if you're inside of the solver or [InferCtxtEvalExt::evaluate_root_goal] if you're /// outside of it. - #[instrument(level = "debug", skip(tcx, search_graph, goal_evaluation), ret)] + #[instrument(level = "trace", skip(tcx, search_graph, goal_evaluation), ret)] fn evaluate_canonical_goal( tcx: TyCtxt<'tcx>, search_graph: &'a mut search_graph::SearchGraph<'tcx>, @@ -458,13 +458,13 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> { } } - #[instrument(level = "debug", skip(self))] + #[instrument(level = "trace", skip(self))] pub(super) fn add_normalizes_to_goal(&mut self, goal: Goal<'tcx, ty::NormalizesTo<'tcx>>) { self.inspect.add_normalizes_to_goal(self.infcx, self.max_input_universe, goal); self.nested_goals.normalizes_to_goals.push(goal); } - #[instrument(level = "debug", skip(self))] + #[instrument(level = "trace", skip(self))] pub(super) fn add_goal(&mut self, source: GoalSource, goal: Goal<'tcx, ty::Predicate<'tcx>>) { self.inspect.add_goal(self.infcx, self.max_input_universe, source, goal); self.nested_goals.goals.push((source, goal)); @@ -472,7 +472,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> { // Recursively evaluates all the goals added to this `EvalCtxt` to completion, returning // the certainty of all the goals. - #[instrument(level = "debug", skip(self))] + #[instrument(level = "trace", skip(self))] pub(super) fn try_evaluate_added_goals(&mut self) -> Result { self.inspect.start_evaluate_added_goals(); let mut response = Ok(Certainty::overflow(false)); @@ -526,7 +526,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> { unconstrained_goal, )?; // Add the nested goals from normalization to our own nested goals. - debug!(?nested_goals); + trace!(?nested_goals); goals.goals.extend(nested_goals); // Finally, equate the goal's RHS with the unconstrained var. @@ -622,7 +622,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { /// /// This is the case if the `term` does not occur in any other part of the predicate /// and is able to name all other placeholder and inference variables. - #[instrument(level = "debug", skip(self), ret)] + #[instrument(level = "trace", skip(self), ret)] pub(super) fn term_is_fully_unconstrained( &self, goal: Goal<'tcx, ty::NormalizesTo<'tcx>>, @@ -718,7 +718,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { && goal.param_env.visit_with(&mut visitor).is_continue() } - #[instrument(level = "debug", skip(self, param_env), ret)] + #[instrument(level = "trace", skip(self, param_env), ret)] pub(super) fn eq>( &mut self, param_env: ty::ParamEnv<'tcx>, @@ -733,7 +733,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { self.add_goals(GoalSource::Misc, obligations.into_iter().map(|o| o.into())); }) .map_err(|e| { - debug!(?e, "failed to equate"); + trace!(?e, "failed to equate"); NoSolution }) } @@ -743,7 +743,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { /// Normally we emit a nested `AliasRelate` when equating an inference /// variable and an alias. This causes us to instead constrain the inference /// variable to the alias without emitting a nested alias relate goals. - #[instrument(level = "debug", skip(self, param_env), ret)] + #[instrument(level = "trace", skip(self, param_env), ret)] pub(super) fn relate_rigid_alias_non_alias( &mut self, param_env: ty::ParamEnv<'tcx>, @@ -781,7 +781,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { /// This sohuld only be used when we're either instantiating a previously /// unconstrained "return value" or when we're sure that all aliases in /// the types are rigid. - #[instrument(level = "debug", skip(self, param_env), ret)] + #[instrument(level = "trace", skip(self, param_env), ret)] pub(super) fn eq_structurally_relating_aliases>( &mut self, param_env: ty::ParamEnv<'tcx>, @@ -798,7 +798,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { Ok(()) } - #[instrument(level = "debug", skip(self, param_env), ret)] + #[instrument(level = "trace", skip(self, param_env), ret)] pub(super) fn sub>( &mut self, param_env: ty::ParamEnv<'tcx>, @@ -813,12 +813,12 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { self.add_goals(GoalSource::Misc, obligations.into_iter().map(|o| o.into())); }) .map_err(|e| { - debug!(?e, "failed to subtype"); + trace!(?e, "failed to subtype"); NoSolution }) } - #[instrument(level = "debug", skip(self, param_env), ret)] + #[instrument(level = "trace", skip(self, param_env), ret)] pub(super) fn relate>( &mut self, param_env: ty::ParamEnv<'tcx>, @@ -834,7 +834,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { self.add_goals(GoalSource::Misc, obligations.into_iter().map(|o| o.into())); }) .map_err(|e| { - debug!(?e, "failed to relate"); + trace!(?e, "failed to relate"); NoSolution }) } @@ -859,7 +859,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { obligations.into_iter().map(|o| o.into()).collect() }) .map_err(|e| { - debug!(?e, "failed to equate"); + trace!(?e, "failed to equate"); NoSolution }) } diff --git a/compiler/rustc_trait_selection/src/solve/fulfill.rs b/compiler/rustc_trait_selection/src/solve/fulfill.rs index 4cc041fca8cea..586d2095d9c0e 100644 --- a/compiler/rustc_trait_selection/src/solve/fulfill.rs +++ b/compiler/rustc_trait_selection/src/solve/fulfill.rs @@ -119,7 +119,7 @@ impl<'tcx> FulfillmentCtxt<'tcx> { } impl<'tcx> TraitEngine<'tcx> for FulfillmentCtxt<'tcx> { - #[instrument(level = "debug", skip(self, infcx))] + #[instrument(level = "trace", skip(self, infcx))] fn register_predicate_obligation( &mut self, infcx: &InferCtxt<'tcx>, diff --git a/compiler/rustc_trait_selection/src/solve/mod.rs b/compiler/rustc_trait_selection/src/solve/mod.rs index b2b076e28e648..80ae4b6022dcf 100644 --- a/compiler/rustc_trait_selection/src/solve/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/mod.rs @@ -82,7 +82,7 @@ impl<'tcx> Canonical<'tcx, Response<'tcx>> { } impl<'a, 'tcx> EvalCtxt<'a, 'tcx> { - #[instrument(level = "debug", skip(self))] + #[instrument(level = "trace", skip(self))] fn compute_type_outlives_goal( &mut self, goal: Goal<'tcx, TypeOutlivesPredicate<'tcx>>, @@ -92,7 +92,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> { self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) } - #[instrument(level = "debug", skip(self))] + #[instrument(level = "trace", skip(self))] fn compute_region_outlives_goal( &mut self, goal: Goal<'tcx, RegionOutlivesPredicate<'tcx>>, @@ -102,7 +102,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> { self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) } - #[instrument(level = "debug", skip(self))] + #[instrument(level = "trace", skip(self))] fn compute_coerce_goal( &mut self, goal: Goal<'tcx, CoercePredicate<'tcx>>, @@ -117,7 +117,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> { }) } - #[instrument(level = "debug", skip(self))] + #[instrument(level = "trace", skip(self))] fn compute_subtype_goal( &mut self, goal: Goal<'tcx, SubtypePredicate<'tcx>>, @@ -138,7 +138,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> { } } - #[instrument(level = "debug", skip(self))] + #[instrument(level = "trace", skip(self))] fn compute_well_formed_goal( &mut self, goal: Goal<'tcx, ty::GenericArg<'tcx>>, @@ -152,7 +152,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> { } } - #[instrument(level = "debug", skip(self))] + #[instrument(level = "trace", skip(self))] fn compute_const_evaluatable_goal( &mut self, Goal { param_env, predicate: ct }: Goal<'tcx, ty::Const<'tcx>>, @@ -189,7 +189,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> { } } - #[instrument(level = "debug", skip(self), ret)] + #[instrument(level = "trace", skip(self), ret)] fn compute_const_arg_has_type_goal( &mut self, goal: Goal<'tcx, (ty::Const<'tcx>, Ty<'tcx>)>, @@ -201,7 +201,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> { } impl<'tcx> EvalCtxt<'_, 'tcx> { - #[instrument(level = "debug", skip(self, goals))] + #[instrument(level = "trace", skip(self, goals))] fn add_goals( &mut self, source: GoalSource, @@ -215,7 +215,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { /// Try to merge multiple possible ways to prove a goal, if that is not possible returns `None`. /// /// In this case we tend to flounder and return ambiguity by calling `[EvalCtxt::flounder]`. - #[instrument(level = "debug", skip(self), ret)] + #[instrument(level = "trace", skip(self), ret)] fn try_merge_responses( &mut self, responses: &[CanonicalResponse<'tcx>], @@ -241,7 +241,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { } /// If we fail to merge responses we flounder and return overflow or ambiguity. - #[instrument(level = "debug", skip(self), ret)] + #[instrument(level = "trace", skip(self), ret)] fn flounder(&mut self, responses: &[CanonicalResponse<'tcx>]) -> QueryResult<'tcx> { if responses.is_empty() { return Err(NoSolution); @@ -263,7 +263,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { /// This function is necessary in nearly all cases before matching on a type. /// Not doing so is likely to be incomplete and therefore unsound during /// coherence. - #[instrument(level = "debug", skip(self, param_env), ret)] + #[instrument(level = "trace", skip(self, param_env), ret)] fn structurally_normalize_ty( &mut self, param_env: ty::ParamEnv<'tcx>, diff --git a/compiler/rustc_trait_selection/src/solve/normalize.rs b/compiler/rustc_trait_selection/src/solve/normalize.rs index cd1add9e0fa0d..1ac1827bf1c33 100644 --- a/compiler/rustc_trait_selection/src/solve/normalize.rs +++ b/compiler/rustc_trait_selection/src/solve/normalize.rs @@ -162,7 +162,7 @@ impl<'tcx> FallibleTypeFolder> for NormalizationFolder<'_, 'tcx> { Ok(t) } - #[instrument(level = "debug", skip(self), ret)] + #[instrument(level = "trace", skip(self), ret)] fn try_fold_ty(&mut self, ty: Ty<'tcx>) -> Result, Self::Error> { let infcx = self.at.infcx; debug_assert_eq!(ty, infcx.shallow_resolve(ty)); @@ -189,7 +189,7 @@ impl<'tcx> FallibleTypeFolder> for NormalizationFolder<'_, 'tcx> { } } - #[instrument(level = "debug", skip(self), ret)] + #[instrument(level = "trace", skip(self), ret)] fn try_fold_const(&mut self, ct: ty::Const<'tcx>) -> Result, Self::Error> { let infcx = self.at.infcx; debug_assert_eq!(ct, infcx.shallow_resolve_const(ct)); diff --git a/compiler/rustc_trait_selection/src/solve/normalizes_to/anon_const.rs b/compiler/rustc_trait_selection/src/solve/normalizes_to/anon_const.rs index 37d5645289398..94e078f56159e 100644 --- a/compiler/rustc_trait_selection/src/solve/normalizes_to/anon_const.rs +++ b/compiler/rustc_trait_selection/src/solve/normalizes_to/anon_const.rs @@ -3,7 +3,7 @@ use rustc_middle::traits::solve::{Certainty, Goal, QueryResult}; use rustc_middle::ty; impl<'tcx> EvalCtxt<'_, 'tcx> { - #[instrument(level = "debug", skip(self), ret)] + #[instrument(level = "trace", skip(self), ret)] pub(super) fn normalize_anon_const( &mut self, goal: Goal<'tcx, ty::NormalizesTo<'tcx>>, diff --git a/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs b/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs index 454c7a5f00f80..8d5c5d2a06380 100644 --- a/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs @@ -25,7 +25,7 @@ mod opaque_types; mod weak_types; impl<'tcx> EvalCtxt<'_, 'tcx> { - #[instrument(level = "debug", skip(self), ret)] + #[instrument(level = "trace", skip(self), ret)] pub(super) fn compute_normalizes_to_goal( &mut self, goal: Goal<'tcx, NormalizesTo<'tcx>>, @@ -59,7 +59,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { /// Normalize the given alias by at least one step. If the alias is rigid, this /// returns `NoSolution`. - #[instrument(level = "debug", skip(self), ret)] + #[instrument(level = "trace", skip(self), ret)] fn normalize_at_least_one_step( &mut self, goal: Goal<'tcx, NormalizesTo<'tcx>>, @@ -897,7 +897,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> { /// /// FIXME: We should merge these 3 implementations as it's likely that they otherwise /// diverge. -#[instrument(level = "debug", skip(ecx, param_env), ret)] +#[instrument(level = "trace", skip(ecx, param_env), ret)] fn fetch_eligible_assoc_item_def<'tcx>( ecx: &EvalCtxt<'_, 'tcx>, param_env: ty::ParamEnv<'tcx>, @@ -920,7 +920,7 @@ fn fetch_eligible_assoc_item_def<'tcx>( let poly_trait_ref = ecx.resolve_vars_if_possible(goal_trait_ref); !poly_trait_ref.still_further_specializable() } else { - debug!(?node_item.item.def_id, "not eligible due to default"); + trace!(?node_item.item.def_id, "not eligible due to default"); false } }; diff --git a/compiler/rustc_trait_selection/src/solve/project_goals.rs b/compiler/rustc_trait_selection/src/solve/project_goals.rs index 30ae385a8a0b7..74b3db71e78f2 100644 --- a/compiler/rustc_trait_selection/src/solve/project_goals.rs +++ b/compiler/rustc_trait_selection/src/solve/project_goals.rs @@ -5,7 +5,7 @@ use rustc_middle::traits::solve::{Certainty, Goal, QueryResult}; use rustc_middle::ty::{self, ProjectionPredicate}; impl<'tcx> EvalCtxt<'_, 'tcx> { - #[instrument(level = "debug", skip(self), ret)] + #[instrument(level = "trace", skip(self), ret)] pub(super) fn compute_projection_goal( &mut self, goal: Goal<'tcx, ProjectionPredicate<'tcx>>, diff --git a/compiler/rustc_trait_selection/src/solve/search_graph.rs b/compiler/rustc_trait_selection/src/solve/search_graph.rs index a48b2f2478b0d..468476d81d75f 100644 --- a/compiler/rustc_trait_selection/src/solve/search_graph.rs +++ b/compiler/rustc_trait_selection/src/solve/search_graph.rs @@ -130,7 +130,7 @@ impl<'tcx> SearchGraph<'tcx> { } /// Update the stack and reached depths on cache hits. - #[instrument(level = "debug", skip(self))] + #[instrument(level = "trace", skip(self))] fn on_cache_hit(&mut self, additional_depth: usize, encountered_overflow: bool) { let reached_depth = self.stack.next_index().plus(additional_depth); if let Some(last) = self.stack.raw.last_mut() { @@ -328,7 +328,7 @@ impl<'tcx> SearchGraph<'tcx> { ); return entry.result; } else if let Some(stack_depth) = cache_entry.stack_depth { - debug!("encountered cycle with depth {stack_depth:?}"); + trace!("encountered cycle with depth {stack_depth:?}"); // We have a nested goal which directly relies on a goal deeper in the stack. // // We start by tagging all cycle participants, as that's necessary for caching. @@ -436,7 +436,7 @@ impl<'tcx> SearchGraph<'tcx> { } } - debug!("canonical cycle overflow"); + trace!("canonical cycle overflow"); let current_entry = self.pop_stack(); debug_assert!(current_entry.has_been_used.is_empty()); let result = Self::response_no_constraints(tcx, input, Certainty::overflow(false)); diff --git a/compiler/rustc_trait_selection/src/solve/trait_goals.rs b/compiler/rustc_trait_selection/src/solve/trait_goals.rs index 083cc0aa3c219..2f1b7d60df310 100644 --- a/compiler/rustc_trait_selection/src/solve/trait_goals.rs +++ b/compiler/rustc_trait_selection/src/solve/trait_goals.rs @@ -1130,7 +1130,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { }, ); if let Some(def_id) = disqualifying_impl { - debug!(?def_id, ?goal, "disqualified auto-trait implementation"); + trace!(?def_id, ?goal, "disqualified auto-trait implementation"); // No need to actually consider the candidate here, // since we do that in `consider_impl_candidate`. return Some(Err(NoSolution)); @@ -1171,7 +1171,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { }) } - #[instrument(level = "debug", skip(self))] + #[instrument(level = "trace", skip(self))] pub(super) fn compute_trait_goal( &mut self, goal: Goal<'tcx, TraitPredicate<'tcx>>, From c66328f9adf06c849d373b676ed59536e51f3290 Mon Sep 17 00:00:00 2001 From: lcnr Date: Sun, 12 May 2024 03:46:24 +0000 Subject: [PATCH 112/179] structurally important functions to `debug` --- .../rustc_trait_selection/src/solve/assembly/mod.rs | 10 +++++----- .../rustc_trait_selection/src/solve/eval_ctxt/mod.rs | 6 +++--- .../rustc_trait_selection/src/solve/eval_ctxt/probe.rs | 1 + .../rustc_trait_selection/src/solve/search_graph.rs | 6 ++++-- 4 files changed, 13 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_trait_selection/src/solve/assembly/mod.rs b/compiler/rustc_trait_selection/src/solve/assembly/mod.rs index ebd633b236712..938bd80b9eb0a 100644 --- a/compiler/rustc_trait_selection/src/solve/assembly/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/assembly/mod.rs @@ -282,7 +282,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { }; if normalized_self_ty.is_ty_var() { - trace!("self type has been normalized to infer"); + debug!("self type has been normalized to infer"); return self.forced_ambiguity(MaybeCause::Ambiguity).into_iter().collect(); } @@ -785,7 +785,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { // FIXME(@lcnr): The current structure here makes me unhappy and feels ugly. idk how // to improve this however. However, this should make it fairly straightforward to refine // the filtering going forward, so it seems alright-ish for now. - #[instrument(level = "trace", skip(self, goal))] + #[instrument(level = "debug", skip(self, goal))] fn discard_impls_shadowed_by_env>( &mut self, goal: Goal<'tcx, G>, @@ -814,7 +814,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { Certainty::Yes => { candidates.retain(|c| match c.source { CandidateSource::Impl(_) | CandidateSource::BuiltinImpl(_) => { - trace!(?c, "discard impl candidate"); + debug!(?c, "discard impl candidate"); false } CandidateSource::ParamEnv(_) | CandidateSource::AliasBound => true, @@ -825,7 +825,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { // to be ambig and wait for inference constraints. See // tests/ui/traits/next-solver/env-shadows-impls/ambig-env-no-shadow.rs Certainty::Maybe(cause) => { - trace!(?cause, "force ambiguity"); + debug!(?cause, "force ambiguity"); *candidates = self.forced_ambiguity(cause).into_iter().collect(); } } @@ -836,7 +836,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { /// If there are multiple ways to prove a trait or projection goal, we have /// to somehow try to merge the candidates into one. If that fails, we return /// ambiguity. - #[instrument(level = "trace", skip(self), ret)] + #[instrument(level = "debug", skip(self), ret)] pub(super) fn merge_candidates( &mut self, candidates: Vec>, diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs index 1faf52232b6c5..8614c17cabf1d 100644 --- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs @@ -137,7 +137,7 @@ impl<'tcx> InferCtxt<'tcx> { /// /// Using this while inside of the solver is wrong as it uses a new /// search graph which would break cycle detection. - #[instrument(level = "trace", skip(self))] + #[instrument(level = "debug", skip(self))] fn evaluate_root_goal( &self, goal: Goal<'tcx, ty::Predicate<'tcx>>, @@ -276,7 +276,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> { /// Instead of calling this function directly, use either [EvalCtxt::evaluate_goal] /// if you're inside of the solver or [InferCtxtEvalExt::evaluate_root_goal] if you're /// outside of it. - #[instrument(level = "trace", skip(tcx, search_graph, goal_evaluation), ret)] + #[instrument(level = "debug", skip(tcx, search_graph, goal_evaluation), ret)] fn evaluate_canonical_goal( tcx: TyCtxt<'tcx>, search_graph: &'a mut search_graph::SearchGraph<'tcx>, @@ -464,7 +464,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> { self.nested_goals.normalizes_to_goals.push(goal); } - #[instrument(level = "trace", skip(self))] + #[instrument(level = "debug", skip(self))] pub(super) fn add_goal(&mut self, source: GoalSource, goal: Goal<'tcx, ty::Predicate<'tcx>>) { self.inspect.add_goal(self.infcx, self.max_input_universe, source, goal); self.nested_goals.goals.push((source, goal)); diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/probe.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/probe.rs index ee23f49939b7c..47109c8ad5d2f 100644 --- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/probe.rs +++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/probe.rs @@ -58,6 +58,7 @@ impl<'tcx, F> TraitProbeCtxt<'_, '_, 'tcx, F> where F: FnOnce(&QueryResult<'tcx>) -> inspect::ProbeKind<'tcx>, { + #[instrument(level = "debug", skip_all, fields(source = ?self.source))] pub(in crate::solve) fn enter( self, f: impl FnOnce(&mut EvalCtxt<'_, 'tcx>) -> QueryResult<'tcx>, diff --git a/compiler/rustc_trait_selection/src/solve/search_graph.rs b/compiler/rustc_trait_selection/src/solve/search_graph.rs index 468476d81d75f..60362aa01da8b 100644 --- a/compiler/rustc_trait_selection/src/solve/search_graph.rs +++ b/compiler/rustc_trait_selection/src/solve/search_graph.rs @@ -296,6 +296,7 @@ impl<'tcx> SearchGraph<'tcx> { } self.on_cache_hit(reached_depth, encountered_overflow); + debug!("global cache hit"); return result; } @@ -315,6 +316,7 @@ impl<'tcx> SearchGraph<'tcx> { .filter(|p| !Self::stack_coinductive_from(tcx, &self.stack, p.head)) }) { + debug!("provisional cache hit"); // We have a nested goal which is already in the provisional cache, use // its result. We do not provide any usage kind as that should have been // already set correctly while computing the cache entry. @@ -328,7 +330,7 @@ impl<'tcx> SearchGraph<'tcx> { ); return entry.result; } else if let Some(stack_depth) = cache_entry.stack_depth { - trace!("encountered cycle with depth {stack_depth:?}"); + debug!("encountered cycle with depth {stack_depth:?}"); // We have a nested goal which directly relies on a goal deeper in the stack. // // We start by tagging all cycle participants, as that's necessary for caching. @@ -436,7 +438,7 @@ impl<'tcx> SearchGraph<'tcx> { } } - trace!("canonical cycle overflow"); + debug!("canonical cycle overflow"); let current_entry = self.pop_stack(); debug_assert!(current_entry.has_been_used.is_empty()); let result = Self::response_no_constraints(tcx, input, Certainty::overflow(false)); From dcab06d7d206a1e061233c0e251deb06ef0c1300 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Fri, 10 May 2024 22:00:57 -0700 Subject: [PATCH 113/179] Unify `Rvalue::Aggregate` paths in cg_ssa --- compiler/rustc_abi/src/lib.rs | 2 +- compiler/rustc_codegen_ssa/src/mir/operand.rs | 13 +++++++ compiler/rustc_codegen_ssa/src/mir/rvalue.rs | 37 ++++++++----------- tests/codegen/mir-aggregate-no-alloca.rs | 2 +- 4 files changed, 31 insertions(+), 23 deletions(-) diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs index a8d019c980496..ea805c5ad5db7 100644 --- a/compiler/rustc_abi/src/lib.rs +++ b/compiler/rustc_abi/src/lib.rs @@ -1255,7 +1255,7 @@ impl FieldsShape { /// Gets source indices of the fields by increasing offsets. #[inline] - pub fn index_by_increasing_offset(&self) -> impl Iterator + '_ { + pub fn index_by_increasing_offset(&self) -> impl ExactSizeIterator + '_ { let mut inverse_small = [0u8; 64]; let mut inverse_big = IndexVec::new(); let use_small = self.count() <= inverse_small.len(); diff --git a/compiler/rustc_codegen_ssa/src/mir/operand.rs b/compiler/rustc_codegen_ssa/src/mir/operand.rs index e1c584e8ed5f1..32fd9b657f99c 100644 --- a/compiler/rustc_codegen_ssa/src/mir/operand.rs +++ b/compiler/rustc_codegen_ssa/src/mir/operand.rs @@ -110,6 +110,19 @@ impl OperandValue { let (llval, llextra) = self.pointer_parts(); PlaceValue { llval, llextra, align } } + + pub(crate) fn is_expected_variant_for_type<'tcx, Cx: LayoutTypeMethods<'tcx>>( + &self, + cx: &Cx, + ty: TyAndLayout<'tcx>, + ) -> bool { + match self { + OperandValue::ZeroSized => ty.is_zst(), + OperandValue::Immediate(_) => cx.is_backend_immediate(ty), + OperandValue::Pair(_, _) => cx.is_backend_scalar_pair(ty), + OperandValue::Ref(_) => cx.is_backend_ref(ty), + } + } } /// An `OperandRef` is an "SSA" reference to a Rust value, along with diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs index e47a8198736f2..b764ea6a4c6e2 100644 --- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs +++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs @@ -18,6 +18,7 @@ use rustc_span::{Span, DUMMY_SP}; use rustc_target::abi::{self, FieldIdx, FIRST_VARIANT}; use arrayvec::ArrayVec; +use either::Either; impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { #[instrument(level = "trace", skip(self, bx))] @@ -696,35 +697,25 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { OperandRef { val: OperandValue::Immediate(static_), layout } } mir::Rvalue::Use(ref operand) => self.codegen_operand(bx, operand), - mir::Rvalue::Aggregate(box mir::AggregateKind::RawPtr(..), ref fields) => { - let ty = rvalue.ty(self.mir, self.cx.tcx()); - let layout = self.cx.layout_of(self.monomorphize(ty)); - let [data, meta] = &*fields.raw else { - bug!("RawPtr fields: {fields:?}"); - }; - let data = self.codegen_operand(bx, data); - let meta = self.codegen_operand(bx, meta); - match (data.val, meta.val) { - (p @ OperandValue::Immediate(_), OperandValue::ZeroSized) => { - OperandRef { val: p, layout } - } - (OperandValue::Immediate(p), OperandValue::Immediate(m)) => { - OperandRef { val: OperandValue::Pair(p, m), layout } - } - _ => bug!("RawPtr operands {data:?} {meta:?}"), - } - } mir::Rvalue::Repeat(..) => bug!("{rvalue:?} in codegen_rvalue_operand"), - mir::Rvalue::Aggregate(_, ref fields) => { + mir::Rvalue::Aggregate(ref kind, ref fields) => { let ty = rvalue.ty(self.mir, self.cx.tcx()); let ty = self.monomorphize(ty); let layout = self.cx.layout_of(ty); + let field_indices = if let mir::AggregateKind::RawPtr(..) = **kind { + // `index_by_increasing_offset` gives an empty iterator for primitives + Either::Left([0_usize, 1_usize].iter().copied()) + } else { + Either::Right(layout.fields.index_by_increasing_offset()) + }; + debug_assert_eq!(field_indices.len(), fields.len()); + // `rvalue_creates_operand` has arranged that we only get here if // we can build the aggregate immediate from the field immediates. let mut inputs = ArrayVec::::new(); let mut input_scalars = ArrayVec::::new(); - for field_idx in layout.fields.index_by_increasing_offset() { + for field_idx in field_indices { let field_idx = FieldIdx::from_usize(field_idx); let op = self.codegen_operand(bx, &fields[field_idx]); let values = op.val.immediates_or_place().left_or_else(|p| { @@ -748,6 +739,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { ); let val = OperandValue::from_immediates(inputs); + debug_assert!( + val.is_expected_variant_for_type(self.cx, layout), + "Made wrong variant {val:?} for type {layout:?}", + ); OperandRef { val, layout } } mir::Rvalue::ShallowInitBox(ref operand, content_ty) => { @@ -792,7 +787,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { debug_assert!( if bx.cx().type_has_metadata(ty) { matches!(val, OperandValue::Pair(..)) - } else { + } else { matches!(val, OperandValue::Immediate(..)) }, "Address of place was unexpectedly {val:?} for pointee type {ty:?}", diff --git a/tests/codegen/mir-aggregate-no-alloca.rs b/tests/codegen/mir-aggregate-no-alloca.rs index a7752d714fe39..c0e7e1a05e390 100644 --- a/tests/codegen/mir-aggregate-no-alloca.rs +++ b/tests/codegen/mir-aggregate-no-alloca.rs @@ -55,7 +55,7 @@ pub fn make_cell_of_bool(b: bool) -> std::cell::Cell { std::cell::Cell::new(b) } -// CHECK-LABLE: { i8, i16 } @make_cell_of_bool_and_short(i1 noundef zeroext %b, i16 noundef %s) +// CHECK-LABEL: { i8, i16 } @make_cell_of_bool_and_short(i1 noundef zeroext %b, i16 noundef %s) #[no_mangle] pub fn make_cell_of_bool_and_short(b: bool, s: u16) -> std::cell::Cell<(bool, u16)> { // CHECK-NOT: alloca From 99213ae164e42966f8dd37fe9f64a1e138fdf500 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Sat, 11 May 2024 15:26:49 -0700 Subject: [PATCH 114/179] Make `index_by_increasing_offset` return one item for primitives --- compiler/rustc_abi/src/lib.rs | 7 ++++++- compiler/rustc_codegen_ssa/src/mir/rvalue.rs | 13 ++----------- 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs index ea805c5ad5db7..9f2788c87c323 100644 --- a/compiler/rustc_abi/src/lib.rs +++ b/compiler/rustc_abi/src/lib.rs @@ -1271,7 +1271,12 @@ impl FieldsShape { } } - (0..self.count()).map(move |i| match *self { + // Primitives don't really have fields in the way that structs do, + // but having this return an empty iterator for them is unhelpful + // since that makes them look kinda like ZSTs, which they're not. + let pseudofield_count = if let FieldsShape::Primitive = self { 1 } else { self.count() }; + + (0..pseudofield_count).map(move |i| match *self { FieldsShape::Primitive | FieldsShape::Union(_) | FieldsShape::Array { .. } => i, FieldsShape::Arbitrary { .. } => { if use_small { diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs index b764ea6a4c6e2..936ed41a294b5 100644 --- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs +++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs @@ -18,7 +18,6 @@ use rustc_span::{Span, DUMMY_SP}; use rustc_target::abi::{self, FieldIdx, FIRST_VARIANT}; use arrayvec::ArrayVec; -use either::Either; impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { #[instrument(level = "trace", skip(self, bx))] @@ -698,24 +697,16 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } mir::Rvalue::Use(ref operand) => self.codegen_operand(bx, operand), mir::Rvalue::Repeat(..) => bug!("{rvalue:?} in codegen_rvalue_operand"), - mir::Rvalue::Aggregate(ref kind, ref fields) => { + mir::Rvalue::Aggregate(_, ref fields) => { let ty = rvalue.ty(self.mir, self.cx.tcx()); let ty = self.monomorphize(ty); let layout = self.cx.layout_of(ty); - let field_indices = if let mir::AggregateKind::RawPtr(..) = **kind { - // `index_by_increasing_offset` gives an empty iterator for primitives - Either::Left([0_usize, 1_usize].iter().copied()) - } else { - Either::Right(layout.fields.index_by_increasing_offset()) - }; - debug_assert_eq!(field_indices.len(), fields.len()); - // `rvalue_creates_operand` has arranged that we only get here if // we can build the aggregate immediate from the field immediates. let mut inputs = ArrayVec::::new(); let mut input_scalars = ArrayVec::::new(); - for field_idx in field_indices { + for field_idx in layout.fields.index_by_increasing_offset() { let field_idx = FieldIdx::from_usize(field_idx); let op = self.codegen_operand(bx, &fields[field_idx]); let values = op.val.immediates_or_place().left_or_else(|p| { From 48506150f4b8f8f095d5befee0db08724799b936 Mon Sep 17 00:00:00 2001 From: ickk Date: Sun, 12 May 2024 17:18:44 +1000 Subject: [PATCH 115/179] fix hidden title in command-line-arguments docs --- src/doc/rustdoc/src/command-line-arguments.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustdoc/src/command-line-arguments.md b/src/doc/rustdoc/src/command-line-arguments.md index 822f341b370af..69fb7e3313fe9 100644 --- a/src/doc/rustdoc/src/command-line-arguments.md +++ b/src/doc/rustdoc/src/command-line-arguments.md @@ -273,7 +273,7 @@ will be added. When rendering Rust files, this flag is ignored. -## `--html-in-header`: include more HTML in +## `--html-in-header`: include more HTML in `` Using this flag looks like this: From 114e25761ff1cf1ee75aa85cabc197a5095cf484 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 11 May 2024 20:27:50 +0200 Subject: [PATCH 116/179] Migrate `rustdoc-scrape-examples-ordering` to `rmake` --- src/tools/run-make-support/src/rustc.rs | 6 +- src/tools/run-make-support/src/rustdoc.rs | 5 +- .../tidy/src/allowed_run_make_makefiles.txt | 1 - .../rustdoc-scrape-examples-ordering/Makefile | 5 -- .../rustdoc-scrape-examples-ordering/rmake.rs | 55 +++++++++++++++++++ 5 files changed, 61 insertions(+), 11 deletions(-) delete mode 100644 tests/run-make/rustdoc-scrape-examples-ordering/Makefile create mode 100644 tests/run-make/rustdoc-scrape-examples-ordering/rmake.rs diff --git a/src/tools/run-make-support/src/rustc.rs b/src/tools/run-make-support/src/rustc.rs index 852353575a983..1671a01860ae4 100644 --- a/src/tools/run-make-support/src/rustc.rs +++ b/src/tools/run-make-support/src/rustc.rs @@ -1,5 +1,5 @@ use std::env; -use std::ffi::OsString; +use std::ffi::{OsStr, OsString}; use std::io::Write; use std::path::Path; use std::process::{Command, Output, Stdio}; @@ -177,9 +177,9 @@ impl Rustc { } /// Specify the crate name. - pub fn crate_name(&mut self, name: &str) -> &mut Self { + pub fn crate_name>(&mut self, name: S) -> &mut Self { self.cmd.arg("--crate-name"); - self.cmd.arg(name); + self.cmd.arg(name.as_ref()); self } diff --git a/src/tools/run-make-support/src/rustdoc.rs b/src/tools/run-make-support/src/rustdoc.rs index 6a65d9616fcc5..75ca1fc29747f 100644 --- a/src/tools/run-make-support/src/rustdoc.rs +++ b/src/tools/run-make-support/src/rustdoc.rs @@ -1,4 +1,5 @@ use std::env; +use std::ffi::OsStr; use std::io::Write; use std::path::Path; use std::process::{Command, Output, Stdio}; @@ -130,9 +131,9 @@ impl Rustdoc { } /// Specify the crate name. - pub fn crate_name(&mut self, name: &str) -> &mut Self { + pub fn crate_name>(&mut self, name: S) -> &mut Self { self.cmd.arg("--crate-name"); - self.cmd.arg(name); + self.cmd.arg(name.as_ref()); self } diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index e87950b36d9df..008fa5ec707a6 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -248,7 +248,6 @@ run-make/rustdoc-io-error/Makefile run-make/rustdoc-scrape-examples-invalid-expr/Makefile run-make/rustdoc-scrape-examples-macros/Makefile run-make/rustdoc-scrape-examples-multiple/Makefile -run-make/rustdoc-scrape-examples-ordering/Makefile run-make/rustdoc-scrape-examples-remap/Makefile run-make/rustdoc-scrape-examples-test/Makefile run-make/rustdoc-scrape-examples-whitespace/Makefile diff --git a/tests/run-make/rustdoc-scrape-examples-ordering/Makefile b/tests/run-make/rustdoc-scrape-examples-ordering/Makefile deleted file mode 100644 index bf45b8148c03a..0000000000000 --- a/tests/run-make/rustdoc-scrape-examples-ordering/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -deps := ex1 ex2 - -include ../rustdoc-scrape-examples-multiple/scrape.mk - -all: scrape diff --git a/tests/run-make/rustdoc-scrape-examples-ordering/rmake.rs b/tests/run-make/rustdoc-scrape-examples-ordering/rmake.rs new file mode 100644 index 0000000000000..edcf3406d47f8 --- /dev/null +++ b/tests/run-make/rustdoc-scrape-examples-ordering/rmake.rs @@ -0,0 +1,55 @@ +use run_make_support::{python_command, rustc, rustdoc, source_path, tmp_dir}; +use std::fs::read_dir; +use std::path::Path; + +fn main() { + let lib_dir = tmp_dir(); + let out_dir = tmp_dir().join("rustdoc"); + let crate_name = "foobar"; + let deps = read_dir("examples") + .unwrap() + .filter_map(|entry| entry.ok().map(|e| e.path())) + .filter(|path| path.is_file() && path.extension().is_some_and(|ext| ext == "rs")) + .collect::>(); + + rustc().input("src/lib.rs").crate_name(crate_name).crate_type("lib").emit("metadata").run(); + + let mut out_deps = Vec::with_capacity(deps.len()); + for dep in deps { + let dep_stem = dep.file_stem().unwrap(); + let out_example = out_dir.join(format!("{}.calls", dep_stem.to_str().unwrap())); + rustdoc() + .input(&dep) + .crate_name(&dep_stem) + .crate_type("bin") + .output(&out_dir) + .extern_(crate_name, lib_dir.join(format!("lib{crate_name}.rmeta"))) + .arg("-Zunstable-options") + .arg("--scrape-examples-output-path") + .arg(&out_example) + .arg("--scrape-examples-target-crate") + .arg(crate_name) + .run(); + out_deps.push(out_example); + } + + let mut rustdoc = rustdoc(); + rustdoc + .input("src/lib.rs") + .output(&out_dir) + .crate_name(crate_name) + .crate_type("lib") + .arg("-Zunstable-options"); + for dep in out_deps { + rustdoc.arg("--with-examples").arg(dep); + } + rustdoc.run(); + + python_command() + .arg(source_path().join("/src/etc/htmldocck.py")) + .arg(out_dir) + .arg("src/lib.rs") + .status() + .unwrap() + .success(); +} From cfc919f5320e9fb59745653dd16e28acdf6ab05e Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sun, 12 May 2024 12:47:09 +0000 Subject: [PATCH 117/179] Use cargo in y.sh This will allow adding dependencies to the build system in the future. --- .gitignore | 4 ---- build_system/Cargo.toml | 3 +++ build_system/main.rs | 8 +++++--- y.cmd | 4 +--- y.ps1 | 7 +------ y.sh | 3 +-- 6 files changed, 11 insertions(+), 18 deletions(-) mode change 100644 => 100755 y.ps1 diff --git a/.gitignore b/.gitignore index 7915fa138f8fc..5a38f2acb0e2f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,4 @@ # Build artifacts during normal use -/y.bin -/y.bin.dSYM -/y.exe -/y.pdb /download /build /dist diff --git a/build_system/Cargo.toml b/build_system/Cargo.toml index f47b9bc554041..feed2b6eafe82 100644 --- a/build_system/Cargo.toml +++ b/build_system/Cargo.toml @@ -11,3 +11,6 @@ path = "main.rs" unstable-features = [] # for rust-analyzer # Do not add any dependencies + +[profile.dev] +debug = 1 diff --git a/build_system/main.rs b/build_system/main.rs index cdd2bae03f8f1..7dbf608f991e4 100644 --- a/build_system/main.rs +++ b/build_system/main.rs @@ -147,9 +147,11 @@ fn main() { let rustup_toolchain_name = match (env::var("CARGO"), env::var("RUSTC"), env::var("RUSTDOC")) { (Ok(_), Ok(_), Ok(_)) => None, - (Err(_), Err(_), Err(_)) => Some(rustc_info::get_toolchain_name()), - _ => { - eprintln!("All of CARGO, RUSTC and RUSTDOC need to be set or none must be set"); + (_, Err(_), Err(_)) => Some(rustc_info::get_toolchain_name()), + vars => { + eprintln!( + "If RUSTC or RUSTDOC is set, both need to be set and in addition CARGO needs to be set: {vars:?}" + ); process::exit(1); } }; diff --git a/y.cmd b/y.cmd index e9b688645a4d8..42106849163b5 100644 --- a/y.cmd +++ b/y.cmd @@ -1,8 +1,6 @@ @echo off echo [BUILD] build system >&2 -mkdir build 2>nul -rustc build_system/main.rs -o build\y.exe -Cdebuginfo=1 --edition 2021 || goto :error -build\y.exe %* || goto :error +cargo run --manifest-path build_system/Cargo.toml -- %* || goto :error goto :EOF :error diff --git a/y.ps1 b/y.ps1 old mode 100644 new mode 100755 index 02ef0fcbd50f1..821f0ec6e5777 --- a/y.ps1 +++ b/y.ps1 @@ -1,12 +1,7 @@ $ErrorActionPreference = "Stop" $host.ui.WriteErrorLine("[BUILD] build system") -New-Item -ItemType Directory -Force -Path build | Out-Null -& rustc build_system/main.rs -o build\y.exe -Cdebuginfo=1 --edition 2021 -if ($LASTEXITCODE -ne 0) { - exit $LASTEXITCODE -} -& build\y.exe $args +& cargo run --manifest-path build_system/Cargo.toml -- $args if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } diff --git a/y.sh b/y.sh index bc925a23e2a88..b9152d2cc6de0 100755 --- a/y.sh +++ b/y.sh @@ -2,5 +2,4 @@ set -e echo "[BUILD] build system" 1>&2 -rustc build_system/main.rs -o y.bin -Cdebuginfo=1 --edition 2021 -exec ./y.bin "$@" +exec cargo run --manifest-path build_system/Cargo.toml -- "$@" From 6db27529ddbb6d94e0c990e527aa8341c3d85a79 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sun, 12 May 2024 12:58:30 +0000 Subject: [PATCH 118/179] Significantly reduce check cfg warnings --- build_system/build_sysroot.rs | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/build_system/build_sysroot.rs b/build_system/build_sysroot.rs index 10c3f9cfa2ce3..7791df1d53fd2 100644 --- a/build_system/build_sysroot.rs +++ b/build_system/build_sysroot.rs @@ -267,6 +267,10 @@ fn build_clif_sysroot_for_triple( prefix.to_str().unwrap() )); } + rustflags.push("-Zunstable-options".to_owned()); + for (name, values) in EXTRA_CHECK_CFGS { + rustflags.push(check_cfg_arg(name, *values)); + } compiler.rustflags.extend(rustflags); let mut build_cmd = STANDARD_LIBRARY.build(&compiler, dirs); if channel == "release" { @@ -326,3 +330,34 @@ fn build_rtstartup(dirs: &Dirs, compiler: &Compiler) -> Option { Some(target_libs) } + +// Copied from https://github.com/rust-lang/rust/blob/4fd98a4b1b100f5329c6efae18031791f64372d2/src/bootstrap/src/utils/helpers.rs#L569-L585 +/// Create a `--check-cfg` argument invocation for a given name +/// and it's values. +fn check_cfg_arg(name: &str, values: Option<&[&str]>) -> String { + // Creating a string of the values by concatenating each value: + // ',values("tvos","watchos")' or '' (nothing) when there are no values. + let next = match values { + Some(values) => { + let mut tmp = values.iter().flat_map(|val| [",", "\"", val, "\""]).collect::(); + + tmp.insert_str(1, "values("); + tmp.push(')'); + tmp + } + None => "".to_string(), + }; + format!("--check-cfg=cfg({name}{next})") +} + +const EXTRA_CHECK_CFGS: &[(&str, Option<&[&str]>)] = &[ + ("bootstrap", None), + ("stdarch_intel_sde", None), + ("no_fp_fmt_parse", None), + ("no_global_oom_handling", None), + ("no_rc", None), + ("no_sync", None), + ("netbsd10", None), + ("backtrace_in_libstd", None), + ("target_arch", Some(&["xtensa"])), +]; From 7d565dfa0fa40991df9e3567f991284b4912ab0b Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 12 May 2024 15:44:17 +0200 Subject: [PATCH 119/179] Preparing for merge from rustc --- src/tools/miri/rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version index 3636c856d0b55..603417b77eeab 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -ef15976387ad9c1cdceaabf469e0cf35f5852f6d +b71fa82d786ae1b5866510f1b3a7e5b7e1890e4c From 9d92a7f35524ad9f55f519da970737cce2613e9f Mon Sep 17 00:00:00 2001 From: Jules Bertholet Date: Thu, 2 May 2024 19:55:03 -0400 Subject: [PATCH 120/179] Match ergonomics 2024: migration lint Unfortunately, we can't always offer a machine-applicable suggestion when there are subpatterns from macro expansion. Co-Authored-By: Guillaume Boisseau --- Cargo.lock | 1 + compiler/rustc_hir_typeck/messages.ftl | 4 - compiler/rustc_hir_typeck/src/errors.rs | 7 -- compiler/rustc_hir_typeck/src/pat.rs | 49 ++++++---- compiler/rustc_hir_typeck/src/writeback.rs | 17 ++++ compiler/rustc_lint_defs/src/builtin.rs | 38 ++++---- .../rustc_middle/src/ty/typeck_results.rs | 19 ++++ compiler/rustc_mir_build/Cargo.toml | 1 + compiler/rustc_mir_build/messages.ftl | 2 + compiler/rustc_mir_build/src/errors.rs | 27 ++++++ .../rustc_mir_build/src/thir/pattern/mod.rs | 90 +++++++++++++---- .../auxiliary/match_ergonomics_2024_macros.rs | 12 +++ tests/ui/pattern/match_ergonomics_2024.fixed | 57 +++++++++++ tests/ui/pattern/match_ergonomics_2024.rs | 57 +++++++++++ tests/ui/pattern/match_ergonomics_2024.stderr | 97 +++++++++++++++++++ .../mut_preserve_binding_mode_2024_lint.rs | 16 --- ...mut_preserve_binding_mode_2024_lint.stderr | 31 ------ 17 files changed, 409 insertions(+), 116 deletions(-) create mode 100644 tests/ui/pattern/auxiliary/match_ergonomics_2024_macros.rs create mode 100644 tests/ui/pattern/match_ergonomics_2024.fixed create mode 100644 tests/ui/pattern/match_ergonomics_2024.rs create mode 100644 tests/ui/pattern/match_ergonomics_2024.stderr delete mode 100644 tests/ui/pattern/mut_preserve_binding_mode_2024_lint.rs delete mode 100644 tests/ui/pattern/mut_preserve_binding_mode_2024_lint.stderr diff --git a/Cargo.lock b/Cargo.lock index a562bdbafa83a..a17fc000bfb9a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4367,6 +4367,7 @@ dependencies = [ "rustc_hir", "rustc_index", "rustc_infer", + "rustc_lint", "rustc_macros", "rustc_middle", "rustc_pattern_analysis", diff --git a/compiler/rustc_hir_typeck/messages.ftl b/compiler/rustc_hir_typeck/messages.ftl index 0560d0d902a3f..72b95a9603dd0 100644 --- a/compiler/rustc_hir_typeck/messages.ftl +++ b/compiler/rustc_hir_typeck/messages.ftl @@ -46,10 +46,6 @@ hir_typeck_ctor_is_private = tuple struct constructor `{$def}` is private hir_typeck_deref_is_empty = this expression `Deref`s to `{$deref_ty}` which implements `is_empty` -hir_typeck_dereferencing_mut_binding = dereferencing `mut` binding - .label = `mut` dereferences the type of this binding - .help = this will change in edition 2024 - hir_typeck_expected_default_return_type = expected `()` because of default return type hir_typeck_expected_return_type = expected `{$expected}` because of return type diff --git a/compiler/rustc_hir_typeck/src/errors.rs b/compiler/rustc_hir_typeck/src/errors.rs index ba8f246fd8d24..f250b909596ea 100644 --- a/compiler/rustc_hir_typeck/src/errors.rs +++ b/compiler/rustc_hir_typeck/src/errors.rs @@ -651,10 +651,3 @@ pub enum SuggestBoxingForReturnImplTrait { ends: Vec, }, } -#[derive(LintDiagnostic)] -#[diag(hir_typeck_dereferencing_mut_binding)] -pub struct DereferencingMutBinding { - #[label] - #[help] - pub span: Span, -} diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index 259336f438d64..b77f91dd544c1 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -73,21 +73,23 @@ struct TopInfo<'tcx> { /// found type `std::result::Result<_, _>` /// ``` span: Option, + /// The [`HirId`] of the top-level pattern. + hir_id: HirId, } #[derive(Copy, Clone)] struct PatInfo<'tcx, 'a> { binding_mode: ByRef, max_ref_mutbl: MutblCap, - top_info: TopInfo<'tcx>, - decl_origin: Option>, + top_info: &'a TopInfo<'tcx>, + decl_origin: Option>, /// The depth of current pattern current_depth: u32, } impl<'tcx> FnCtxt<'_, 'tcx> { - fn pattern_cause(&self, ti: TopInfo<'tcx>, cause_span: Span) -> ObligationCause<'tcx> { + fn pattern_cause(&self, ti: &TopInfo<'tcx>, cause_span: Span) -> ObligationCause<'tcx> { let code = ObligationCauseCode::Pattern { span: ti.span, root_ty: ti.expected, @@ -101,7 +103,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> { cause_span: Span, expected: Ty<'tcx>, actual: Ty<'tcx>, - ti: TopInfo<'tcx>, + ti: &TopInfo<'tcx>, ) -> Option> { let mut diag = self.demand_eqtype_with_origin(&self.pattern_cause(ti, cause_span), expected, actual)?; @@ -118,7 +120,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> { cause_span: Span, expected: Ty<'tcx>, actual: Ty<'tcx>, - ti: TopInfo<'tcx>, + ti: &TopInfo<'tcx>, ) { if let Some(err) = self.demand_eqtype_pat_diag(cause_span, expected, actual, ti) { err.emit(); @@ -199,11 +201,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { origin_expr: Option<&'tcx hir::Expr<'tcx>>, decl_origin: Option>, ) { - let info = TopInfo { expected, origin_expr, span }; + let info = TopInfo { expected, origin_expr, span, hir_id: pat.hir_id }; let pat_info = PatInfo { binding_mode: ByRef::No, max_ref_mutbl: MutblCap::Mut, - top_info: info, + top_info: &info, decl_origin, current_depth: 0, }; @@ -463,7 +465,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { span: Span, lt: &hir::Expr<'tcx>, expected: Ty<'tcx>, - ti: TopInfo<'tcx>, + ti: &TopInfo<'tcx>, ) -> Ty<'tcx> { // We've already computed the type above (when checking for a non-ref pat), // so avoid computing it again. @@ -533,7 +535,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { lhs: Option<&'tcx hir::Expr<'tcx>>, rhs: Option<&'tcx hir::Expr<'tcx>>, expected: Ty<'tcx>, - ti: TopInfo<'tcx>, + ti: &TopInfo<'tcx>, ) -> Ty<'tcx> { let calc_side = |opt_expr: Option<&'tcx hir::Expr<'tcx>>| match opt_expr { None => None, @@ -671,18 +673,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Determine the binding mode... let bm = match user_bind_annot { + // `mut` resets binding mode on edition <= 2021 BindingMode(ByRef::No, Mutability::Mut) if !(pat.span.at_least_rust_2024() && self.tcx.features().mut_preserve_binding_mode_2024) && matches!(def_br, ByRef::Yes(_)) => { - // `mut x` resets the binding mode in edition <= 2021. - self.tcx.emit_node_span_lint( - rustc_lint::builtin::DEREFERENCING_MUT_BINDING, - pat.hir_id, - pat.span, - errors::DereferencingMutBinding { span: pat.span }, - ); + self.typeck_results + .borrow_mut() + .rust_2024_migration_desugared_pats_mut() + .insert(pat_info.top_info.hir_id); BindingMode(ByRef::No, Mutability::Mut) } BindingMode(ByRef::No, mutbl) => BindingMode(def_br, mutbl), @@ -754,7 +754,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { span: Span, var_id: HirId, ty: Ty<'tcx>, - ti: TopInfo<'tcx>, + ti: &TopInfo<'tcx>, ) { let var_ty = self.local_ty(span, var_id); if let Some(mut err) = self.demand_eqtype_pat_diag(span, var_ty, ty, ti) { @@ -996,7 +996,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { qpath: &hir::QPath<'_>, path_resolution: (Res, Option>, &'tcx [hir::PathSegment<'tcx>]), expected: Ty<'tcx>, - ti: TopInfo<'tcx>, + ti: &TopInfo<'tcx>, ) -> Ty<'tcx> { let tcx = self.tcx; @@ -2178,8 +2178,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } else { // Reset binding mode on old editions - pat_info.binding_mode = ByRef::No; - pat_info.max_ref_mutbl = MutblCap::Mut + + if pat_info.binding_mode != ByRef::No { + pat_info.binding_mode = ByRef::No; + + self.typeck_results + .borrow_mut() + .rust_2024_migration_desugared_pats_mut() + .insert(pat_info.top_info.hir_id); + } + + pat_info.max_ref_mutbl = MutblCap::Mut; } let tcx = self.tcx; diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs index 0a40ffb0d5aab..45f8fa77e56f8 100644 --- a/compiler/rustc_hir_typeck/src/writeback.rs +++ b/compiler/rustc_hir_typeck/src/writeback.rs @@ -346,6 +346,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for WritebackCx<'cx, 'tcx> { _ => {} }; + self.visit_rust_2024_migration_desugared_pats(p.hir_id); self.visit_skipped_ref_pats(p.hir_id); self.visit_pat_adjustments(p.span, p.hir_id); @@ -655,6 +656,22 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { } } + #[instrument(skip(self), level = "debug")] + fn visit_rust_2024_migration_desugared_pats(&mut self, hir_id: hir::HirId) { + if self + .fcx + .typeck_results + .borrow_mut() + .rust_2024_migration_desugared_pats_mut() + .remove(hir_id) + { + debug!( + "node is a pat whose match ergonomics are desugared by the Rust 2024 migration lint" + ); + self.typeck_results.rust_2024_migration_desugared_pats_mut().insert(hir_id); + } + } + #[instrument(skip(self, span), level = "debug")] fn visit_pat_adjustments(&mut self, span: Span, hir_id: HirId) { let adjustment = self.fcx.typeck_results.borrow_mut().pat_adjustments_mut().remove(hir_id); diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index eea3ca44c48b2..5369454577249 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -38,7 +38,6 @@ declare_lint_pass! { DEPRECATED_CFG_ATTR_CRATE_TYPE_NAME, DEPRECATED_IN_FUTURE, DEPRECATED_WHERE_CLAUSE_LOCATION, - DEREFERENCING_MUT_BINDING, DUPLICATE_MACRO_ATTRIBUTES, ELIDED_LIFETIMES_IN_ASSOCIATED_CONSTANT, ELIDED_LIFETIMES_IN_PATHS, @@ -90,6 +89,7 @@ declare_lint_pass! { RUST_2021_INCOMPATIBLE_OR_PATTERNS, RUST_2021_PREFIXES_INCOMPATIBLE_SYNTAX, RUST_2021_PRELUDE_COLLISIONS, + RUST_2024_INCOMPATIBLE_PAT, SEMICOLON_IN_EXPRESSIONS_FROM_MACROS, SINGLE_USE_LIFETIMES, SOFT_UNSTABLE, @@ -1630,34 +1630,34 @@ declare_lint! { } declare_lint! { - /// The `dereferencing_mut_binding` lint detects a `mut x` pattern that resets the binding mode, - /// as this behavior will change in rust 2024. + /// The `rust_2024_incompatible_pat` lint + /// detects patterns whose meaning will change in the Rust 2024 edition. /// /// ### Example /// - /// ```rust - /// # #![warn(dereferencing_mut_binding)] - /// let x = Some(123u32); - /// let _y = match &x { - /// Some(mut x) => { - /// x += 1; - /// x - /// } - /// None => 0, - /// }; + /// ```rust,edition2021 + /// #![feature(ref_pat_eat_one_layer_2024)] + /// #![warn(rust_2024_incompatible_pat)] + /// + /// if let Some(&a) = &Some(&0u8) { + /// let _: u8 = a; + /// } + /// if let Some(mut _a) = &mut Some(0u8) { + /// _a = 7u8; + /// } /// ``` /// /// {{produces}} /// /// ### Explanation /// - /// Without the `mut`, `x` would have type `&u32`. Pre-2024, adding `mut` makes `x` have type - /// `u32`, which was deemed surprising. After edition 2024, adding `mut` will not change the - /// type of `x`. This lint warns users of editions before 2024 to update their code. - pub DEREFERENCING_MUT_BINDING, + /// In Rust 2024 and above, the `mut` keyword does not reset the pattern binding mode, + /// and nor do `&` or `&mut` patterns. The lint will suggest code that + /// has the same meaning in all editions. + pub RUST_2024_INCOMPATIBLE_PAT, Allow, - "detects `mut x` bindings that change the type of `x`", - @feature_gate = sym::mut_preserve_binding_mode_2024; + "detects patterns whose meaning will change in Rust 2024", + @feature_gate = sym::ref_pat_eat_one_layer_2024; // FIXME uncomment below upon stabilization /*@future_incompatible = FutureIncompatibleInfo { reason: FutureIncompatibilityReason::EditionSemanticsChange(Edition::Edition2024), diff --git a/compiler/rustc_middle/src/ty/typeck_results.rs b/compiler/rustc_middle/src/ty/typeck_results.rs index 41f417dfd4b1a..24e3e623ff274 100644 --- a/compiler/rustc_middle/src/ty/typeck_results.rs +++ b/compiler/rustc_middle/src/ty/typeck_results.rs @@ -79,6 +79,10 @@ pub struct TypeckResults<'tcx> { /// Stores the actual binding mode for all instances of [`BindingMode`]. pat_binding_modes: ItemLocalMap, + /// Top-level patterns whose match ergonomics need to be desugared + /// by the Rust 2021 -> 2024 migration lint. + rust_2024_migration_desugared_pats: ItemLocalSet, + /// Stores the types which were implicitly dereferenced in pattern binding modes /// for later usage in THIR lowering. For example, /// @@ -229,6 +233,7 @@ impl<'tcx> TypeckResults<'tcx> { adjustments: Default::default(), pat_binding_modes: Default::default(), pat_adjustments: Default::default(), + rust_2024_migration_desugared_pats: Default::default(), skipped_ref_pats: Default::default(), closure_kind_origins: Default::default(), liberated_fn_sigs: Default::default(), @@ -432,6 +437,20 @@ impl<'tcx> TypeckResults<'tcx> { LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.pat_adjustments } } + pub fn rust_2024_migration_desugared_pats(&self) -> LocalSetInContext<'_> { + LocalSetInContext { + hir_owner: self.hir_owner, + data: &self.rust_2024_migration_desugared_pats, + } + } + + pub fn rust_2024_migration_desugared_pats_mut(&mut self) -> LocalSetInContextMut<'_> { + LocalSetInContextMut { + hir_owner: self.hir_owner, + data: &mut self.rust_2024_migration_desugared_pats, + } + } + pub fn skipped_ref_pats(&self) -> LocalSetInContext<'_> { LocalSetInContext { hir_owner: self.hir_owner, data: &self.skipped_ref_pats } } diff --git a/compiler/rustc_mir_build/Cargo.toml b/compiler/rustc_mir_build/Cargo.toml index 6618e4f5a0024..77f27236437dd 100644 --- a/compiler/rustc_mir_build/Cargo.toml +++ b/compiler/rustc_mir_build/Cargo.toml @@ -16,6 +16,7 @@ rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_hir = { path = "../rustc_hir" } rustc_index = { path = "../rustc_index" } rustc_infer = { path = "../rustc_infer" } +rustc_lint = { path = "../rustc_lint" } rustc_macros = { path = "../rustc_macros" } rustc_middle = { path = "../rustc_middle" } rustc_pattern_analysis = { path = "../rustc_pattern_analysis" } diff --git a/compiler/rustc_mir_build/messages.ftl b/compiler/rustc_mir_build/messages.ftl index 34440c60cf378..0bb44dbb8706b 100644 --- a/compiler/rustc_mir_build/messages.ftl +++ b/compiler/rustc_mir_build/messages.ftl @@ -267,6 +267,8 @@ mir_build_pointer_pattern = function pointers and raw pointers not derived from mir_build_privately_uninhabited = pattern `{$witness_1}` is currently uninhabited, but this variant contains private fields which may become inhabited in the future +mir_build_rust_2024_incompatible_pat = the semantics of this pattern will change in edition 2024 + mir_build_rustc_box_attribute_error = `#[rustc_box]` attribute used incorrectly .attributes = no other attributes may be applied .not_box = `#[rustc_box]` may only be applied to a `Box::new()` call diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs index f67113afd6d9d..e2a28467b8457 100644 --- a/compiler/rustc_mir_build/src/errors.rs +++ b/compiler/rustc_mir_build/src/errors.rs @@ -950,3 +950,30 @@ pub enum RustcBoxAttrReason { #[note(mir_build_missing_box)] MissingBox, } + +#[derive(LintDiagnostic)] +#[diag(mir_build_rust_2024_incompatible_pat)] +pub struct Rust2024IncompatiblePat { + #[subdiagnostic] + pub sugg: Rust2024IncompatiblePatSugg, +} + +pub struct Rust2024IncompatiblePatSugg { + pub suggestion: Vec<(Span, String)>, +} + +impl Subdiagnostic for Rust2024IncompatiblePatSugg { + fn add_to_diag_with>( + self, + diag: &mut Diag<'_, G>, + _f: &F, + ) { + let applicability = + if self.suggestion.iter().all(|(span, _)| span.can_be_used_for_suggestions()) { + Applicability::MachineApplicable + } else { + Applicability::MaybeIncorrect + }; + diag.multipart_suggestion("desugar the match ergonomics", self.suggestion, applicability); + } +} diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index 5c016682d8d2d..48fc0293f4058 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -11,8 +11,9 @@ use crate::thir::util::UserAnnotatedTyHelpers; use rustc_errors::codes::*; use rustc_hir::def::{CtorOf, DefKind, Res}; use rustc_hir::pat_util::EnumerateAndAdjustIterator; -use rustc_hir::{self as hir, RangeEnd}; +use rustc_hir::{self as hir, ByRef, Mutability, RangeEnd}; use rustc_index::Idx; +use rustc_lint as lint; use rustc_middle::mir::interpret::{ErrorHandled, GlobalId, LitToConstError, LitToConstInput}; use rustc_middle::mir::{self, Const}; use rustc_middle::thir::{ @@ -30,6 +31,9 @@ struct PatCtxt<'a, 'tcx> { tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, typeck_results: &'a ty::TypeckResults<'tcx>, + + /// Used by the Rust 2024 migration lint. + rust_2024_migration_suggestion: Option, } pub(super) fn pat_from_hir<'a, 'tcx>( @@ -38,9 +42,25 @@ pub(super) fn pat_from_hir<'a, 'tcx>( typeck_results: &'a ty::TypeckResults<'tcx>, pat: &'tcx hir::Pat<'tcx>, ) -> Box> { - let mut pcx = PatCtxt { tcx, param_env, typeck_results }; + let mut pcx = PatCtxt { + tcx, + param_env, + typeck_results, + rust_2024_migration_suggestion: typeck_results + .rust_2024_migration_desugared_pats() + .contains(pat.hir_id) + .then_some(Rust2024IncompatiblePatSugg { suggestion: Vec::new() }), + }; let result = pcx.lower_pattern(pat); debug!("pat_from_hir({:?}) = {:?}", pat, result); + if let Some(sugg) = pcx.rust_2024_migration_suggestion { + tcx.emit_node_span_lint( + lint::builtin::RUST_2024_INCOMPATIBLE_PAT, + pat.hir_id, + pat.span, + Rust2024IncompatiblePat { sugg }, + ); + } result } @@ -73,17 +93,38 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { } _ => self.lower_pattern_unadjusted(pat), }; - self.typeck_results.pat_adjustments().get(pat.hir_id).unwrap_or(&vec![]).iter().rev().fold( - unadjusted_pat, - |pat: Box<_>, ref_ty| { - debug!("{:?}: wrapping pattern with type {:?}", pat, ref_ty); - Box::new(Pat { - span: pat.span, - ty: *ref_ty, - kind: PatKind::Deref { subpattern: pat }, + + let adjustments: &[Ty<'tcx>] = + self.typeck_results.pat_adjustments().get(pat.hir_id).map_or(&[], |v| &**v); + let adjusted_pat = adjustments.iter().rev().fold(unadjusted_pat, |thir_pat, ref_ty| { + debug!("{:?}: wrapping pattern with type {:?}", thir_pat, ref_ty); + Box::new(Pat { + span: thir_pat.span, + ty: *ref_ty, + kind: PatKind::Deref { subpattern: thir_pat }, + }) + }); + + if let Some(s) = &mut self.rust_2024_migration_suggestion + && !adjustments.is_empty() + { + let suggestion_str: String = adjustments + .iter() + .map(|ref_ty| { + let &ty::Ref(_, _, mutbl) = ref_ty.kind() else { + span_bug!(pat.span, "pattern implicitly dereferences a non-ref type"); + }; + + match mutbl { + ty::Mutability::Not => "&", + ty::Mutability::Mut => "&mut ", + } }) - }, - ) + .collect(); + s.suggestion.push((pat.span.shrink_to_lo(), suggestion_str)); + }; + + adjusted_pat } fn lower_pattern_range_endpoint( @@ -272,7 +313,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { PatKind::Deref { subpattern: self.lower_pattern(subpattern) } } - hir::PatKind::Slice(prefix, ref slice, suffix) => { + hir::PatKind::Slice(prefix, slice, suffix) => { self.slice_or_array_pattern(pat.span, ty, prefix, slice, suffix) } @@ -284,7 +325,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { PatKind::Leaf { subpatterns } } - hir::PatKind::Binding(_, id, ident, ref sub) => { + hir::PatKind::Binding(explicit_ba, id, ident, sub) => { if let Some(ident_span) = ident.span.find_ancestor_inside(span) { span = span.with_hi(ident_span.hi()); } @@ -295,6 +336,20 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { .get(pat.hir_id) .expect("missing binding mode"); + if let Some(s) = &mut self.rust_2024_migration_suggestion + && explicit_ba.0 == ByRef::No + && let ByRef::Yes(mutbl) = mode.0 + { + let sugg_str = match mutbl { + Mutability::Not => "ref ", + Mutability::Mut => "ref mut ", + }; + s.suggestion.push(( + pat.span.with_lo(ident.span.lo()).shrink_to_lo(), + sugg_str.to_owned(), + )) + } + // A ref x pattern is the same node used for x, and as such it has // x's type, which is &T, where we want T (the type being matched). let var_ty = ty; @@ -366,10 +421,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { pats.iter().map(|p| self.lower_pattern(p)).collect() } - fn lower_opt_pattern( - &mut self, - pat: &'tcx Option<&'tcx hir::Pat<'tcx>>, - ) -> Option>> { + fn lower_opt_pattern(&mut self, pat: Option<&'tcx hir::Pat<'tcx>>) -> Option>> { pat.map(|p| self.lower_pattern(p)) } @@ -378,7 +430,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { span: Span, ty: Ty<'tcx>, prefix: &'tcx [hir::Pat<'tcx>], - slice: &'tcx Option<&'tcx hir::Pat<'tcx>>, + slice: Option<&'tcx hir::Pat<'tcx>>, suffix: &'tcx [hir::Pat<'tcx>], ) -> PatKind<'tcx> { let prefix = self.lower_patterns(prefix); diff --git a/tests/ui/pattern/auxiliary/match_ergonomics_2024_macros.rs b/tests/ui/pattern/auxiliary/match_ergonomics_2024_macros.rs new file mode 100644 index 0000000000000..0b70e4404abce --- /dev/null +++ b/tests/ui/pattern/auxiliary/match_ergonomics_2024_macros.rs @@ -0,0 +1,12 @@ +//@ edition: 2024 +//@ compile-flags: -Z unstable-options + +// This contains a binding in edition 2024, so if matched with a reference binding mode it will end +// up with a `mut ref mut` binding mode. We use this to test the migration lint on patterns with +// mixed editions. +#[macro_export] +macro_rules! mixed_edition_pat { + ($foo:ident) => { + Some(mut $foo) + }; +} diff --git a/tests/ui/pattern/match_ergonomics_2024.fixed b/tests/ui/pattern/match_ergonomics_2024.fixed new file mode 100644 index 0000000000000..d8dbcb217c040 --- /dev/null +++ b/tests/ui/pattern/match_ergonomics_2024.fixed @@ -0,0 +1,57 @@ +//@ edition: 2021 +//@ run-rustfix +//@ rustfix-only-machine-applicable +//@ aux-build:match_ergonomics_2024_macros.rs +#![feature(mut_preserve_binding_mode_2024, ref_pat_eat_one_layer_2024)] +#![allow(incomplete_features, unused)] +#![deny(rust_2024_incompatible_pat)] + +extern crate match_ergonomics_2024_macros; + +struct Foo(u8); + +fn main() { + let &Foo(mut a) = &Foo(0); + //~^ ERROR: the semantics of this pattern will change in edition 2024 + a = 42; + + let &mut Foo(mut a) = &mut Foo(0); + //~^ ERROR: the semantics of this pattern will change in edition 2024 + a = 42; + + if let &&&&&Some(&_) = &&&&&Some(&0u8) {} + //~^ ERROR: the semantics of this pattern will change in edition 2024 + + if let &&&&&Some(&mut _) = &&&&&Some(&mut 0u8) {} + //~^ ERROR: the semantics of this pattern will change in edition 2024 + + if let &&&&&mut Some(&_) = &&&&&mut Some(&0u8) {} + //~^ ERROR: the semantics of this pattern will change in edition 2024 + + if let &mut Some(&mut Some(&mut Some(_))) = &mut Some(&mut Some(&mut Some(0u8))) {} + //~^ ERROR: the semantics of this pattern will change in edition 2024 + + if let &mut Some(&mut Some(&mut Some(ref mut _a))) = &mut Some(&mut Some(&mut Some(0u8))) {} + //~^ ERROR: the semantics of this pattern will change in edition 2024 + + struct Struct { + a: u32, + b: u32, + c: u32, + } + let s = Struct { a: 0, b: 0, c: 0 }; + let &Struct { ref a, mut b, ref c } = &s; + //~^ ERROR: the semantics of this pattern will change in edition 2024 + + #[warn(rust_2024_incompatible_pat)] + match &(Some(0), Some(0)) { + // The two patterns are the same syntactically, but because they're defined in different + // editions they don't mean the same thing. + (Some(mut _x), match_ergonomics_2024_macros::mixed_edition_pat!(_y)) => { + //~^ WARN: the semantics of this pattern will change in edition 2024 + _x = 4; + _y = &7; + } + _ => {} + } +} diff --git a/tests/ui/pattern/match_ergonomics_2024.rs b/tests/ui/pattern/match_ergonomics_2024.rs new file mode 100644 index 0000000000000..38dc0c8bebb2f --- /dev/null +++ b/tests/ui/pattern/match_ergonomics_2024.rs @@ -0,0 +1,57 @@ +//@ edition: 2021 +//@ run-rustfix +//@ rustfix-only-machine-applicable +//@ aux-build:match_ergonomics_2024_macros.rs +#![feature(mut_preserve_binding_mode_2024, ref_pat_eat_one_layer_2024)] +#![allow(incomplete_features, unused)] +#![deny(rust_2024_incompatible_pat)] + +extern crate match_ergonomics_2024_macros; + +struct Foo(u8); + +fn main() { + let Foo(mut a) = &Foo(0); + //~^ ERROR: the semantics of this pattern will change in edition 2024 + a = 42; + + let Foo(mut a) = &mut Foo(0); + //~^ ERROR: the semantics of this pattern will change in edition 2024 + a = 42; + + if let Some(&_) = &&&&&Some(&0u8) {} + //~^ ERROR: the semantics of this pattern will change in edition 2024 + + if let Some(&mut _) = &&&&&Some(&mut 0u8) {} + //~^ ERROR: the semantics of this pattern will change in edition 2024 + + if let Some(&_) = &&&&&mut Some(&0u8) {} + //~^ ERROR: the semantics of this pattern will change in edition 2024 + + if let Some(&mut Some(Some(_))) = &mut Some(&mut Some(&mut Some(0u8))) {} + //~^ ERROR: the semantics of this pattern will change in edition 2024 + + if let Some(&mut Some(Some(_a))) = &mut Some(&mut Some(&mut Some(0u8))) {} + //~^ ERROR: the semantics of this pattern will change in edition 2024 + + struct Struct { + a: u32, + b: u32, + c: u32, + } + let s = Struct { a: 0, b: 0, c: 0 }; + let Struct { a, mut b, c } = &s; + //~^ ERROR: the semantics of this pattern will change in edition 2024 + + #[warn(rust_2024_incompatible_pat)] + match &(Some(0), Some(0)) { + // The two patterns are the same syntactically, but because they're defined in different + // editions they don't mean the same thing. + (Some(mut _x), match_ergonomics_2024_macros::mixed_edition_pat!(_y)) => { + //~^ WARN: the semantics of this pattern will change in edition 2024 + _x = 4; + _y = &7; + } + _ => {} + } +} diff --git a/tests/ui/pattern/match_ergonomics_2024.stderr b/tests/ui/pattern/match_ergonomics_2024.stderr new file mode 100644 index 0000000000000..11844434ad214 --- /dev/null +++ b/tests/ui/pattern/match_ergonomics_2024.stderr @@ -0,0 +1,97 @@ +error: the semantics of this pattern will change in edition 2024 + --> $DIR/match_ergonomics_2024.rs:14:9 + | +LL | let Foo(mut a) = &Foo(0); + | -^^^^^^^^^ + | | + | help: desugar the match ergonomics: `&` + | +note: the lint level is defined here + --> $DIR/match_ergonomics_2024.rs:7:9 + | +LL | #![deny(rust_2024_incompatible_pat)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: the semantics of this pattern will change in edition 2024 + --> $DIR/match_ergonomics_2024.rs:18:9 + | +LL | let Foo(mut a) = &mut Foo(0); + | -^^^^^^^^^ + | | + | help: desugar the match ergonomics: `&mut` + +error: the semantics of this pattern will change in edition 2024 + --> $DIR/match_ergonomics_2024.rs:22:12 + | +LL | if let Some(&_) = &&&&&Some(&0u8) {} + | -^^^^^^^ + | | + | help: desugar the match ergonomics: `&&&&&` + +error: the semantics of this pattern will change in edition 2024 + --> $DIR/match_ergonomics_2024.rs:25:12 + | +LL | if let Some(&mut _) = &&&&&Some(&mut 0u8) {} + | -^^^^^^^^^^^ + | | + | help: desugar the match ergonomics: `&&&&&` + +error: the semantics of this pattern will change in edition 2024 + --> $DIR/match_ergonomics_2024.rs:28:12 + | +LL | if let Some(&_) = &&&&&mut Some(&0u8) {} + | -^^^^^^^ + | | + | help: desugar the match ergonomics: `&&&&&mut` + +error: the semantics of this pattern will change in edition 2024 + --> $DIR/match_ergonomics_2024.rs:31:12 + | +LL | if let Some(&mut Some(Some(_))) = &mut Some(&mut Some(&mut Some(0u8))) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: desugar the match ergonomics + | +LL | if let &mut Some(&mut Some(&mut Some(_))) = &mut Some(&mut Some(&mut Some(0u8))) {} + | ++++ ++++ + +error: the semantics of this pattern will change in edition 2024 + --> $DIR/match_ergonomics_2024.rs:34:12 + | +LL | if let Some(&mut Some(Some(_a))) = &mut Some(&mut Some(&mut Some(0u8))) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: desugar the match ergonomics + | +LL | if let &mut Some(&mut Some(&mut Some(ref mut _a))) = &mut Some(&mut Some(&mut Some(0u8))) {} + | ++++ ++++ +++++++ + +error: the semantics of this pattern will change in edition 2024 + --> $DIR/match_ergonomics_2024.rs:43:9 + | +LL | let Struct { a, mut b, c } = &s; + | ^^^^^^^^^^^^^^^^^^^^^^ + | +help: desugar the match ergonomics + | +LL | let &Struct { ref a, mut b, ref c } = &s; + | + +++ +++ + +warning: the semantics of this pattern will change in edition 2024 + --> $DIR/match_ergonomics_2024.rs:50:9 + | +LL | (Some(mut _x), match_ergonomics_2024_macros::mixed_edition_pat!(_y)) => { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/match_ergonomics_2024.rs:46:12 + | +LL | #[warn(rust_2024_incompatible_pat)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: desugar the match ergonomics + | +LL | &(Some(mut _x), match_ergonomics_2024_macros::mixed_edition_pat!(ref _y)) => { + | + +++ + +error: aborting due to 8 previous errors; 1 warning emitted + diff --git a/tests/ui/pattern/mut_preserve_binding_mode_2024_lint.rs b/tests/ui/pattern/mut_preserve_binding_mode_2024_lint.rs deleted file mode 100644 index 249f251d2cd2e..0000000000000 --- a/tests/ui/pattern/mut_preserve_binding_mode_2024_lint.rs +++ /dev/null @@ -1,16 +0,0 @@ -//@ edition: 2021 -#![feature(mut_preserve_binding_mode_2024)] -#![allow(incomplete_features, unused)] -#![forbid(dereferencing_mut_binding)] - -struct Foo(u8); - -fn main() { - let Foo(mut a) = &Foo(0); - //~^ ERROR: dereferencing `mut` binding - a = 42; - - let Foo(mut a) = &mut Foo(0); - //~^ ERROR: dereferencing `mut` binding - a = 42; -} diff --git a/tests/ui/pattern/mut_preserve_binding_mode_2024_lint.stderr b/tests/ui/pattern/mut_preserve_binding_mode_2024_lint.stderr deleted file mode 100644 index e8d11acd83e50..0000000000000 --- a/tests/ui/pattern/mut_preserve_binding_mode_2024_lint.stderr +++ /dev/null @@ -1,31 +0,0 @@ -error: dereferencing `mut` binding - --> $DIR/mut_preserve_binding_mode_2024_lint.rs:9:13 - | -LL | let Foo(mut a) = &Foo(0); - | ^^^^^ `mut` dereferences the type of this binding - | -help: this will change in edition 2024 - --> $DIR/mut_preserve_binding_mode_2024_lint.rs:9:13 - | -LL | let Foo(mut a) = &Foo(0); - | ^^^^^ -note: the lint level is defined here - --> $DIR/mut_preserve_binding_mode_2024_lint.rs:4:11 - | -LL | #![forbid(dereferencing_mut_binding)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: dereferencing `mut` binding - --> $DIR/mut_preserve_binding_mode_2024_lint.rs:13:13 - | -LL | let Foo(mut a) = &mut Foo(0); - | ^^^^^ `mut` dereferences the type of this binding - | -help: this will change in edition 2024 - --> $DIR/mut_preserve_binding_mode_2024_lint.rs:13:13 - | -LL | let Foo(mut a) = &mut Foo(0); - | ^^^^^ - -error: aborting due to 2 previous errors - From 5808c5801db40d8de97e76660407ba55528df531 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 7 May 2024 15:12:54 -0400 Subject: [PATCH 121/179] Assert that MemCategorizationVisitor actually errors when it bails ungracefully --- .../rustc_hir_typeck/src/mem_categorization.rs | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_hir_typeck/src/mem_categorization.rs b/compiler/rustc_hir_typeck/src/mem_categorization.rs index ae71c484f7b04..acd11d352bf53 100644 --- a/compiler/rustc_hir_typeck/src/mem_categorization.rs +++ b/compiler/rustc_hir_typeck/src/mem_categorization.rs @@ -131,9 +131,15 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> { match ty { Some(ty) => { let ty = self.resolve_vars_if_possible(ty); - if ty.references_error() || ty.is_ty_var() { + if ty.references_error() { debug!("resolve_type_vars_or_error: error from {:?}", ty); Err(()) + } else if ty.is_ty_var() { + debug!("resolve_type_vars_or_error: infer var from {:?}", ty); + self.tcx() + .dcx() + .span_delayed_bug(self.tcx().hir().span(id), "encountered type variable"); + Err(()) } else { Ok(ty) } @@ -210,6 +216,9 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> { Some(ty) => Ok(ty), None => { debug!("By-ref binding of non-derefable type"); + self.tcx() + .dcx() + .span_delayed_bug(pat.span, "by-ref binding of non-derefable type"); Err(()) } } @@ -488,6 +497,10 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> { Some(pointee_ty) => pointee_ty, None => { debug!("explicit deref of non-derefable type: {:?}", base_curr_ty); + self.tcx().dcx().span_delayed_bug( + self.tcx().hir().span(node.hir_id()), + "explicit deref of non-derefable type", + ); return Err(()); } }; @@ -732,6 +745,9 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> { PatKind::Slice(before, ref slice, after) => { let Some(element_ty) = place_with_id.place.ty().builtin_index() else { debug!("explicit index of non-indexable type {:?}", place_with_id); + self.tcx() + .dcx() + .span_delayed_bug(pat.span, "explicit index of non-indexable type"); return Err(()); }; let elt_place = self.cat_projection( From d7595eb6df12c5470f822b19c3a79fa2c3b23848 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 8 May 2024 13:10:50 -0400 Subject: [PATCH 122/179] Inline MemCategorization into ExprUseVisitor --- .../rustc_hir_typeck/src/expr_use_visitor.rs | 905 +++++++++++++++--- compiler/rustc_hir_typeck/src/lib.rs | 1 - .../src/mem_categorization.rs | 790 --------------- .../src/operators/assign_op_pattern.rs | 4 +- src/tools/clippy/clippy_lints/src/unwrap.rs | 2 +- 5 files changed, 778 insertions(+), 924 deletions(-) delete mode 100644 compiler/rustc_hir_typeck/src/mem_categorization.rs diff --git a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs index cc42e69f53827..5b99b547c24d7 100644 --- a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs +++ b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs @@ -2,26 +2,32 @@ //! normal visitor, which just walks the entire body in one shot, the //! `ExprUseVisitor` determines how expressions are being used. +use std::cell::RefCell; use std::slice::from_ref; use hir::def::DefKind; +use hir::pat_util::EnumerateAndAdjustIterator as _; use hir::Expr; // Export these here so that Clippy can use them. pub use rustc_middle::hir::place::{Place, PlaceBase, PlaceWithHirId, Projection}; use rustc_data_structures::fx::FxIndexMap; use rustc_hir as hir; -use rustc_hir::def::Res; +use rustc_hir::def::{CtorOf, Res}; use rustc_hir::def_id::LocalDefId; use rustc_hir::{HirId, PatKind}; use rustc_infer::infer::InferCtxt; use rustc_middle::hir::place::ProjectionKind; use rustc_middle::mir::FakeReadCause; -use rustc_middle::ty::{self, adjustment, AdtKind, Ty, TyCtxt}; -use rustc_target::abi::FIRST_VARIANT; +use rustc_middle::ty::{ + self, adjustment, AdtKind, Ty, TyCtxt, TypeFoldable, TypeVisitableExt as _, +}; +use rustc_span::{ErrorGuaranteed, Span}; +use rustc_target::abi::{FieldIdx, VariantIdx, FIRST_VARIANT}; +use rustc_trait_selection::infer::InferCtxtExt as _; use ty::BorrowKind::ImmBorrow; -use crate::mem_categorization as mc; +type McResult = Result; /// This trait defines the callbacks you can expect to receive when /// employing the ExprUseVisitor. @@ -80,21 +86,16 @@ pub trait Delegate<'tcx> { ); } -#[derive(Copy, Clone, PartialEq, Debug)] -enum ConsumeMode { - /// reference to x where x has a type that copies - Copy, - /// reference to x where x has a type that moves - Move, -} - /// The ExprUseVisitor type /// /// This is the code that actually walks the tree. -pub struct ExprUseVisitor<'a, 'tcx> { - mc: mc::MemCategorizationContext<'a, 'tcx>, +pub struct ExprUseVisitor<'a, 'tcx, D: Delegate<'tcx>> { + typeck_results: &'a ty::TypeckResults<'tcx>, + infcx: &'a InferCtxt<'tcx>, + param_env: ty::ParamEnv<'tcx>, + upvars: Option<&'tcx FxIndexMap>, body_owner: LocalDefId, - delegate: &'a mut dyn Delegate<'tcx>, + delegate: RefCell<&'a mut D>, } /// If the MC results in an error, it's because the type check @@ -108,7 +109,7 @@ macro_rules! return_if_err { ($inp: expr) => { match $inp { Ok(v) => v, - Err(()) => { + Err(_) => { debug!("mc reported err"); return; } @@ -116,33 +117,36 @@ macro_rules! return_if_err { }; } -impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { +impl<'a, 'tcx, D: Delegate<'tcx>> ExprUseVisitor<'a, 'tcx, D> { /// Creates the ExprUseVisitor, configuring it with the various options provided: /// /// - `delegate` -- who receives the callbacks /// - `param_env` --- parameter environment for trait lookups (esp. pertaining to `Copy`) /// - `typeck_results` --- typeck results for the code being analyzed pub fn new( - delegate: &'a mut (dyn Delegate<'tcx> + 'a), + delegate: &'a mut D, infcx: &'a InferCtxt<'tcx>, body_owner: LocalDefId, param_env: ty::ParamEnv<'tcx>, typeck_results: &'a ty::TypeckResults<'tcx>, ) -> Self { ExprUseVisitor { - mc: mc::MemCategorizationContext::new(infcx, param_env, body_owner, typeck_results), + infcx, + param_env, + typeck_results, body_owner, - delegate, + delegate: RefCell::new(delegate), + upvars: infcx.tcx.upvars_mentioned(body_owner), } } #[instrument(skip(self), level = "debug")] - pub fn consume_body(&mut self, body: &hir::Body<'_>) { + pub fn consume_body(&self, body: &hir::Body<'_>) { for param in body.params { - let param_ty = return_if_err!(self.mc.pat_ty_adjusted(param.pat)); + let param_ty = return_if_err!(self.pat_ty_adjusted(param.pat)); debug!("consume_body: param_ty = {:?}", param_ty); - let param_place = self.mc.cat_rvalue(param.hir_id, param_ty); + let param_place = self.cat_rvalue(param.hir_id, param_ty); self.walk_irrefutable_pat(¶m_place, param.pat); } @@ -151,47 +155,50 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { } fn tcx(&self) -> TyCtxt<'tcx> { - self.mc.tcx() + self.infcx.tcx } - fn delegate_consume(&mut self, place_with_id: &PlaceWithHirId<'tcx>, diag_expr_id: HirId) { - delegate_consume(&self.mc, self.delegate, place_with_id, diag_expr_id) + fn consume_or_copy(&self, place_with_id: &PlaceWithHirId<'tcx>, diag_expr_id: HirId) { + debug!("delegate_consume(place_with_id={:?})", place_with_id); + + if self.type_is_copy_modulo_regions(place_with_id.place.ty()) { + self.delegate.borrow_mut().copy(place_with_id, diag_expr_id) + } else { + self.delegate.borrow_mut().consume(place_with_id, diag_expr_id) + } } - fn consume_exprs(&mut self, exprs: &[hir::Expr<'_>]) { + fn consume_exprs(&self, exprs: &[hir::Expr<'_>]) { for expr in exprs { self.consume_expr(expr); } } - pub fn consume_expr(&mut self, expr: &hir::Expr<'_>) { + // FIXME: It's suspicious that this is public; clippy should probably use `walk_expr`. + pub fn consume_expr(&self, expr: &hir::Expr<'_>) { debug!("consume_expr(expr={:?})", expr); - let place_with_id = return_if_err!(self.mc.cat_expr(expr)); - self.delegate_consume(&place_with_id, place_with_id.hir_id); + let place_with_id = return_if_err!(self.cat_expr(expr)); + self.consume_or_copy(&place_with_id, place_with_id.hir_id); self.walk_expr(expr); } - fn mutate_expr(&mut self, expr: &hir::Expr<'_>) { - let place_with_id = return_if_err!(self.mc.cat_expr(expr)); - self.delegate.mutate(&place_with_id, place_with_id.hir_id); + fn mutate_expr(&self, expr: &hir::Expr<'_>) { + let place_with_id = return_if_err!(self.cat_expr(expr)); + self.delegate.borrow_mut().mutate(&place_with_id, place_with_id.hir_id); self.walk_expr(expr); } - fn borrow_expr(&mut self, expr: &hir::Expr<'_>, bk: ty::BorrowKind) { + fn borrow_expr(&self, expr: &hir::Expr<'_>, bk: ty::BorrowKind) { debug!("borrow_expr(expr={:?}, bk={:?})", expr, bk); - let place_with_id = return_if_err!(self.mc.cat_expr(expr)); - self.delegate.borrow(&place_with_id, place_with_id.hir_id, bk); - - self.walk_expr(expr) - } + let place_with_id = return_if_err!(self.cat_expr(expr)); + self.delegate.borrow_mut().borrow(&place_with_id, place_with_id.hir_id, bk); - fn select_from_expr(&mut self, expr: &hir::Expr<'_>) { self.walk_expr(expr) } - pub fn walk_expr(&mut self, expr: &hir::Expr<'_>) { + pub fn walk_expr(&self, expr: &hir::Expr<'_>) { debug!("walk_expr(expr={:?})", expr); self.walk_adjustment(expr); @@ -203,17 +210,17 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { hir::ExprKind::Unary(hir::UnOp::Deref, base) => { // *base - self.select_from_expr(base); + self.walk_expr(base); } hir::ExprKind::Field(base, _) => { // base.f - self.select_from_expr(base); + self.walk_expr(base); } hir::ExprKind::Index(lhs, rhs, _) => { // lhs[rhs] - self.select_from_expr(lhs); + self.walk_expr(lhs); self.consume_expr(rhs); } @@ -246,11 +253,11 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { } hir::ExprKind::Let(hir::LetExpr { pat, init, .. }) => { - self.walk_local(init, pat, None, |t| t.borrow_expr(init, ty::ImmBorrow)) + self.walk_local(init, pat, None, || self.borrow_expr(init, ty::ImmBorrow)) } hir::ExprKind::Match(discr, arms, _) => { - let discr_place = return_if_err!(self.mc.cat_expr(discr)); + let discr_place = return_if_err!(self.cat_expr(discr)); return_if_err!(self.maybe_read_scrutinee( discr, discr_place.clone(), @@ -347,7 +354,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { } hir::ExprKind::AssignOp(_, lhs, rhs) => { - if self.mc.typeck_results.is_method_call(expr) { + if self.typeck_results.is_method_call(expr) { self.consume_expr(lhs); } else { self.mutate_expr(lhs); @@ -369,10 +376,10 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { } } - fn walk_stmt(&mut self, stmt: &hir::Stmt<'_>) { + fn walk_stmt(&self, stmt: &hir::Stmt<'_>) { match stmt.kind { hir::StmtKind::Let(hir::LetStmt { pat, init: Some(expr), els, .. }) => { - self.walk_local(expr, pat, *els, |_| {}) + self.walk_local(expr, pat, *els, || {}) } hir::StmtKind::Let(_) => {} @@ -389,19 +396,18 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { } fn maybe_read_scrutinee<'t>( - &mut self, + &self, discr: &Expr<'_>, discr_place: PlaceWithHirId<'tcx>, pats: impl Iterator>, - ) -> Result<(), ()> { + ) -> McResult<()> { // Matching should not always be considered a use of the place, hence // discr does not necessarily need to be borrowed. // We only want to borrow discr if the pattern contain something other // than wildcards. - let ExprUseVisitor { ref mc, body_owner: _, delegate: _ } = *self; let mut needs_to_be_read = false; for pat in pats { - mc.cat_pattern(discr_place.clone(), pat, |place, pat| { + self.cat_pattern(discr_place.clone(), pat, |place, pat| { match &pat.kind { PatKind::Binding(.., opt_sub_pat) => { // If the opt_sub_pat is None, then the binding does not count as @@ -419,7 +425,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { // A `Path` pattern is just a name like `Foo`. This is either a // named constant or else it refers to an ADT variant - let res = self.mc.typeck_results.qpath_res(qpath, pat.hir_id); + let res = self.typeck_results.qpath_res(qpath, pat.hir_id); match res { Res::Def(DefKind::Const, _) | Res::Def(DefKind::AssocConst, _) => { // Named constants have to be equated with the value @@ -484,7 +490,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { _ => None, }; - self.delegate.fake_read( + self.delegate.borrow_mut().fake_read( &discr_place, FakeReadCause::ForMatchedPlace(closure_def_id), discr_place.hir_id, @@ -498,17 +504,17 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { } fn walk_local( - &mut self, + &self, expr: &hir::Expr<'_>, pat: &hir::Pat<'_>, els: Option<&hir::Block<'_>>, mut f: F, ) where - F: FnMut(&mut Self), + F: FnMut(), { self.walk_expr(expr); - let expr_place = return_if_err!(self.mc.cat_expr(expr)); - f(self); + let expr_place = return_if_err!(self.cat_expr(expr)); + f(); if let Some(els) = els { // borrowing because we need to test the discriminant return_if_err!(self.maybe_read_scrutinee( @@ -523,7 +529,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { /// Indicates that the value of `blk` will be consumed, meaning either copied or moved /// depending on its type. - fn walk_block(&mut self, blk: &hir::Block<'_>) { + fn walk_block(&self, blk: &hir::Block<'_>) { debug!("walk_block(blk.hir_id={})", blk.hir_id); for stmt in blk.stmts { @@ -536,7 +542,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { } fn walk_struct_expr<'hir>( - &mut self, + &self, fields: &[hir::ExprField<'_>], opt_with: &Option<&'hir hir::Expr<'_>>, ) { @@ -545,7 +551,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { self.consume_expr(field.expr); // The struct path probably didn't resolve - if self.mc.typeck_results.opt_field_index(field.hir_id).is_none() { + if self.typeck_results.opt_field_index(field.hir_id).is_none() { self.tcx().dcx().span_delayed_bug(field.span, "couldn't resolve index for field"); } } @@ -557,7 +563,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { } }; - let with_place = return_if_err!(self.mc.cat_expr(with_expr)); + let with_place = return_if_err!(self.cat_expr(with_expr)); // Select just those fields of the `with` // expression that will actually be used @@ -567,15 +573,15 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { for (f_index, with_field) in adt.non_enum_variant().fields.iter_enumerated() { let is_mentioned = fields .iter() - .any(|f| self.mc.typeck_results.opt_field_index(f.hir_id) == Some(f_index)); + .any(|f| self.typeck_results.opt_field_index(f.hir_id) == Some(f_index)); if !is_mentioned { - let field_place = self.mc.cat_projection( - &*with_expr, + let field_place = self.cat_projection( + with_expr.hir_id, with_place.clone(), with_field.ty(self.tcx(), args), ProjectionKind::Field(f_index, FIRST_VARIANT), ); - self.delegate_consume(&field_place, field_place.hir_id); + self.consume_or_copy(&field_place, field_place.hir_id); } } } @@ -598,9 +604,9 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { /// Invoke the appropriate delegate calls for anything that gets /// consumed or borrowed as part of the automatic adjustment /// process. - fn walk_adjustment(&mut self, expr: &hir::Expr<'_>) { - let adjustments = self.mc.typeck_results.expr_adjustments(expr); - let mut place_with_id = return_if_err!(self.mc.cat_expr_unadjusted(expr)); + fn walk_adjustment(&self, expr: &hir::Expr<'_>) { + let adjustments = self.typeck_results.expr_adjustments(expr); + let mut place_with_id = return_if_err!(self.cat_expr_unadjusted(expr)); for adjustment in adjustments { debug!("walk_adjustment expr={:?} adj={:?}", expr, adjustment); match adjustment.kind { @@ -609,7 +615,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { | adjustment::Adjust::DynStar => { // Creating a closure/fn-pointer or unsizing consumes // the input and stores it into the resulting rvalue. - self.delegate_consume(&place_with_id, place_with_id.hir_id); + self.consume_or_copy(&place_with_id, place_with_id.hir_id); } adjustment::Adjust::Deref(None) => {} @@ -621,15 +627,14 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { // this is an autoref of `x`. adjustment::Adjust::Deref(Some(ref deref)) => { let bk = ty::BorrowKind::from_mutbl(deref.mutbl); - self.delegate.borrow(&place_with_id, place_with_id.hir_id, bk); + self.delegate.borrow_mut().borrow(&place_with_id, place_with_id.hir_id, bk); } adjustment::Adjust::Borrow(ref autoref) => { self.walk_autoref(expr, &place_with_id, autoref); } } - place_with_id = - return_if_err!(self.mc.cat_expr_adjusted(expr, place_with_id, adjustment)); + place_with_id = return_if_err!(self.cat_expr_adjusted(expr, place_with_id, adjustment)); } } @@ -637,7 +642,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { /// `expr`. `base_place` is the mem-categorized form of `expr` /// after all relevant autoderefs have occurred. fn walk_autoref( - &mut self, + &self, expr: &hir::Expr<'_>, base_place: &PlaceWithHirId<'tcx>, autoref: &adjustment::AutoBorrow<'tcx>, @@ -649,7 +654,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { match *autoref { adjustment::AutoBorrow::Ref(_, m) => { - self.delegate.borrow( + self.delegate.borrow_mut().borrow( base_place, base_place.hir_id, ty::BorrowKind::from_mutbl(m.into()), @@ -659,18 +664,22 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { adjustment::AutoBorrow::RawPtr(m) => { debug!("walk_autoref: expr.hir_id={} base_place={:?}", expr.hir_id, base_place); - self.delegate.borrow(base_place, base_place.hir_id, ty::BorrowKind::from_mutbl(m)); + self.delegate.borrow_mut().borrow( + base_place, + base_place.hir_id, + ty::BorrowKind::from_mutbl(m), + ); } } } - fn walk_arm(&mut self, discr_place: &PlaceWithHirId<'tcx>, arm: &hir::Arm<'_>) { + fn walk_arm(&self, discr_place: &PlaceWithHirId<'tcx>, arm: &hir::Arm<'_>) { let closure_def_id = match discr_place.place.base { PlaceBase::Upvar(upvar_id) => Some(upvar_id.closure_expr_id), _ => None, }; - self.delegate.fake_read( + self.delegate.borrow_mut().fake_read( discr_place, FakeReadCause::ForMatchedPlace(closure_def_id), discr_place.hir_id, @@ -686,13 +695,13 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { /// Walks a pat that occurs in isolation (i.e., top-level of fn argument or /// let binding, and *not* a match arm or nested pat.) - fn walk_irrefutable_pat(&mut self, discr_place: &PlaceWithHirId<'tcx>, pat: &hir::Pat<'_>) { + fn walk_irrefutable_pat(&self, discr_place: &PlaceWithHirId<'tcx>, pat: &hir::Pat<'_>) { let closure_def_id = match discr_place.place.base { PlaceBase::Upvar(upvar_id) => Some(upvar_id.closure_expr_id), _ => None, }; - self.delegate.fake_read( + self.delegate.borrow_mut().fake_read( discr_place, FakeReadCause::ForLet(closure_def_id), discr_place.hir_id, @@ -701,38 +710,32 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { } /// The core driver for walking a pattern - fn walk_pat( - &mut self, - discr_place: &PlaceWithHirId<'tcx>, - pat: &hir::Pat<'_>, - has_guard: bool, - ) { + fn walk_pat(&self, discr_place: &PlaceWithHirId<'tcx>, pat: &hir::Pat<'_>, has_guard: bool) { debug!("walk_pat(discr_place={:?}, pat={:?}, has_guard={:?})", discr_place, pat, has_guard); let tcx = self.tcx(); - let ExprUseVisitor { ref mc, body_owner: _, ref mut delegate } = *self; - return_if_err!(mc.cat_pattern(discr_place.clone(), pat, |place, pat| { + return_if_err!(self.cat_pattern(discr_place.clone(), pat, |place, pat| { if let PatKind::Binding(_, canonical_id, ..) = pat.kind { debug!("walk_pat: binding place={:?} pat={:?}", place, pat); if let Some(bm) = - mc.typeck_results.extract_binding_mode(tcx.sess, pat.hir_id, pat.span) + self.typeck_results.extract_binding_mode(tcx.sess, pat.hir_id, pat.span) { debug!("walk_pat: pat.hir_id={:?} bm={:?}", pat.hir_id, bm); // pat_ty: the type of the binding being produced. - let pat_ty = return_if_err!(mc.node_ty(pat.hir_id)); + let pat_ty = return_if_err!(self.node_ty(pat.hir_id)); debug!("walk_pat: pat_ty={:?}", pat_ty); let def = Res::Local(canonical_id); - if let Ok(ref binding_place) = mc.cat_res(pat.hir_id, pat.span, pat_ty, def) { - delegate.bind(binding_place, binding_place.hir_id); + if let Ok(ref binding_place) = self.cat_res(pat.hir_id, pat.span, pat_ty, def) { + self.delegate.borrow_mut().bind(binding_place, binding_place.hir_id); } // Subtle: MIR desugaring introduces immutable borrows for each pattern // binding when lowering pattern guards to ensure that the guard does not // modify the scrutinee. if has_guard { - delegate.borrow(place, discr_place.hir_id, ImmBorrow); + self.delegate.borrow_mut().borrow(place, discr_place.hir_id, ImmBorrow); } // It is also a borrow or copy/move of the value being matched. @@ -742,11 +745,11 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { match bm.0 { hir::ByRef::Yes(m) => { let bk = ty::BorrowKind::from_mutbl(m); - delegate.borrow(place, discr_place.hir_id, bk); + self.delegate.borrow_mut().borrow(place, discr_place.hir_id, bk); } hir::ByRef::No => { debug!("walk_pat binding consuming pat"); - delegate_consume(mc, *delegate, place, discr_place.hir_id); + self.consume_or_copy(place, discr_place.hir_id); } } } @@ -755,10 +758,10 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { // determines whether to borrow *at the level of the deref pattern* rather than // borrowing the bound place (since that inner place is inside the temporary that // stores the result of calling `deref()`/`deref_mut()` so can't be captured). - let mutable = mc.typeck_results.pat_has_ref_mut_binding(subpattern); + let mutable = self.typeck_results.pat_has_ref_mut_binding(subpattern); let mutability = if mutable { hir::Mutability::Mut } else { hir::Mutability::Not }; let bk = ty::BorrowKind::from_mutbl(mutability); - delegate.borrow(place, discr_place.hir_id, bk); + self.delegate.borrow_mut().borrow(place, discr_place.hir_id, bk); } })); } @@ -782,7 +785,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { /// /// - When reporting the Place back to the Delegate, ensure that the UpvarId uses the enclosing /// closure as the DefId. - fn walk_captures(&mut self, closure_expr: &hir::Closure<'_>) { + fn walk_captures(&self, closure_expr: &hir::Closure<'_>) { fn upvar_is_local_variable( upvars: Option<&FxIndexMap>, upvar_id: HirId, @@ -802,7 +805,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { matches!(tcx.hir().body_owner_kind(self.body_owner), hir::BodyOwnerKind::Closure,); // If we have a nested closure, we want to include the fake reads present in the nested closure. - if let Some(fake_reads) = self.mc.typeck_results.closure_fake_reads.get(&closure_def_id) { + if let Some(fake_reads) = self.typeck_results.closure_fake_reads.get(&closure_def_id) { for (fake_read, cause, hir_id) in fake_reads.iter() { match fake_read.base { PlaceBase::Upvar(upvar_id) => { @@ -837,7 +840,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { ); } }; - self.delegate.fake_read( + self.delegate.borrow_mut().fake_read( &PlaceWithHirId { place: fake_read.clone(), hir_id: *hir_id }, *cause, *hir_id, @@ -845,8 +848,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { } } - if let Some(min_captures) = self.mc.typeck_results.closure_min_captures.get(&closure_def_id) - { + if let Some(min_captures) = self.typeck_results.closure_min_captures.get(&closure_def_id) { for (var_hir_id, min_list) in min_captures.iter() { if upvars.map_or(body_owner_is_closure, |upvars| !upvars.contains_key(var_hir_id)) { // The nested closure might be capturing the current (enclosing) closure's local variables. @@ -878,10 +880,10 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { match capture_info.capture_kind { ty::UpvarCapture::ByValue => { - self.delegate_consume(&place_with_id, place_with_id.hir_id); + self.consume_or_copy(&place_with_id, place_with_id.hir_id); } ty::UpvarCapture::ByRef(upvar_borrow) => { - self.delegate.borrow( + self.delegate.borrow_mut().borrow( &place_with_id, place_with_id.hir_id, upvar_borrow, @@ -892,34 +894,677 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { } } } -} -fn copy_or_move<'a, 'tcx>( - mc: &mc::MemCategorizationContext<'a, 'tcx>, - place_with_id: &PlaceWithHirId<'tcx>, -) -> ConsumeMode { - if !mc.type_is_copy_modulo_regions(place_with_id.place.ty()) { - ConsumeMode::Move - } else { - ConsumeMode::Copy + fn type_is_copy_modulo_regions(&self, ty: Ty<'tcx>) -> bool { + self.infcx.type_is_copy_modulo_regions(self.param_env, ty) } -} -// - If a place is used in a `ByValue` context then move it if it's not a `Copy` type. -// - If the place that is a `Copy` type consider it an `ImmBorrow`. -fn delegate_consume<'a, 'tcx>( - mc: &mc::MemCategorizationContext<'a, 'tcx>, - delegate: &mut (dyn Delegate<'tcx> + 'a), - place_with_id: &PlaceWithHirId<'tcx>, - diag_expr_id: HirId, -) { - debug!("delegate_consume(place_with_id={:?})", place_with_id); - - let mode = copy_or_move(mc, place_with_id); - - match mode { - ConsumeMode::Move => delegate.consume(place_with_id, diag_expr_id), - ConsumeMode::Copy => delegate.copy(place_with_id, diag_expr_id), + fn resolve_vars_if_possible(&self, value: T) -> T + where + T: TypeFoldable>, + { + self.infcx.resolve_vars_if_possible(value) + } + + fn tainted_by_errors(&self) -> Option { + self.infcx.tainted_by_errors() + } + + fn resolve_type_vars_or_error(&self, id: HirId, ty: Option>) -> McResult> { + match ty { + Some(ty) => { + let ty = self.resolve_vars_if_possible(ty); + if let Err(guar) = ty.error_reported() { + debug!("resolve_type_vars_or_error: error from {:?}", ty); + Err(guar) + } else if ty.is_ty_var() { + debug!("resolve_type_vars_or_error: infer var from {:?}", ty); + Err(self + .tcx() + .dcx() + .span_delayed_bug(self.tcx().hir().span(id), "encountered type variable")) + } else { + Ok(ty) + } + } + None => { + // FIXME + if let Some(guar) = self.tainted_by_errors() { + Err(guar) + } else { + bug!( + "no type for node {} in mem_categorization", + self.tcx().hir().node_to_string(id) + ); + } + } + } + } + + fn node_ty(&self, hir_id: HirId) -> McResult> { + self.resolve_type_vars_or_error(hir_id, self.typeck_results.node_type_opt(hir_id)) + } + + fn expr_ty(&self, expr: &hir::Expr<'_>) -> McResult> { + self.resolve_type_vars_or_error(expr.hir_id, self.typeck_results.expr_ty_opt(expr)) + } + + fn expr_ty_adjusted(&self, expr: &hir::Expr<'_>) -> McResult> { + self.resolve_type_vars_or_error(expr.hir_id, self.typeck_results.expr_ty_adjusted_opt(expr)) + } + + /// Returns the type of value that this pattern matches against. + /// Some non-obvious cases: + /// + /// - a `ref x` binding matches against a value of type `T` and gives + /// `x` the type `&T`; we return `T`. + /// - a pattern with implicit derefs (thanks to default binding + /// modes #42640) may look like `Some(x)` but in fact have + /// implicit deref patterns attached (e.g., it is really + /// `&Some(x)`). In that case, we return the "outermost" type + /// (e.g., `&Option`). + fn pat_ty_adjusted(&self, pat: &hir::Pat<'_>) -> McResult> { + // Check for implicit `&` types wrapping the pattern; note + // that these are never attached to binding patterns, so + // actually this is somewhat "disjoint" from the code below + // that aims to account for `ref x`. + if let Some(vec) = self.typeck_results.pat_adjustments().get(pat.hir_id) { + if let Some(first_ty) = vec.first() { + debug!("pat_ty(pat={:?}) found adjusted ty `{:?}`", pat, first_ty); + return Ok(*first_ty); + } + } + + self.pat_ty_unadjusted(pat) + } + + /// Like `pat_ty`, but ignores implicit `&` patterns. + #[instrument(level = "debug", skip(self), ret)] + fn pat_ty_unadjusted(&self, pat: &hir::Pat<'_>) -> McResult> { + let base_ty = self.node_ty(pat.hir_id)?; + trace!(?base_ty); + + // This code detects whether we are looking at a `ref x`, + // and if so, figures out what the type *being borrowed* is. + match pat.kind { + PatKind::Binding(..) => { + let bm = *self + .typeck_results + .pat_binding_modes() + .get(pat.hir_id) + .expect("missing binding mode"); + + if matches!(bm.0, hir::ByRef::Yes(_)) { + // a bind-by-ref means that the base_ty will be the type of the ident itself, + // but what we want here is the type of the underlying value being borrowed. + // So peel off one-level, turning the &T into T. + match base_ty.builtin_deref(false) { + Some(t) => Ok(t.ty), + None => { + debug!("By-ref binding of non-derefable type"); + Err(self + .tcx() + .dcx() + .span_delayed_bug(pat.span, "by-ref binding of non-derefable type")) + } + } + } else { + Ok(base_ty) + } + } + _ => Ok(base_ty), + } + } + + fn cat_expr(&self, expr: &hir::Expr<'_>) -> McResult> { + // This recursion helper avoids going through *too many* + // adjustments, since *only* non-overloaded deref recurses. + fn helper<'a, 'tcx, D: Delegate<'tcx>>( + this: &ExprUseVisitor<'a, 'tcx, D>, + expr: &hir::Expr<'_>, + adjustments: &[adjustment::Adjustment<'tcx>], + ) -> McResult> { + match adjustments.split_last() { + None => this.cat_expr_unadjusted(expr), + Some((adjustment, previous)) => { + this.cat_expr_adjusted_with(expr, || helper(this, expr, previous), adjustment) + } + } + } + + helper(self, expr, self.typeck_results.expr_adjustments(expr)) + } + + fn cat_expr_adjusted( + &self, + expr: &hir::Expr<'_>, + previous: PlaceWithHirId<'tcx>, + adjustment: &adjustment::Adjustment<'tcx>, + ) -> McResult> { + self.cat_expr_adjusted_with(expr, || Ok(previous), adjustment) + } + + #[instrument(level = "debug", skip(self, previous))] + fn cat_expr_adjusted_with( + &self, + expr: &hir::Expr<'_>, + previous: F, + adjustment: &adjustment::Adjustment<'tcx>, + ) -> McResult> + where + F: FnOnce() -> McResult>, + { + let target = self.resolve_vars_if_possible(adjustment.target); + match adjustment.kind { + adjustment::Adjust::Deref(overloaded) => { + // Equivalent to *expr or something similar. + let base = if let Some(deref) = overloaded { + let ref_ty = Ty::new_ref(self.tcx(), deref.region, target, deref.mutbl); + self.cat_rvalue(expr.hir_id, ref_ty) + } else { + previous()? + }; + self.cat_deref(expr.hir_id, base) + } + + adjustment::Adjust::NeverToAny + | adjustment::Adjust::Pointer(_) + | adjustment::Adjust::Borrow(_) + | adjustment::Adjust::DynStar => { + // Result is an rvalue. + Ok(self.cat_rvalue(expr.hir_id, target)) + } + } + } + + #[instrument(level = "debug", skip(self), ret)] + fn cat_expr_unadjusted(&self, expr: &hir::Expr<'_>) -> McResult> { + let expr_ty = self.expr_ty(expr)?; + match expr.kind { + hir::ExprKind::Unary(hir::UnOp::Deref, e_base) => { + if self.typeck_results.is_method_call(expr) { + self.cat_overloaded_place(expr, e_base) + } else { + let base = self.cat_expr(e_base)?; + self.cat_deref(expr.hir_id, base) + } + } + + hir::ExprKind::Field(base, _) => { + let base = self.cat_expr(base)?; + debug!(?base); + + let field_idx = self + .typeck_results + .field_indices() + .get(expr.hir_id) + .cloned() + .expect("Field index not found"); + + Ok(self.cat_projection( + expr.hir_id, + base, + expr_ty, + ProjectionKind::Field(field_idx, FIRST_VARIANT), + )) + } + + hir::ExprKind::Index(base, _, _) => { + if self.typeck_results.is_method_call(expr) { + // If this is an index implemented by a method call, then it + // will include an implicit deref of the result. + // The call to index() returns a `&T` value, which + // is an rvalue. That is what we will be + // dereferencing. + self.cat_overloaded_place(expr, base) + } else { + let base = self.cat_expr(base)?; + Ok(self.cat_projection(expr.hir_id, base, expr_ty, ProjectionKind::Index)) + } + } + + hir::ExprKind::Path(ref qpath) => { + let res = self.typeck_results.qpath_res(qpath, expr.hir_id); + self.cat_res(expr.hir_id, expr.span, expr_ty, res) + } + + hir::ExprKind::Type(e, _) => self.cat_expr(e), + + hir::ExprKind::AddrOf(..) + | hir::ExprKind::Call(..) + | hir::ExprKind::Assign(..) + | hir::ExprKind::AssignOp(..) + | hir::ExprKind::Closure { .. } + | hir::ExprKind::Ret(..) + | hir::ExprKind::Become(..) + | hir::ExprKind::Unary(..) + | hir::ExprKind::Yield(..) + | hir::ExprKind::MethodCall(..) + | hir::ExprKind::Cast(..) + | hir::ExprKind::DropTemps(..) + | hir::ExprKind::Array(..) + | hir::ExprKind::If(..) + | hir::ExprKind::Tup(..) + | hir::ExprKind::Binary(..) + | hir::ExprKind::Block(..) + | hir::ExprKind::Let(..) + | hir::ExprKind::Loop(..) + | hir::ExprKind::Match(..) + | hir::ExprKind::Lit(..) + | hir::ExprKind::ConstBlock(..) + | hir::ExprKind::Break(..) + | hir::ExprKind::Continue(..) + | hir::ExprKind::Struct(..) + | hir::ExprKind::Repeat(..) + | hir::ExprKind::InlineAsm(..) + | hir::ExprKind::OffsetOf(..) + | hir::ExprKind::Err(_) => Ok(self.cat_rvalue(expr.hir_id, expr_ty)), + } + } + + #[instrument(level = "debug", skip(self, span), ret)] + fn cat_res( + &self, + hir_id: HirId, + span: Span, + expr_ty: Ty<'tcx>, + res: Res, + ) -> McResult> { + match res { + Res::Def( + DefKind::Ctor(..) + | DefKind::Const + | DefKind::ConstParam + | DefKind::AssocConst + | DefKind::Fn + | DefKind::AssocFn, + _, + ) + | Res::SelfCtor(..) => Ok(self.cat_rvalue(hir_id, expr_ty)), + + Res::Def(DefKind::Static { .. }, _) => { + Ok(PlaceWithHirId::new(hir_id, expr_ty, PlaceBase::StaticItem, Vec::new())) + } + + Res::Local(var_id) => { + if self.upvars.is_some_and(|upvars| upvars.contains_key(&var_id)) { + self.cat_upvar(hir_id, var_id) + } else { + Ok(PlaceWithHirId::new(hir_id, expr_ty, PlaceBase::Local(var_id), Vec::new())) + } + } + + def => span_bug!(span, "unexpected definition in memory categorization: {:?}", def), + } + } + + /// Categorize an upvar. + /// + /// Note: the actual upvar access contains invisible derefs of closure + /// environment and upvar reference as appropriate. Only regionck cares + /// about these dereferences, so we let it compute them as needed. + #[instrument(level = "debug", skip(self), ret)] + fn cat_upvar(&self, hir_id: HirId, var_id: HirId) -> McResult> { + let closure_expr_def_id = self.body_owner; + + let upvar_id = ty::UpvarId { + var_path: ty::UpvarPath { hir_id: var_id }, + closure_expr_id: closure_expr_def_id, + }; + let var_ty = self.node_ty(var_id)?; + + Ok(PlaceWithHirId::new(hir_id, var_ty, PlaceBase::Upvar(upvar_id), Vec::new())) + } + + #[instrument(level = "debug", skip(self), ret)] + fn cat_rvalue(&self, hir_id: HirId, expr_ty: Ty<'tcx>) -> PlaceWithHirId<'tcx> { + PlaceWithHirId::new(hir_id, expr_ty, PlaceBase::Rvalue, Vec::new()) + } + + #[instrument(level = "debug", skip(self, node), ret)] + fn cat_projection( + &self, + node: HirId, + base_place: PlaceWithHirId<'tcx>, + ty: Ty<'tcx>, + kind: ProjectionKind, + ) -> PlaceWithHirId<'tcx> { + let place_ty = base_place.place.ty(); + let mut projections = base_place.place.projections; + + let node_ty = self.typeck_results.node_type(node); + // Opaque types can't have field projections, but we can instead convert + // the current place in-place (heh) to the hidden type, and then apply all + // follow up projections on that. + if node_ty != place_ty && matches!(place_ty.kind(), ty::Alias(ty::Opaque, ..)) { + projections.push(Projection { kind: ProjectionKind::OpaqueCast, ty: node_ty }); + } + projections.push(Projection { kind, ty }); + PlaceWithHirId::new(node, base_place.place.base_ty, base_place.place.base, projections) + } + + #[instrument(level = "debug", skip(self))] + fn cat_overloaded_place( + &self, + expr: &hir::Expr<'_>, + base: &hir::Expr<'_>, + ) -> McResult> { + // Reconstruct the output assuming it's a reference with the + // same region and mutability as the receiver. This holds for + // `Deref(Mut)::Deref(_mut)` and `Index(Mut)::index(_mut)`. + let place_ty = self.expr_ty(expr)?; + let base_ty = self.expr_ty_adjusted(base)?; + + let ty::Ref(region, _, mutbl) = *base_ty.kind() else { + span_bug!(expr.span, "cat_overloaded_place: base is not a reference"); + }; + let ref_ty = Ty::new_ref(self.tcx(), region, place_ty, mutbl); + + let base = self.cat_rvalue(expr.hir_id, ref_ty); + self.cat_deref(expr.hir_id, base) + } + + #[instrument(level = "debug", skip(self, node), ret)] + fn cat_deref( + &self, + node: HirId, + base_place: PlaceWithHirId<'tcx>, + ) -> McResult> { + let base_curr_ty = base_place.place.ty(); + let deref_ty = match base_curr_ty.builtin_deref(true) { + Some(mt) => mt.ty, + None => { + debug!("explicit deref of non-derefable type: {:?}", base_curr_ty); + return Err(self.tcx().dcx().span_delayed_bug( + self.tcx().hir().span(node), + "explicit deref of non-derefable type", + )); + } + }; + let mut projections = base_place.place.projections; + projections.push(Projection { kind: ProjectionKind::Deref, ty: deref_ty }); + + Ok(PlaceWithHirId::new(node, base_place.place.base_ty, base_place.place.base, projections)) + } + + fn cat_pattern( + &self, + place: PlaceWithHirId<'tcx>, + pat: &hir::Pat<'_>, + mut op: F, + ) -> McResult<()> + where + F: FnMut(&PlaceWithHirId<'tcx>, &hir::Pat<'_>), + { + self.cat_pattern_(place, pat, &mut op) + } + + /// Returns the variant index for an ADT used within a Struct or TupleStruct pattern + /// Here `pat_hir_id` is the HirId of the pattern itself. + fn variant_index_for_adt( + &self, + qpath: &hir::QPath<'_>, + pat_hir_id: HirId, + span: Span, + ) -> McResult { + let res = self.typeck_results.qpath_res(qpath, pat_hir_id); + let ty = self.typeck_results.node_type(pat_hir_id); + let ty::Adt(adt_def, _) = ty.kind() else { + return Err(self + .tcx() + .dcx() + .span_delayed_bug(span, "struct or tuple struct pattern not applied to an ADT")); + }; + + match res { + Res::Def(DefKind::Variant, variant_id) => Ok(adt_def.variant_index_with_id(variant_id)), + Res::Def(DefKind::Ctor(CtorOf::Variant, ..), variant_ctor_id) => { + Ok(adt_def.variant_index_with_ctor_id(variant_ctor_id)) + } + Res::Def(DefKind::Ctor(CtorOf::Struct, ..), _) + | Res::Def(DefKind::Struct | DefKind::Union | DefKind::TyAlias | DefKind::AssocTy, _) + | Res::SelfCtor(..) + | Res::SelfTyParam { .. } + | Res::SelfTyAlias { .. } => { + // Structs and Unions have only have one variant. + Ok(FIRST_VARIANT) + } + _ => bug!("expected ADT path, found={:?}", res), + } + } + + /// Returns the total number of fields in an ADT variant used within a pattern. + /// Here `pat_hir_id` is the HirId of the pattern itself. + fn total_fields_in_adt_variant( + &self, + pat_hir_id: HirId, + variant_index: VariantIdx, + span: Span, + ) -> McResult { + let ty = self.typeck_results.node_type(pat_hir_id); + match ty.kind() { + ty::Adt(adt_def, _) => Ok(adt_def.variant(variant_index).fields.len()), + _ => { + self.tcx() + .dcx() + .span_bug(span, "struct or tuple struct pattern not applied to an ADT"); + } + } + } + + /// Returns the total number of fields in a tuple used within a Tuple pattern. + /// Here `pat_hir_id` is the HirId of the pattern itself. + fn total_fields_in_tuple(&self, pat_hir_id: HirId, span: Span) -> McResult { + let ty = self.typeck_results.node_type(pat_hir_id); + match ty.kind() { + ty::Tuple(args) => Ok(args.len()), + _ => { + Err(self.tcx().dcx().span_delayed_bug(span, "tuple pattern not applied to a tuple")) + } + } + } + + /// Here, `place` is the `PlaceWithHirId` being matched and pat is the pattern it + /// is being matched against. + /// + /// In general, the way that this works is that we walk down the pattern, + /// constructing a `PlaceWithHirId` that represents the path that will be taken + /// to reach the value being matched. + #[instrument(skip(self, op), ret, level = "debug")] + fn cat_pattern_( + &self, + mut place_with_id: PlaceWithHirId<'tcx>, + pat: &hir::Pat<'_>, + op: &mut F, + ) -> McResult<()> + where + F: FnMut(&PlaceWithHirId<'tcx>, &hir::Pat<'_>), + { + // If (pattern) adjustments are active for this pattern, adjust the `PlaceWithHirId` correspondingly. + // `PlaceWithHirId`s are constructed differently from patterns. For example, in + // + // ``` + // match foo { + // &&Some(x, ) => { ... }, + // _ => { ... }, + // } + // ``` + // + // the pattern `&&Some(x,)` is represented as `Ref { Ref { TupleStruct }}`. To build the + // corresponding `PlaceWithHirId` we start with the `PlaceWithHirId` for `foo`, and then, by traversing the + // pattern, try to answer the question: given the address of `foo`, how is `x` reached? + // + // `&&Some(x,)` `place_foo` + // `&Some(x,)` `deref { place_foo}` + // `Some(x,)` `deref { deref { place_foo }}` + // `(x,)` `field0 { deref { deref { place_foo }}}` <- resulting place + // + // The above example has no adjustments. If the code were instead the (after adjustments, + // equivalent) version + // + // ``` + // match foo { + // Some(x, ) => { ... }, + // _ => { ... }, + // } + // ``` + // + // Then we see that to get the same result, we must start with + // `deref { deref { place_foo }}` instead of `place_foo` since the pattern is now `Some(x,)` + // and not `&&Some(x,)`, even though its assigned type is that of `&&Some(x,)`. + for _ in 0..self.typeck_results.pat_adjustments().get(pat.hir_id).map_or(0, |v| v.len()) { + debug!("applying adjustment to place_with_id={:?}", place_with_id); + place_with_id = self.cat_deref(pat.hir_id, place_with_id)?; + } + let place_with_id = place_with_id; // lose mutability + debug!("applied adjustment derefs to get place_with_id={:?}", place_with_id); + + // Invoke the callback, but only now, after the `place_with_id` has adjusted. + // + // To see that this makes sense, consider `match &Some(3) { Some(x) => { ... }}`. In that + // case, the initial `place_with_id` will be that for `&Some(3)` and the pattern is `Some(x)`. We + // don't want to call `op` with these incompatible values. As written, what happens instead + // is that `op` is called with the adjusted place (that for `*&Some(3)`) and the pattern + // `Some(x)` (which matches). Recursing once more, `*&Some(3)` and the pattern `Some(x)` + // result in the place `Downcast(*&Some(3)).0` associated to `x` and invoke `op` with + // that (where the `ref` on `x` is implied). + op(&place_with_id, pat); + + match pat.kind { + PatKind::Tuple(subpats, dots_pos) => { + // (p1, ..., pN) + let total_fields = self.total_fields_in_tuple(pat.hir_id, pat.span)?; + + for (i, subpat) in subpats.iter().enumerate_and_adjust(total_fields, dots_pos) { + let subpat_ty = self.pat_ty_adjusted(subpat)?; + let projection_kind = + ProjectionKind::Field(FieldIdx::from_usize(i), FIRST_VARIANT); + let sub_place = self.cat_projection( + pat.hir_id, + place_with_id.clone(), + subpat_ty, + projection_kind, + ); + self.cat_pattern_(sub_place, subpat, op)?; + } + } + + PatKind::TupleStruct(ref qpath, subpats, dots_pos) => { + // S(p1, ..., pN) + let variant_index = self.variant_index_for_adt(qpath, pat.hir_id, pat.span)?; + let total_fields = + self.total_fields_in_adt_variant(pat.hir_id, variant_index, pat.span)?; + + for (i, subpat) in subpats.iter().enumerate_and_adjust(total_fields, dots_pos) { + let subpat_ty = self.pat_ty_adjusted(subpat)?; + let projection_kind = + ProjectionKind::Field(FieldIdx::from_usize(i), variant_index); + let sub_place = self.cat_projection( + pat.hir_id, + place_with_id.clone(), + subpat_ty, + projection_kind, + ); + self.cat_pattern_(sub_place, subpat, op)?; + } + } + + PatKind::Struct(ref qpath, field_pats, _) => { + // S { f1: p1, ..., fN: pN } + + let variant_index = self.variant_index_for_adt(qpath, pat.hir_id, pat.span)?; + + for fp in field_pats { + let field_ty = self.pat_ty_adjusted(fp.pat)?; + let field_index = self + .typeck_results + .field_indices() + .get(fp.hir_id) + .cloned() + .expect("no index for a field"); + + let field_place = self.cat_projection( + pat.hir_id, + place_with_id.clone(), + field_ty, + ProjectionKind::Field(field_index, variant_index), + ); + self.cat_pattern_(field_place, fp.pat, op)?; + } + } + + PatKind::Or(pats) => { + for pat in pats { + self.cat_pattern_(place_with_id.clone(), pat, op)?; + } + } + + PatKind::Binding(.., Some(subpat)) => { + self.cat_pattern_(place_with_id, subpat, op)?; + } + + PatKind::Box(subpat) | PatKind::Ref(subpat, _) => { + // box p1, &p1, &mut p1. we can ignore the mutability of + // PatKind::Ref since that information is already contained + // in the type. + let subplace = self.cat_deref(pat.hir_id, place_with_id)?; + self.cat_pattern_(subplace, subpat, op)?; + } + PatKind::Deref(subpat) => { + let mutable = self.typeck_results.pat_has_ref_mut_binding(subpat); + let mutability = if mutable { hir::Mutability::Mut } else { hir::Mutability::Not }; + let re_erased = self.tcx().lifetimes.re_erased; + let ty = self.pat_ty_adjusted(subpat)?; + let ty = Ty::new_ref(self.tcx(), re_erased, ty, mutability); + // A deref pattern generates a temporary. + let place = self.cat_rvalue(pat.hir_id, ty); + self.cat_pattern_(place, subpat, op)?; + } + + PatKind::Slice(before, ref slice, after) => { + let Some(element_ty) = place_with_id.place.ty().builtin_index() else { + debug!("explicit index of non-indexable type {:?}", place_with_id); + return Err(self + .tcx() + .dcx() + .span_delayed_bug(pat.span, "explicit index of non-indexable type")); + }; + let elt_place = self.cat_projection( + pat.hir_id, + place_with_id.clone(), + element_ty, + ProjectionKind::Index, + ); + for before_pat in before { + self.cat_pattern_(elt_place.clone(), before_pat, op)?; + } + if let Some(slice_pat) = *slice { + let slice_pat_ty = self.pat_ty_adjusted(slice_pat)?; + let slice_place = self.cat_projection( + pat.hir_id, + place_with_id, + slice_pat_ty, + ProjectionKind::Subslice, + ); + self.cat_pattern_(slice_place, slice_pat, op)?; + } + for after_pat in after { + self.cat_pattern_(elt_place.clone(), after_pat, op)?; + } + } + + PatKind::Path(_) + | PatKind::Binding(.., None) + | PatKind::Lit(..) + | PatKind::Range(..) + | PatKind::Never + | PatKind::Wild + | PatKind::Err(_) => { + // always ok + } + } + + Ok(()) } } diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index e270e5895054b..296560dd5baba 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -32,7 +32,6 @@ mod fallback; mod fn_ctxt; mod gather_locals; mod intrinsicck; -mod mem_categorization; mod method; mod op; mod pat; diff --git a/compiler/rustc_hir_typeck/src/mem_categorization.rs b/compiler/rustc_hir_typeck/src/mem_categorization.rs deleted file mode 100644 index acd11d352bf53..0000000000000 --- a/compiler/rustc_hir_typeck/src/mem_categorization.rs +++ /dev/null @@ -1,790 +0,0 @@ -//! # Categorization -//! -//! The job of the categorization module is to analyze an expression to -//! determine what kind of memory is used in evaluating it (for example, -//! where dereferences occur and what kind of pointer is dereferenced; -//! whether the memory is mutable, etc.). -//! -//! Categorization effectively transforms all of our expressions into -//! expressions of the following forms (the actual enum has many more -//! possibilities, naturally, but they are all variants of these base -//! forms): -//! ```ignore (not-rust) -//! E = rvalue // some computed rvalue -//! | x // address of a local variable or argument -//! | *E // deref of a ptr -//! | E.comp // access to an interior component -//! ``` -//! Imagine a routine ToAddr(Expr) that evaluates an expression and returns an -//! address where the result is to be found. If Expr is a place, then this -//! is the address of the place. If `Expr` is an rvalue, this is the address of -//! some temporary spot in memory where the result is stored. -//! -//! Now, `cat_expr()` classifies the expression `Expr` and the address `A = ToAddr(Expr)` -//! as follows: -//! -//! - `cat`: what kind of expression was this? This is a subset of the -//! full expression forms which only includes those that we care about -//! for the purpose of the analysis. -//! - `mutbl`: mutability of the address `A`. -//! - `ty`: the type of data found at the address `A`. -//! -//! The resulting categorization tree differs somewhat from the expressions -//! themselves. For example, auto-derefs are explicit. Also, an index `a[b]` is -//! decomposed into two operations: a dereference to reach the array data and -//! then an index to jump forward to the relevant item. -//! -//! ## By-reference upvars -//! -//! One part of the codegen which may be non-obvious is that we translate -//! closure upvars into the dereference of a borrowed pointer; this more closely -//! resembles the runtime codegen. So, for example, if we had: -//! -//! let mut x = 3; -//! let y = 5; -//! let inc = || x += y; -//! -//! Then when we categorize `x` (*within* the closure) we would yield a -//! result of `*x'`, effectively, where `x'` is a `Categorization::Upvar` reference -//! tied to `x`. The type of `x'` will be a borrowed pointer. - -use rustc_middle::hir::place::*; -use rustc_middle::ty::adjustment; -use rustc_middle::ty::fold::TypeFoldable; -use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt}; - -use rustc_data_structures::fx::FxIndexMap; -use rustc_hir as hir; -use rustc_hir::def::{CtorOf, DefKind, Res}; -use rustc_hir::def_id::LocalDefId; -use rustc_hir::pat_util::EnumerateAndAdjustIterator; -use rustc_hir::{HirId, PatKind}; -use rustc_infer::infer::InferCtxt; -use rustc_span::Span; -use rustc_target::abi::{FieldIdx, VariantIdx, FIRST_VARIANT}; -use rustc_trait_selection::infer::InferCtxtExt; - -pub(crate) trait HirNode { - fn hir_id(&self) -> HirId; -} - -impl HirNode for hir::Expr<'_> { - fn hir_id(&self) -> HirId { - self.hir_id - } -} - -impl HirNode for hir::Pat<'_> { - fn hir_id(&self) -> HirId { - self.hir_id - } -} - -#[derive(Clone)] -pub(crate) struct MemCategorizationContext<'a, 'tcx> { - pub(crate) typeck_results: &'a ty::TypeckResults<'tcx>, - infcx: &'a InferCtxt<'tcx>, - param_env: ty::ParamEnv<'tcx>, - body_owner: LocalDefId, - upvars: Option<&'tcx FxIndexMap>, -} - -pub(crate) type McResult = Result; - -impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> { - /// Creates a `MemCategorizationContext`. - pub(crate) fn new( - infcx: &'a InferCtxt<'tcx>, - param_env: ty::ParamEnv<'tcx>, - body_owner: LocalDefId, - typeck_results: &'a ty::TypeckResults<'tcx>, - ) -> MemCategorizationContext<'a, 'tcx> { - MemCategorizationContext { - typeck_results, - infcx, - param_env, - body_owner, - upvars: infcx.tcx.upvars_mentioned(body_owner), - } - } - - pub(crate) fn tcx(&self) -> TyCtxt<'tcx> { - self.infcx.tcx - } - - pub(crate) fn type_is_copy_modulo_regions(&self, ty: Ty<'tcx>) -> bool { - self.infcx.type_is_copy_modulo_regions(self.param_env, ty) - } - - fn resolve_vars_if_possible(&self, value: T) -> T - where - T: TypeFoldable>, - { - self.infcx.resolve_vars_if_possible(value) - } - - fn is_tainted_by_errors(&self) -> bool { - self.infcx.tainted_by_errors().is_some() - } - - fn resolve_type_vars_or_error(&self, id: HirId, ty: Option>) -> McResult> { - match ty { - Some(ty) => { - let ty = self.resolve_vars_if_possible(ty); - if ty.references_error() { - debug!("resolve_type_vars_or_error: error from {:?}", ty); - Err(()) - } else if ty.is_ty_var() { - debug!("resolve_type_vars_or_error: infer var from {:?}", ty); - self.tcx() - .dcx() - .span_delayed_bug(self.tcx().hir().span(id), "encountered type variable"); - Err(()) - } else { - Ok(ty) - } - } - // FIXME - None if self.is_tainted_by_errors() => Err(()), - None => { - bug!( - "no type for node {} in mem_categorization", - self.tcx().hir().node_to_string(id) - ); - } - } - } - - pub(crate) fn node_ty(&self, hir_id: HirId) -> McResult> { - self.resolve_type_vars_or_error(hir_id, self.typeck_results.node_type_opt(hir_id)) - } - - fn expr_ty(&self, expr: &hir::Expr<'_>) -> McResult> { - self.resolve_type_vars_or_error(expr.hir_id, self.typeck_results.expr_ty_opt(expr)) - } - - pub(crate) fn expr_ty_adjusted(&self, expr: &hir::Expr<'_>) -> McResult> { - self.resolve_type_vars_or_error(expr.hir_id, self.typeck_results.expr_ty_adjusted_opt(expr)) - } - - /// Returns the type of value that this pattern matches against. - /// Some non-obvious cases: - /// - /// - a `ref x` binding matches against a value of type `T` and gives - /// `x` the type `&T`; we return `T`. - /// - a pattern with implicit derefs (thanks to default binding - /// modes #42640) may look like `Some(x)` but in fact have - /// implicit deref patterns attached (e.g., it is really - /// `&Some(x)`). In that case, we return the "outermost" type - /// (e.g., `&Option`). - pub(crate) fn pat_ty_adjusted(&self, pat: &hir::Pat<'_>) -> McResult> { - // Check for implicit `&` types wrapping the pattern; note - // that these are never attached to binding patterns, so - // actually this is somewhat "disjoint" from the code below - // that aims to account for `ref x`. - if let Some(vec) = self.typeck_results.pat_adjustments().get(pat.hir_id) { - if let Some(first_ty) = vec.first() { - debug!("pat_ty(pat={:?}) found adjusted ty `{:?}`", pat, first_ty); - return Ok(*first_ty); - } - } - - self.pat_ty_unadjusted(pat) - } - - /// Like `pat_ty`, but ignores implicit `&` patterns. - #[instrument(level = "debug", skip(self), ret)] - fn pat_ty_unadjusted(&self, pat: &hir::Pat<'_>) -> McResult> { - let base_ty = self.node_ty(pat.hir_id)?; - trace!(?base_ty); - - // This code detects whether we are looking at a `ref x`, - // and if so, figures out what the type *being borrowed* is. - match pat.kind { - PatKind::Binding(..) => { - let bm = *self - .typeck_results - .pat_binding_modes() - .get(pat.hir_id) - .expect("missing binding mode"); - - if matches!(bm.0, hir::ByRef::Yes(_)) { - // a bind-by-ref means that the base_ty will be the type of the ident itself, - // but what we want here is the type of the underlying value being borrowed. - // So peel off one-level, turning the &T into T. - match base_ty.builtin_deref(false) { - Some(ty) => Ok(ty), - None => { - debug!("By-ref binding of non-derefable type"); - self.tcx() - .dcx() - .span_delayed_bug(pat.span, "by-ref binding of non-derefable type"); - Err(()) - } - } - } else { - Ok(base_ty) - } - } - _ => Ok(base_ty), - } - } - - pub(crate) fn cat_expr(&self, expr: &hir::Expr<'_>) -> McResult> { - // This recursion helper avoids going through *too many* - // adjustments, since *only* non-overloaded deref recurses. - fn helper<'a, 'tcx>( - mc: &MemCategorizationContext<'a, 'tcx>, - expr: &hir::Expr<'_>, - adjustments: &[adjustment::Adjustment<'tcx>], - ) -> McResult> { - match adjustments.split_last() { - None => mc.cat_expr_unadjusted(expr), - Some((adjustment, previous)) => { - mc.cat_expr_adjusted_with(expr, || helper(mc, expr, previous), adjustment) - } - } - } - - helper(self, expr, self.typeck_results.expr_adjustments(expr)) - } - - pub(crate) fn cat_expr_adjusted( - &self, - expr: &hir::Expr<'_>, - previous: PlaceWithHirId<'tcx>, - adjustment: &adjustment::Adjustment<'tcx>, - ) -> McResult> { - self.cat_expr_adjusted_with(expr, || Ok(previous), adjustment) - } - - #[instrument(level = "debug", skip(self, previous))] - fn cat_expr_adjusted_with( - &self, - expr: &hir::Expr<'_>, - previous: F, - adjustment: &adjustment::Adjustment<'tcx>, - ) -> McResult> - where - F: FnOnce() -> McResult>, - { - let target = self.resolve_vars_if_possible(adjustment.target); - match adjustment.kind { - adjustment::Adjust::Deref(overloaded) => { - // Equivalent to *expr or something similar. - let base = if let Some(deref) = overloaded { - let ref_ty = Ty::new_ref(self.tcx(), deref.region, target, deref.mutbl); - self.cat_rvalue(expr.hir_id, ref_ty) - } else { - previous()? - }; - self.cat_deref(expr, base) - } - - adjustment::Adjust::NeverToAny - | adjustment::Adjust::Pointer(_) - | adjustment::Adjust::Borrow(_) - | adjustment::Adjust::DynStar => { - // Result is an rvalue. - Ok(self.cat_rvalue(expr.hir_id, target)) - } - } - } - - #[instrument(level = "debug", skip(self), ret)] - pub(crate) fn cat_expr_unadjusted( - &self, - expr: &hir::Expr<'_>, - ) -> McResult> { - let expr_ty = self.expr_ty(expr)?; - match expr.kind { - hir::ExprKind::Unary(hir::UnOp::Deref, e_base) => { - if self.typeck_results.is_method_call(expr) { - self.cat_overloaded_place(expr, e_base) - } else { - let base = self.cat_expr(e_base)?; - self.cat_deref(expr, base) - } - } - - hir::ExprKind::Field(base, _) => { - let base = self.cat_expr(base)?; - debug!(?base); - - let field_idx = self - .typeck_results - .field_indices() - .get(expr.hir_id) - .cloned() - .expect("Field index not found"); - - Ok(self.cat_projection( - expr, - base, - expr_ty, - ProjectionKind::Field(field_idx, FIRST_VARIANT), - )) - } - - hir::ExprKind::Index(base, _, _) => { - if self.typeck_results.is_method_call(expr) { - // If this is an index implemented by a method call, then it - // will include an implicit deref of the result. - // The call to index() returns a `&T` value, which - // is an rvalue. That is what we will be - // dereferencing. - self.cat_overloaded_place(expr, base) - } else { - let base = self.cat_expr(base)?; - Ok(self.cat_projection(expr, base, expr_ty, ProjectionKind::Index)) - } - } - - hir::ExprKind::Path(ref qpath) => { - let res = self.typeck_results.qpath_res(qpath, expr.hir_id); - self.cat_res(expr.hir_id, expr.span, expr_ty, res) - } - - hir::ExprKind::Type(e, _) => self.cat_expr(e), - - hir::ExprKind::AddrOf(..) - | hir::ExprKind::Call(..) - | hir::ExprKind::Assign(..) - | hir::ExprKind::AssignOp(..) - | hir::ExprKind::Closure { .. } - | hir::ExprKind::Ret(..) - | hir::ExprKind::Become(..) - | hir::ExprKind::Unary(..) - | hir::ExprKind::Yield(..) - | hir::ExprKind::MethodCall(..) - | hir::ExprKind::Cast(..) - | hir::ExprKind::DropTemps(..) - | hir::ExprKind::Array(..) - | hir::ExprKind::If(..) - | hir::ExprKind::Tup(..) - | hir::ExprKind::Binary(..) - | hir::ExprKind::Block(..) - | hir::ExprKind::Let(..) - | hir::ExprKind::Loop(..) - | hir::ExprKind::Match(..) - | hir::ExprKind::Lit(..) - | hir::ExprKind::ConstBlock(..) - | hir::ExprKind::Break(..) - | hir::ExprKind::Continue(..) - | hir::ExprKind::Struct(..) - | hir::ExprKind::Repeat(..) - | hir::ExprKind::InlineAsm(..) - | hir::ExprKind::OffsetOf(..) - | hir::ExprKind::Err(_) => Ok(self.cat_rvalue(expr.hir_id, expr_ty)), - } - } - - #[instrument(level = "debug", skip(self, span), ret)] - pub(crate) fn cat_res( - &self, - hir_id: HirId, - span: Span, - expr_ty: Ty<'tcx>, - res: Res, - ) -> McResult> { - match res { - Res::Def( - DefKind::Ctor(..) - | DefKind::Const - | DefKind::ConstParam - | DefKind::AssocConst - | DefKind::Fn - | DefKind::AssocFn, - _, - ) - | Res::SelfCtor(..) => Ok(self.cat_rvalue(hir_id, expr_ty)), - - Res::Def(DefKind::Static { .. }, _) => { - Ok(PlaceWithHirId::new(hir_id, expr_ty, PlaceBase::StaticItem, Vec::new())) - } - - Res::Local(var_id) => { - if self.upvars.is_some_and(|upvars| upvars.contains_key(&var_id)) { - self.cat_upvar(hir_id, var_id) - } else { - Ok(PlaceWithHirId::new(hir_id, expr_ty, PlaceBase::Local(var_id), Vec::new())) - } - } - - def => span_bug!(span, "unexpected definition in memory categorization: {:?}", def), - } - } - - /// Categorize an upvar. - /// - /// Note: the actual upvar access contains invisible derefs of closure - /// environment and upvar reference as appropriate. Only regionck cares - /// about these dereferences, so we let it compute them as needed. - #[instrument(level = "debug", skip(self), ret)] - fn cat_upvar(&self, hir_id: HirId, var_id: HirId) -> McResult> { - let closure_expr_def_id = self.body_owner; - - let upvar_id = ty::UpvarId { - var_path: ty::UpvarPath { hir_id: var_id }, - closure_expr_id: closure_expr_def_id, - }; - let var_ty = self.node_ty(var_id)?; - - Ok(PlaceWithHirId::new(hir_id, var_ty, PlaceBase::Upvar(upvar_id), Vec::new())) - } - - #[instrument(level = "debug", skip(self), ret)] - pub(crate) fn cat_rvalue(&self, hir_id: HirId, expr_ty: Ty<'tcx>) -> PlaceWithHirId<'tcx> { - PlaceWithHirId::new(hir_id, expr_ty, PlaceBase::Rvalue, Vec::new()) - } - - #[instrument(level = "debug", skip(self, node), ret)] - pub(crate) fn cat_projection( - &self, - node: &N, - base_place: PlaceWithHirId<'tcx>, - ty: Ty<'tcx>, - kind: ProjectionKind, - ) -> PlaceWithHirId<'tcx> { - let place_ty = base_place.place.ty(); - let mut projections = base_place.place.projections; - - let node_ty = self.typeck_results.node_type(node.hir_id()); - // Opaque types can't have field projections, but we can instead convert - // the current place in-place (heh) to the hidden type, and then apply all - // follow up projections on that. - if node_ty != place_ty && matches!(place_ty.kind(), ty::Alias(ty::Opaque, ..)) { - projections.push(Projection { kind: ProjectionKind::OpaqueCast, ty: node_ty }); - } - projections.push(Projection { kind, ty }); - PlaceWithHirId::new( - node.hir_id(), - base_place.place.base_ty, - base_place.place.base, - projections, - ) - } - - #[instrument(level = "debug", skip(self))] - fn cat_overloaded_place( - &self, - expr: &hir::Expr<'_>, - base: &hir::Expr<'_>, - ) -> McResult> { - // Reconstruct the output assuming it's a reference with the - // same region and mutability as the receiver. This holds for - // `Deref(Mut)::Deref(_mut)` and `Index(Mut)::index(_mut)`. - let place_ty = self.expr_ty(expr)?; - let base_ty = self.expr_ty_adjusted(base)?; - - let ty::Ref(region, _, mutbl) = *base_ty.kind() else { - span_bug!(expr.span, "cat_overloaded_place: base is not a reference"); - }; - let ref_ty = Ty::new_ref(self.tcx(), region, place_ty, mutbl); - - let base = self.cat_rvalue(expr.hir_id, ref_ty); - self.cat_deref(expr, base) - } - - #[instrument(level = "debug", skip(self, node), ret)] - fn cat_deref( - &self, - node: &impl HirNode, - base_place: PlaceWithHirId<'tcx>, - ) -> McResult> { - let base_curr_ty = base_place.place.ty(); - let deref_ty = match base_curr_ty.builtin_deref(true) { - Some(pointee_ty) => pointee_ty, - None => { - debug!("explicit deref of non-derefable type: {:?}", base_curr_ty); - self.tcx().dcx().span_delayed_bug( - self.tcx().hir().span(node.hir_id()), - "explicit deref of non-derefable type", - ); - return Err(()); - } - }; - let mut projections = base_place.place.projections; - projections.push(Projection { kind: ProjectionKind::Deref, ty: deref_ty }); - - Ok(PlaceWithHirId::new( - node.hir_id(), - base_place.place.base_ty, - base_place.place.base, - projections, - )) - } - - pub(crate) fn cat_pattern( - &self, - place: PlaceWithHirId<'tcx>, - pat: &hir::Pat<'_>, - mut op: F, - ) -> McResult<()> - where - F: FnMut(&PlaceWithHirId<'tcx>, &hir::Pat<'_>), - { - self.cat_pattern_(place, pat, &mut op) - } - - /// Returns the variant index for an ADT used within a Struct or TupleStruct pattern - /// Here `pat_hir_id` is the HirId of the pattern itself. - fn variant_index_for_adt( - &self, - qpath: &hir::QPath<'_>, - pat_hir_id: HirId, - span: Span, - ) -> McResult { - let res = self.typeck_results.qpath_res(qpath, pat_hir_id); - let ty = self.typeck_results.node_type(pat_hir_id); - let ty::Adt(adt_def, _) = ty.kind() else { - self.tcx() - .dcx() - .span_delayed_bug(span, "struct or tuple struct pattern not applied to an ADT"); - return Err(()); - }; - - match res { - Res::Def(DefKind::Variant, variant_id) => Ok(adt_def.variant_index_with_id(variant_id)), - Res::Def(DefKind::Ctor(CtorOf::Variant, ..), variant_ctor_id) => { - Ok(adt_def.variant_index_with_ctor_id(variant_ctor_id)) - } - Res::Def(DefKind::Ctor(CtorOf::Struct, ..), _) - | Res::Def(DefKind::Struct | DefKind::Union | DefKind::TyAlias | DefKind::AssocTy, _) - | Res::SelfCtor(..) - | Res::SelfTyParam { .. } - | Res::SelfTyAlias { .. } => { - // Structs and Unions have only have one variant. - Ok(FIRST_VARIANT) - } - _ => bug!("expected ADT path, found={:?}", res), - } - } - - /// Returns the total number of fields in an ADT variant used within a pattern. - /// Here `pat_hir_id` is the HirId of the pattern itself. - fn total_fields_in_adt_variant( - &self, - pat_hir_id: HirId, - variant_index: VariantIdx, - span: Span, - ) -> McResult { - let ty = self.typeck_results.node_type(pat_hir_id); - match ty.kind() { - ty::Adt(adt_def, _) => Ok(adt_def.variant(variant_index).fields.len()), - _ => { - self.tcx() - .dcx() - .span_bug(span, "struct or tuple struct pattern not applied to an ADT"); - } - } - } - - /// Returns the total number of fields in a tuple used within a Tuple pattern. - /// Here `pat_hir_id` is the HirId of the pattern itself. - fn total_fields_in_tuple(&self, pat_hir_id: HirId, span: Span) -> McResult { - let ty = self.typeck_results.node_type(pat_hir_id); - match ty.kind() { - ty::Tuple(args) => Ok(args.len()), - _ => { - self.tcx().dcx().span_delayed_bug(span, "tuple pattern not applied to a tuple"); - Err(()) - } - } - } - - /// Here, `place` is the `PlaceWithHirId` being matched and pat is the pattern it - /// is being matched against. - /// - /// In general, the way that this works is that we walk down the pattern, - /// constructing a `PlaceWithHirId` that represents the path that will be taken - /// to reach the value being matched. - #[instrument(skip(self, op), ret, level = "debug")] - fn cat_pattern_( - &self, - mut place_with_id: PlaceWithHirId<'tcx>, - pat: &hir::Pat<'_>, - op: &mut F, - ) -> McResult<()> - where - F: FnMut(&PlaceWithHirId<'tcx>, &hir::Pat<'_>), - { - // If (pattern) adjustments are active for this pattern, adjust the `PlaceWithHirId` correspondingly. - // `PlaceWithHirId`s are constructed differently from patterns. For example, in - // - // ``` - // match foo { - // &&Some(x, ) => { ... }, - // _ => { ... }, - // } - // ``` - // - // the pattern `&&Some(x,)` is represented as `Ref { Ref { TupleStruct }}`. To build the - // corresponding `PlaceWithHirId` we start with the `PlaceWithHirId` for `foo`, and then, by traversing the - // pattern, try to answer the question: given the address of `foo`, how is `x` reached? - // - // `&&Some(x,)` `place_foo` - // `&Some(x,)` `deref { place_foo}` - // `Some(x,)` `deref { deref { place_foo }}` - // `(x,)` `field0 { deref { deref { place_foo }}}` <- resulting place - // - // The above example has no adjustments. If the code were instead the (after adjustments, - // equivalent) version - // - // ``` - // match foo { - // Some(x, ) => { ... }, - // _ => { ... }, - // } - // ``` - // - // Then we see that to get the same result, we must start with - // `deref { deref { place_foo }}` instead of `place_foo` since the pattern is now `Some(x,)` - // and not `&&Some(x,)`, even though its assigned type is that of `&&Some(x,)`. - for _ in 0..self.typeck_results.pat_adjustments().get(pat.hir_id).map_or(0, |v| v.len()) { - debug!("applying adjustment to place_with_id={:?}", place_with_id); - place_with_id = self.cat_deref(pat, place_with_id)?; - } - let place_with_id = place_with_id; // lose mutability - debug!("applied adjustment derefs to get place_with_id={:?}", place_with_id); - - // Invoke the callback, but only now, after the `place_with_id` has adjusted. - // - // To see that this makes sense, consider `match &Some(3) { Some(x) => { ... }}`. In that - // case, the initial `place_with_id` will be that for `&Some(3)` and the pattern is `Some(x)`. We - // don't want to call `op` with these incompatible values. As written, what happens instead - // is that `op` is called with the adjusted place (that for `*&Some(3)`) and the pattern - // `Some(x)` (which matches). Recursing once more, `*&Some(3)` and the pattern `Some(x)` - // result in the place `Downcast(*&Some(3)).0` associated to `x` and invoke `op` with - // that (where the `ref` on `x` is implied). - op(&place_with_id, pat); - - match pat.kind { - PatKind::Tuple(subpats, dots_pos) => { - // (p1, ..., pN) - let total_fields = self.total_fields_in_tuple(pat.hir_id, pat.span)?; - - for (i, subpat) in subpats.iter().enumerate_and_adjust(total_fields, dots_pos) { - let subpat_ty = self.pat_ty_adjusted(subpat)?; - let projection_kind = - ProjectionKind::Field(FieldIdx::from_usize(i), FIRST_VARIANT); - let sub_place = - self.cat_projection(pat, place_with_id.clone(), subpat_ty, projection_kind); - self.cat_pattern_(sub_place, subpat, op)?; - } - } - - PatKind::TupleStruct(ref qpath, subpats, dots_pos) => { - // S(p1, ..., pN) - let variant_index = self.variant_index_for_adt(qpath, pat.hir_id, pat.span)?; - let total_fields = - self.total_fields_in_adt_variant(pat.hir_id, variant_index, pat.span)?; - - for (i, subpat) in subpats.iter().enumerate_and_adjust(total_fields, dots_pos) { - let subpat_ty = self.pat_ty_adjusted(subpat)?; - let projection_kind = - ProjectionKind::Field(FieldIdx::from_usize(i), variant_index); - let sub_place = - self.cat_projection(pat, place_with_id.clone(), subpat_ty, projection_kind); - self.cat_pattern_(sub_place, subpat, op)?; - } - } - - PatKind::Struct(ref qpath, field_pats, _) => { - // S { f1: p1, ..., fN: pN } - - let variant_index = self.variant_index_for_adt(qpath, pat.hir_id, pat.span)?; - - for fp in field_pats { - let field_ty = self.pat_ty_adjusted(fp.pat)?; - let field_index = self - .typeck_results - .field_indices() - .get(fp.hir_id) - .cloned() - .expect("no index for a field"); - - let field_place = self.cat_projection( - pat, - place_with_id.clone(), - field_ty, - ProjectionKind::Field(field_index, variant_index), - ); - self.cat_pattern_(field_place, fp.pat, op)?; - } - } - - PatKind::Or(pats) => { - for pat in pats { - self.cat_pattern_(place_with_id.clone(), pat, op)?; - } - } - - PatKind::Binding(.., Some(subpat)) => { - self.cat_pattern_(place_with_id, subpat, op)?; - } - - PatKind::Box(subpat) | PatKind::Ref(subpat, _) => { - // box p1, &p1, &mut p1. we can ignore the mutability of - // PatKind::Ref since that information is already contained - // in the type. - let subplace = self.cat_deref(pat, place_with_id)?; - self.cat_pattern_(subplace, subpat, op)?; - } - PatKind::Deref(subpat) => { - let mutable = self.typeck_results.pat_has_ref_mut_binding(subpat); - let mutability = if mutable { hir::Mutability::Mut } else { hir::Mutability::Not }; - let re_erased = self.tcx().lifetimes.re_erased; - let ty = self.pat_ty_adjusted(subpat)?; - let ty = Ty::new_ref(self.tcx(), re_erased, ty, mutability); - // A deref pattern generates a temporary. - let place = self.cat_rvalue(pat.hir_id, ty); - self.cat_pattern_(place, subpat, op)?; - } - - PatKind::Slice(before, ref slice, after) => { - let Some(element_ty) = place_with_id.place.ty().builtin_index() else { - debug!("explicit index of non-indexable type {:?}", place_with_id); - self.tcx() - .dcx() - .span_delayed_bug(pat.span, "explicit index of non-indexable type"); - return Err(()); - }; - let elt_place = self.cat_projection( - pat, - place_with_id.clone(), - element_ty, - ProjectionKind::Index, - ); - for before_pat in before { - self.cat_pattern_(elt_place.clone(), before_pat, op)?; - } - if let Some(slice_pat) = *slice { - let slice_pat_ty = self.pat_ty_adjusted(slice_pat)?; - let slice_place = self.cat_projection( - pat, - place_with_id, - slice_pat_ty, - ProjectionKind::Subslice, - ); - self.cat_pattern_(slice_place, slice_pat, op)?; - } - for after_pat in after { - self.cat_pattern_(elt_place.clone(), after_pat, op)?; - } - } - - PatKind::Path(_) - | PatKind::Binding(.., None) - | PatKind::Lit(..) - | PatKind::Range(..) - | PatKind::Never - | PatKind::Wild - | PatKind::Err(_) => { - // always ok - } - } - - Ok(()) - } -} diff --git a/src/tools/clippy/clippy_lints/src/operators/assign_op_pattern.rs b/src/tools/clippy/clippy_lints/src/operators/assign_op_pattern.rs index 435eb9048f587..8effe6ab54db5 100644 --- a/src/tools/clippy/clippy_lints/src/operators/assign_op_pattern.rs +++ b/src/tools/clippy/clippy_lints/src/operators/assign_op_pattern.rs @@ -120,7 +120,7 @@ fn imm_borrows_in_expr(cx: &LateContext<'_>, e: &hir::Expr<'_>) -> HirIdSet { let mut s = S(HirIdSet::default()); let infcx = cx.tcx.infer_ctxt().build(); - let mut v = ExprUseVisitor::new( + let v = ExprUseVisitor::new( &mut s, &infcx, cx.tcx.hir().body_owner_def_id(cx.enclosing_body.unwrap()), @@ -152,7 +152,7 @@ fn mut_borrows_in_expr(cx: &LateContext<'_>, e: &hir::Expr<'_>) -> HirIdSet { let mut s = S(HirIdSet::default()); let infcx = cx.tcx.infer_ctxt().build(); - let mut v = ExprUseVisitor::new( + let v = ExprUseVisitor::new( &mut s, &infcx, cx.tcx.hir().body_owner_def_id(cx.enclosing_body.unwrap()), diff --git a/src/tools/clippy/clippy_lints/src/unwrap.rs b/src/tools/clippy/clippy_lints/src/unwrap.rs index 2622abd59cbd6..6aec3dfa45cbb 100644 --- a/src/tools/clippy/clippy_lints/src/unwrap.rs +++ b/src/tools/clippy/clippy_lints/src/unwrap.rs @@ -253,7 +253,7 @@ impl<'a, 'tcx> UnwrappableVariablesVisitor<'a, 'tcx> { }; let infcx = self.cx.tcx.infer_ctxt().build(); - let mut vis = ExprUseVisitor::new( + let vis = ExprUseVisitor::new( &mut delegate, &infcx, cond.hir_id.owner.def_id, From 72eccf2c6ed640518245c986bed1a26648713250 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 8 May 2024 13:27:00 -0400 Subject: [PATCH 123/179] Remove unncessary mut ref --- .../rustc_hir_typeck/src/expr_use_visitor.rs | 40 ++++++++++++++++++- 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs index 5b99b547c24d7..b8fed4bc688ed 100644 --- a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs +++ b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs @@ -86,6 +86,42 @@ pub trait Delegate<'tcx> { ); } +impl<'tcx, D: Delegate<'tcx>> Delegate<'tcx> for &mut D { + fn consume(&mut self, place_with_id: &PlaceWithHirId<'tcx>, diag_expr_id: HirId) { + (**self).consume(place_with_id, diag_expr_id) + } + + fn borrow( + &mut self, + place_with_id: &PlaceWithHirId<'tcx>, + diag_expr_id: HirId, + bk: ty::BorrowKind, + ) { + (**self).borrow(place_with_id, diag_expr_id, bk) + } + + fn copy(&mut self, place_with_id: &PlaceWithHirId<'tcx>, diag_expr_id: HirId) { + (**self).copy(place_with_id, diag_expr_id) + } + + fn mutate(&mut self, assignee_place: &PlaceWithHirId<'tcx>, diag_expr_id: HirId) { + (**self).mutate(assignee_place, diag_expr_id) + } + + fn bind(&mut self, binding_place: &PlaceWithHirId<'tcx>, diag_expr_id: HirId) { + (**self).bind(binding_place, diag_expr_id) + } + + fn fake_read( + &mut self, + place_with_id: &PlaceWithHirId<'tcx>, + cause: FakeReadCause, + diag_expr_id: HirId, + ) { + (**self).fake_read(place_with_id, cause, diag_expr_id) + } +} + /// The ExprUseVisitor type /// /// This is the code that actually walks the tree. @@ -95,7 +131,7 @@ pub struct ExprUseVisitor<'a, 'tcx, D: Delegate<'tcx>> { param_env: ty::ParamEnv<'tcx>, upvars: Option<&'tcx FxIndexMap>, body_owner: LocalDefId, - delegate: RefCell<&'a mut D>, + delegate: RefCell, } /// If the MC results in an error, it's because the type check @@ -124,7 +160,7 @@ impl<'a, 'tcx, D: Delegate<'tcx>> ExprUseVisitor<'a, 'tcx, D> { /// - `param_env` --- parameter environment for trait lookups (esp. pertaining to `Copy`) /// - `typeck_results` --- typeck results for the code being analyzed pub fn new( - delegate: &'a mut D, + delegate: D, infcx: &'a InferCtxt<'tcx>, body_owner: LocalDefId, param_env: ty::ParamEnv<'tcx>, From e4209f19fd43f220fe5814cc71b5f5315cc28a53 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 8 May 2024 13:40:50 -0400 Subject: [PATCH 124/179] Introduce TypeInformationCtxt to abstract over LateCtxt/FnCtxt --- .../rustc_hir_typeck/src/expr_use_visitor.rs | 289 ++++++++++-------- compiler/rustc_hir_typeck/src/upvar.rs | 5 +- 2 files changed, 160 insertions(+), 134 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs index b8fed4bc688ed..627c7b4a6c406 100644 --- a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs +++ b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs @@ -2,7 +2,8 @@ //! normal visitor, which just walks the entire body in one shot, the //! `ExprUseVisitor` determines how expressions are being used. -use std::cell::RefCell; +use std::cell::{Ref, RefCell}; +use std::ops::Deref; use std::slice::from_ref; use hir::def::DefKind; @@ -16,7 +17,6 @@ use rustc_hir as hir; use rustc_hir::def::{CtorOf, Res}; use rustc_hir::def_id::LocalDefId; use rustc_hir::{HirId, PatKind}; -use rustc_infer::infer::InferCtxt; use rustc_middle::hir::place::ProjectionKind; use rustc_middle::mir::FakeReadCause; use rustc_middle::ty::{ @@ -24,9 +24,11 @@ use rustc_middle::ty::{ }; use rustc_span::{ErrorGuaranteed, Span}; use rustc_target::abi::{FieldIdx, VariantIdx, FIRST_VARIANT}; -use rustc_trait_selection::infer::InferCtxtExt as _; +use rustc_trait_selection::infer::InferCtxtExt; use ty::BorrowKind::ImmBorrow; +use crate::fn_ctxt::FnCtxt; + type McResult = Result; /// This trait defines the callbacks you can expect to receive when @@ -122,16 +124,61 @@ impl<'tcx, D: Delegate<'tcx>> Delegate<'tcx> for &mut D { } } +pub trait TypeInformationCtxt<'tcx> { + type TypeckResults<'a>: Deref> + where + Self: 'a; + + fn typeck_results(&self) -> Self::TypeckResults<'_>; + + fn resolve_vars_if_possible>>(&self, t: T) -> T; + + fn tainted_by_errors(&self) -> Option; + + fn type_is_copy_modulo_regions(&self, ty: Ty<'tcx>) -> bool; + + fn body_owner_def_id(&self) -> LocalDefId; + + fn tcx(&self) -> TyCtxt<'tcx>; +} + +impl<'tcx> TypeInformationCtxt<'tcx> for &FnCtxt<'_, 'tcx> { + type TypeckResults<'a> = Ref<'a, ty::TypeckResults<'tcx>> + where + Self: 'a; + + fn typeck_results(&self) -> Self::TypeckResults<'_> { + self.typeck_results.borrow() + } + + fn resolve_vars_if_possible>>(&self, t: T) -> T { + self.infcx.resolve_vars_if_possible(t) + } + + fn tainted_by_errors(&self) -> Option { + if let Some(guar) = self.infcx.tainted_by_errors() { Err(guar) } else { Ok(()) } + } + + fn type_is_copy_modulo_regions(&self, ty: Ty<'tcx>) -> bool { + self.infcx.type_is_copy_modulo_regions(self.param_env, ty) + } + + fn body_owner_def_id(&self) -> LocalDefId { + self.body_id + } + + fn tcx(&self) -> TyCtxt<'tcx> { + self.tcx + } +} + /// The ExprUseVisitor type /// /// This is the code that actually walks the tree. -pub struct ExprUseVisitor<'a, 'tcx, D: Delegate<'tcx>> { - typeck_results: &'a ty::TypeckResults<'tcx>, - infcx: &'a InferCtxt<'tcx>, - param_env: ty::ParamEnv<'tcx>, - upvars: Option<&'tcx FxIndexMap>, - body_owner: LocalDefId, +pub struct ExprUseVisitor<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> { + cx: Cx, delegate: RefCell, + upvars: Option<&'tcx FxIndexMap>, } /// If the MC results in an error, it's because the type check @@ -153,30 +200,20 @@ macro_rules! return_if_err { }; } -impl<'a, 'tcx, D: Delegate<'tcx>> ExprUseVisitor<'a, 'tcx, D> { +impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx, Cx, D> { /// Creates the ExprUseVisitor, configuring it with the various options provided: /// /// - `delegate` -- who receives the callbacks /// - `param_env` --- parameter environment for trait lookups (esp. pertaining to `Copy`) /// - `typeck_results` --- typeck results for the code being analyzed - pub fn new( - delegate: D, - infcx: &'a InferCtxt<'tcx>, - body_owner: LocalDefId, - param_env: ty::ParamEnv<'tcx>, - typeck_results: &'a ty::TypeckResults<'tcx>, - ) -> Self { + pub fn new(cx: Cx, delegate: D) -> Self { ExprUseVisitor { - infcx, - param_env, - typeck_results, - body_owner, delegate: RefCell::new(delegate), - upvars: infcx.tcx.upvars_mentioned(body_owner), + upvars: cx.tcx().upvars_mentioned(cx.body_owner_def_id()), + cx, } } - #[instrument(skip(self), level = "debug")] pub fn consume_body(&self, body: &hir::Body<'_>) { for param in body.params { let param_ty = return_if_err!(self.pat_ty_adjusted(param.pat)); @@ -190,14 +227,10 @@ impl<'a, 'tcx, D: Delegate<'tcx>> ExprUseVisitor<'a, 'tcx, D> { self.consume_expr(body.value); } - fn tcx(&self) -> TyCtxt<'tcx> { - self.infcx.tcx - } - fn consume_or_copy(&self, place_with_id: &PlaceWithHirId<'tcx>, diag_expr_id: HirId) { debug!("delegate_consume(place_with_id={:?})", place_with_id); - if self.type_is_copy_modulo_regions(place_with_id.place.ty()) { + if self.cx.type_is_copy_modulo_regions(place_with_id.place.ty()) { self.delegate.borrow_mut().copy(place_with_id, diag_expr_id) } else { self.delegate.borrow_mut().consume(place_with_id, diag_expr_id) @@ -390,7 +423,7 @@ impl<'a, 'tcx, D: Delegate<'tcx>> ExprUseVisitor<'a, 'tcx, D> { } hir::ExprKind::AssignOp(_, lhs, rhs) => { - if self.typeck_results.is_method_call(expr) { + if self.cx.typeck_results().is_method_call(expr) { self.consume_expr(lhs); } else { self.mutate_expr(lhs); @@ -461,7 +494,7 @@ impl<'a, 'tcx, D: Delegate<'tcx>> ExprUseVisitor<'a, 'tcx, D> { // A `Path` pattern is just a name like `Foo`. This is either a // named constant or else it refers to an ADT variant - let res = self.typeck_results.qpath_res(qpath, pat.hir_id); + let res = self.cx.typeck_results().qpath_res(qpath, pat.hir_id); match res { Res::Def(DefKind::Const, _) | Res::Def(DefKind::AssocConst, _) => { // Named constants have to be equated with the value @@ -587,8 +620,11 @@ impl<'a, 'tcx, D: Delegate<'tcx>> ExprUseVisitor<'a, 'tcx, D> { self.consume_expr(field.expr); // The struct path probably didn't resolve - if self.typeck_results.opt_field_index(field.hir_id).is_none() { - self.tcx().dcx().span_delayed_bug(field.span, "couldn't resolve index for field"); + if self.cx.typeck_results().opt_field_index(field.hir_id).is_none() { + self.cx + .tcx() + .dcx() + .span_delayed_bug(field.span, "couldn't resolve index for field"); } } @@ -607,14 +643,14 @@ impl<'a, 'tcx, D: Delegate<'tcx>> ExprUseVisitor<'a, 'tcx, D> { ty::Adt(adt, args) if adt.is_struct() => { // Consume those fields of the with expression that are needed. for (f_index, with_field) in adt.non_enum_variant().fields.iter_enumerated() { - let is_mentioned = fields - .iter() - .any(|f| self.typeck_results.opt_field_index(f.hir_id) == Some(f_index)); + let is_mentioned = fields.iter().any(|f| { + self.cx.typeck_results().opt_field_index(f.hir_id) == Some(f_index) + }); if !is_mentioned { let field_place = self.cat_projection( with_expr.hir_id, with_place.clone(), - with_field.ty(self.tcx(), args), + with_field.ty(self.cx.tcx(), args), ProjectionKind::Field(f_index, FIRST_VARIANT), ); self.consume_or_copy(&field_place, field_place.hir_id); @@ -626,7 +662,7 @@ impl<'a, 'tcx, D: Delegate<'tcx>> ExprUseVisitor<'a, 'tcx, D> { // struct; however, when EUV is run during typeck, it // may not. This will generate an error earlier in typeck, // so we can just ignore it. - if self.tcx().dcx().has_errors().is_none() { + if self.cx.tcx().dcx().has_errors().is_none() { span_bug!(with_expr.span, "with expression doesn't evaluate to a struct"); } } @@ -641,7 +677,8 @@ impl<'a, 'tcx, D: Delegate<'tcx>> ExprUseVisitor<'a, 'tcx, D> { /// consumed or borrowed as part of the automatic adjustment /// process. fn walk_adjustment(&self, expr: &hir::Expr<'_>) { - let adjustments = self.typeck_results.expr_adjustments(expr); + let typeck_results = self.cx.typeck_results(); + let adjustments = typeck_results.expr_adjustments(expr); let mut place_with_id = return_if_err!(self.cat_expr_unadjusted(expr)); for adjustment in adjustments { debug!("walk_adjustment expr={:?} adj={:?}", expr, adjustment); @@ -749,12 +786,12 @@ impl<'a, 'tcx, D: Delegate<'tcx>> ExprUseVisitor<'a, 'tcx, D> { fn walk_pat(&self, discr_place: &PlaceWithHirId<'tcx>, pat: &hir::Pat<'_>, has_guard: bool) { debug!("walk_pat(discr_place={:?}, pat={:?}, has_guard={:?})", discr_place, pat, has_guard); - let tcx = self.tcx(); + let tcx = self.cx.tcx(); return_if_err!(self.cat_pattern(discr_place.clone(), pat, |place, pat| { if let PatKind::Binding(_, canonical_id, ..) = pat.kind { debug!("walk_pat: binding place={:?} pat={:?}", place, pat); if let Some(bm) = - self.typeck_results.extract_binding_mode(tcx.sess, pat.hir_id, pat.span) + self.cx.typeck_results().extract_binding_mode(tcx.sess, pat.hir_id, pat.span) { debug!("walk_pat: pat.hir_id={:?} bm={:?}", pat.hir_id, bm); @@ -794,7 +831,7 @@ impl<'a, 'tcx, D: Delegate<'tcx>> ExprUseVisitor<'a, 'tcx, D> { // determines whether to borrow *at the level of the deref pattern* rather than // borrowing the bound place (since that inner place is inside the temporary that // stores the result of calling `deref()`/`deref_mut()` so can't be captured). - let mutable = self.typeck_results.pat_has_ref_mut_binding(subpattern); + let mutable = self.cx.typeck_results().pat_has_ref_mut_binding(subpattern); let mutability = if mutable { hir::Mutability::Mut } else { hir::Mutability::Not }; let bk = ty::BorrowKind::from_mutbl(mutability); self.delegate.borrow_mut().borrow(place, discr_place.hir_id, bk); @@ -832,21 +869,21 @@ impl<'a, 'tcx, D: Delegate<'tcx>> ExprUseVisitor<'a, 'tcx, D> { debug!("walk_captures({:?})", closure_expr); - let tcx = self.tcx(); + let tcx = self.cx.tcx(); let closure_def_id = closure_expr.def_id; - let upvars = tcx.upvars_mentioned(self.body_owner); - // For purposes of this function, coroutine and closures are equivalent. - let body_owner_is_closure = - matches!(tcx.hir().body_owner_kind(self.body_owner), hir::BodyOwnerKind::Closure,); + let body_owner_is_closure = matches!( + tcx.hir().body_owner_kind(self.cx.body_owner_def_id()), + hir::BodyOwnerKind::Closure + ); // If we have a nested closure, we want to include the fake reads present in the nested closure. - if let Some(fake_reads) = self.typeck_results.closure_fake_reads.get(&closure_def_id) { + if let Some(fake_reads) = self.cx.typeck_results().closure_fake_reads.get(&closure_def_id) { for (fake_read, cause, hir_id) in fake_reads.iter() { match fake_read.base { PlaceBase::Upvar(upvar_id) => { if upvar_is_local_variable( - upvars, + self.upvars, upvar_id.var_path.hir_id, body_owner_is_closure, ) { @@ -884,9 +921,14 @@ impl<'a, 'tcx, D: Delegate<'tcx>> ExprUseVisitor<'a, 'tcx, D> { } } - if let Some(min_captures) = self.typeck_results.closure_min_captures.get(&closure_def_id) { + if let Some(min_captures) = + self.cx.typeck_results().closure_min_captures.get(&closure_def_id) + { for (var_hir_id, min_list) in min_captures.iter() { - if upvars.map_or(body_owner_is_closure, |upvars| !upvars.contains_key(var_hir_id)) { + if self + .upvars + .map_or(body_owner_is_closure, |upvars| !upvars.contains_key(var_hir_id)) + { // The nested closure might be capturing the current (enclosing) closure's local variables. // We check if the root variable is ever mentioned within the enclosing closure, if not // then for the current body (if it's a closure) these aren't captures, we will ignore them. @@ -898,7 +940,7 @@ impl<'a, 'tcx, D: Delegate<'tcx>> ExprUseVisitor<'a, 'tcx, D> { let place_base = if body_owner_is_closure { // Mark the place to be captured by the enclosing closure - PlaceBase::Upvar(ty::UpvarId::new(*var_hir_id, self.body_owner)) + PlaceBase::Upvar(ty::UpvarId::new(*var_hir_id, self.cx.body_owner_def_id())) } else { // If the body owner isn't a closure then the variable must // be a local variable @@ -931,46 +973,29 @@ impl<'a, 'tcx, D: Delegate<'tcx>> ExprUseVisitor<'a, 'tcx, D> { } } - fn type_is_copy_modulo_regions(&self, ty: Ty<'tcx>) -> bool { - self.infcx.type_is_copy_modulo_regions(self.param_env, ty) - } - - fn resolve_vars_if_possible(&self, value: T) -> T - where - T: TypeFoldable>, - { - self.infcx.resolve_vars_if_possible(value) - } - - fn tainted_by_errors(&self) -> Option { - self.infcx.tainted_by_errors() - } - fn resolve_type_vars_or_error(&self, id: HirId, ty: Option>) -> McResult> { match ty { Some(ty) => { - let ty = self.resolve_vars_if_possible(ty); - if let Err(guar) = ty.error_reported() { - debug!("resolve_type_vars_or_error: error from {:?}", ty); - Err(guar) - } else if ty.is_ty_var() { + let ty = self.cx.resolve_vars_if_possible(ty); + self.cx.error_reported_in_ty(ty)?; + if ty.is_ty_var() { debug!("resolve_type_vars_or_error: infer var from {:?}", ty); - Err(self - .tcx() - .dcx() - .span_delayed_bug(self.tcx().hir().span(id), "encountered type variable")) + Err(self.cx.tcx().dcx().span_delayed_bug( + self.cx.tcx().hir().span(id), + "encountered type variable", + )) } else { Ok(ty) } } None => { // FIXME - if let Some(guar) = self.tainted_by_errors() { + if let Some(guar) = self.cx.tainted_by_errors() { Err(guar) } else { bug!( "no type for node {} in mem_categorization", - self.tcx().hir().node_to_string(id) + self.cx.tcx().hir().node_to_string(id) ); } } @@ -978,15 +1003,18 @@ impl<'a, 'tcx, D: Delegate<'tcx>> ExprUseVisitor<'a, 'tcx, D> { } fn node_ty(&self, hir_id: HirId) -> McResult> { - self.resolve_type_vars_or_error(hir_id, self.typeck_results.node_type_opt(hir_id)) + self.resolve_type_vars_or_error(hir_id, self.cx.typeck_results().node_type_opt(hir_id)) } fn expr_ty(&self, expr: &hir::Expr<'_>) -> McResult> { - self.resolve_type_vars_or_error(expr.hir_id, self.typeck_results.expr_ty_opt(expr)) + self.resolve_type_vars_or_error(expr.hir_id, self.cx.typeck_results().expr_ty_opt(expr)) } fn expr_ty_adjusted(&self, expr: &hir::Expr<'_>) -> McResult> { - self.resolve_type_vars_or_error(expr.hir_id, self.typeck_results.expr_ty_adjusted_opt(expr)) + self.resolve_type_vars_or_error( + expr.hir_id, + self.cx.typeck_results().expr_ty_adjusted_opt(expr), + ) } /// Returns the type of value that this pattern matches against. @@ -1004,7 +1032,7 @@ impl<'a, 'tcx, D: Delegate<'tcx>> ExprUseVisitor<'a, 'tcx, D> { // that these are never attached to binding patterns, so // actually this is somewhat "disjoint" from the code below // that aims to account for `ref x`. - if let Some(vec) = self.typeck_results.pat_adjustments().get(pat.hir_id) { + if let Some(vec) = self.cx.typeck_results().pat_adjustments().get(pat.hir_id) { if let Some(first_ty) = vec.first() { debug!("pat_ty(pat={:?}) found adjusted ty `{:?}`", pat, first_ty); return Ok(*first_ty); @@ -1015,7 +1043,6 @@ impl<'a, 'tcx, D: Delegate<'tcx>> ExprUseVisitor<'a, 'tcx, D> { } /// Like `pat_ty`, but ignores implicit `&` patterns. - #[instrument(level = "debug", skip(self), ret)] fn pat_ty_unadjusted(&self, pat: &hir::Pat<'_>) -> McResult> { let base_ty = self.node_ty(pat.hir_id)?; trace!(?base_ty); @@ -1025,7 +1052,8 @@ impl<'a, 'tcx, D: Delegate<'tcx>> ExprUseVisitor<'a, 'tcx, D> { match pat.kind { PatKind::Binding(..) => { let bm = *self - .typeck_results + .cx + .typeck_results() .pat_binding_modes() .get(pat.hir_id) .expect("missing binding mode"); @@ -1039,6 +1067,7 @@ impl<'a, 'tcx, D: Delegate<'tcx>> ExprUseVisitor<'a, 'tcx, D> { None => { debug!("By-ref binding of non-derefable type"); Err(self + .cx .tcx() .dcx() .span_delayed_bug(pat.span, "by-ref binding of non-derefable type")) @@ -1053,22 +1082,22 @@ impl<'a, 'tcx, D: Delegate<'tcx>> ExprUseVisitor<'a, 'tcx, D> { } fn cat_expr(&self, expr: &hir::Expr<'_>) -> McResult> { - // This recursion helper avoids going through *too many* - // adjustments, since *only* non-overloaded deref recurses. - fn helper<'a, 'tcx, D: Delegate<'tcx>>( - this: &ExprUseVisitor<'a, 'tcx, D>, - expr: &hir::Expr<'_>, - adjustments: &[adjustment::Adjustment<'tcx>], - ) -> McResult> { - match adjustments.split_last() { - None => this.cat_expr_unadjusted(expr), - Some((adjustment, previous)) => { - this.cat_expr_adjusted_with(expr, || helper(this, expr, previous), adjustment) - } + self.cat_expr_(expr, self.cx.typeck_results().expr_adjustments(expr)) + } + + /// This recursion helper avoids going through *too many* + /// adjustments, since *only* non-overloaded deref recurses. + fn cat_expr_( + &self, + expr: &hir::Expr<'_>, + adjustments: &[adjustment::Adjustment<'tcx>], + ) -> McResult> { + match adjustments.split_last() { + None => self.cat_expr_unadjusted(expr), + Some((adjustment, previous)) => { + self.cat_expr_adjusted_with(expr, || self.cat_expr_(expr, previous), adjustment) } } - - helper(self, expr, self.typeck_results.expr_adjustments(expr)) } fn cat_expr_adjusted( @@ -1080,7 +1109,6 @@ impl<'a, 'tcx, D: Delegate<'tcx>> ExprUseVisitor<'a, 'tcx, D> { self.cat_expr_adjusted_with(expr, || Ok(previous), adjustment) } - #[instrument(level = "debug", skip(self, previous))] fn cat_expr_adjusted_with( &self, expr: &hir::Expr<'_>, @@ -1090,12 +1118,12 @@ impl<'a, 'tcx, D: Delegate<'tcx>> ExprUseVisitor<'a, 'tcx, D> { where F: FnOnce() -> McResult>, { - let target = self.resolve_vars_if_possible(adjustment.target); + let target = self.cx.resolve_vars_if_possible(adjustment.target); match adjustment.kind { adjustment::Adjust::Deref(overloaded) => { // Equivalent to *expr or something similar. let base = if let Some(deref) = overloaded { - let ref_ty = Ty::new_ref(self.tcx(), deref.region, target, deref.mutbl); + let ref_ty = Ty::new_ref(self.cx.tcx(), deref.region, target, deref.mutbl); self.cat_rvalue(expr.hir_id, ref_ty) } else { previous()? @@ -1113,12 +1141,11 @@ impl<'a, 'tcx, D: Delegate<'tcx>> ExprUseVisitor<'a, 'tcx, D> { } } - #[instrument(level = "debug", skip(self), ret)] fn cat_expr_unadjusted(&self, expr: &hir::Expr<'_>) -> McResult> { let expr_ty = self.expr_ty(expr)?; match expr.kind { hir::ExprKind::Unary(hir::UnOp::Deref, e_base) => { - if self.typeck_results.is_method_call(expr) { + if self.cx.typeck_results().is_method_call(expr) { self.cat_overloaded_place(expr, e_base) } else { let base = self.cat_expr(e_base)?; @@ -1131,7 +1158,8 @@ impl<'a, 'tcx, D: Delegate<'tcx>> ExprUseVisitor<'a, 'tcx, D> { debug!(?base); let field_idx = self - .typeck_results + .cx + .typeck_results() .field_indices() .get(expr.hir_id) .cloned() @@ -1146,7 +1174,7 @@ impl<'a, 'tcx, D: Delegate<'tcx>> ExprUseVisitor<'a, 'tcx, D> { } hir::ExprKind::Index(base, _, _) => { - if self.typeck_results.is_method_call(expr) { + if self.cx.typeck_results().is_method_call(expr) { // If this is an index implemented by a method call, then it // will include an implicit deref of the result. // The call to index() returns a `&T` value, which @@ -1160,7 +1188,7 @@ impl<'a, 'tcx, D: Delegate<'tcx>> ExprUseVisitor<'a, 'tcx, D> { } hir::ExprKind::Path(ref qpath) => { - let res = self.typeck_results.qpath_res(qpath, expr.hir_id); + let res = self.cx.typeck_results().qpath_res(qpath, expr.hir_id); self.cat_res(expr.hir_id, expr.span, expr_ty, res) } @@ -1198,7 +1226,6 @@ impl<'a, 'tcx, D: Delegate<'tcx>> ExprUseVisitor<'a, 'tcx, D> { } } - #[instrument(level = "debug", skip(self, span), ret)] fn cat_res( &self, hir_id: HirId, @@ -1239,9 +1266,8 @@ impl<'a, 'tcx, D: Delegate<'tcx>> ExprUseVisitor<'a, 'tcx, D> { /// Note: the actual upvar access contains invisible derefs of closure /// environment and upvar reference as appropriate. Only regionck cares /// about these dereferences, so we let it compute them as needed. - #[instrument(level = "debug", skip(self), ret)] fn cat_upvar(&self, hir_id: HirId, var_id: HirId) -> McResult> { - let closure_expr_def_id = self.body_owner; + let closure_expr_def_id = self.cx.body_owner_def_id(); let upvar_id = ty::UpvarId { var_path: ty::UpvarPath { hir_id: var_id }, @@ -1252,12 +1278,10 @@ impl<'a, 'tcx, D: Delegate<'tcx>> ExprUseVisitor<'a, 'tcx, D> { Ok(PlaceWithHirId::new(hir_id, var_ty, PlaceBase::Upvar(upvar_id), Vec::new())) } - #[instrument(level = "debug", skip(self), ret)] fn cat_rvalue(&self, hir_id: HirId, expr_ty: Ty<'tcx>) -> PlaceWithHirId<'tcx> { PlaceWithHirId::new(hir_id, expr_ty, PlaceBase::Rvalue, Vec::new()) } - #[instrument(level = "debug", skip(self, node), ret)] fn cat_projection( &self, node: HirId, @@ -1268,7 +1292,7 @@ impl<'a, 'tcx, D: Delegate<'tcx>> ExprUseVisitor<'a, 'tcx, D> { let place_ty = base_place.place.ty(); let mut projections = base_place.place.projections; - let node_ty = self.typeck_results.node_type(node); + let node_ty = self.cx.typeck_results().node_type(node); // Opaque types can't have field projections, but we can instead convert // the current place in-place (heh) to the hidden type, and then apply all // follow up projections on that. @@ -1279,7 +1303,6 @@ impl<'a, 'tcx, D: Delegate<'tcx>> ExprUseVisitor<'a, 'tcx, D> { PlaceWithHirId::new(node, base_place.place.base_ty, base_place.place.base, projections) } - #[instrument(level = "debug", skip(self))] fn cat_overloaded_place( &self, expr: &hir::Expr<'_>, @@ -1294,13 +1317,12 @@ impl<'a, 'tcx, D: Delegate<'tcx>> ExprUseVisitor<'a, 'tcx, D> { let ty::Ref(region, _, mutbl) = *base_ty.kind() else { span_bug!(expr.span, "cat_overloaded_place: base is not a reference"); }; - let ref_ty = Ty::new_ref(self.tcx(), region, place_ty, mutbl); + let ref_ty = Ty::new_ref(self.cx.tcx(), region, place_ty, mutbl); let base = self.cat_rvalue(expr.hir_id, ref_ty); self.cat_deref(expr.hir_id, base) } - #[instrument(level = "debug", skip(self, node), ret)] fn cat_deref( &self, node: HirId, @@ -1311,8 +1333,8 @@ impl<'a, 'tcx, D: Delegate<'tcx>> ExprUseVisitor<'a, 'tcx, D> { Some(mt) => mt.ty, None => { debug!("explicit deref of non-derefable type: {:?}", base_curr_ty); - return Err(self.tcx().dcx().span_delayed_bug( - self.tcx().hir().span(node), + return Err(self.cx.tcx().dcx().span_delayed_bug( + self.cx.tcx().hir().span(node), "explicit deref of non-derefable type", )); } @@ -1343,10 +1365,11 @@ impl<'a, 'tcx, D: Delegate<'tcx>> ExprUseVisitor<'a, 'tcx, D> { pat_hir_id: HirId, span: Span, ) -> McResult { - let res = self.typeck_results.qpath_res(qpath, pat_hir_id); - let ty = self.typeck_results.node_type(pat_hir_id); + let res = self.cx.typeck_results().qpath_res(qpath, pat_hir_id); + let ty = self.cx.typeck_results().node_type(pat_hir_id); let ty::Adt(adt_def, _) = ty.kind() else { return Err(self + .cx .tcx() .dcx() .span_delayed_bug(span, "struct or tuple struct pattern not applied to an ADT")); @@ -1377,11 +1400,12 @@ impl<'a, 'tcx, D: Delegate<'tcx>> ExprUseVisitor<'a, 'tcx, D> { variant_index: VariantIdx, span: Span, ) -> McResult { - let ty = self.typeck_results.node_type(pat_hir_id); + let ty = self.cx.typeck_results().node_type(pat_hir_id); match ty.kind() { ty::Adt(adt_def, _) => Ok(adt_def.variant(variant_index).fields.len()), _ => { - self.tcx() + self.cx + .tcx() .dcx() .span_bug(span, "struct or tuple struct pattern not applied to an ADT"); } @@ -1391,12 +1415,14 @@ impl<'a, 'tcx, D: Delegate<'tcx>> ExprUseVisitor<'a, 'tcx, D> { /// Returns the total number of fields in a tuple used within a Tuple pattern. /// Here `pat_hir_id` is the HirId of the pattern itself. fn total_fields_in_tuple(&self, pat_hir_id: HirId, span: Span) -> McResult { - let ty = self.typeck_results.node_type(pat_hir_id); + let ty = self.cx.typeck_results().node_type(pat_hir_id); match ty.kind() { ty::Tuple(args) => Ok(args.len()), - _ => { - Err(self.tcx().dcx().span_delayed_bug(span, "tuple pattern not applied to a tuple")) - } + _ => Err(self + .cx + .tcx() + .dcx() + .span_delayed_bug(span, "tuple pattern not applied to a tuple")), } } @@ -1406,7 +1432,6 @@ impl<'a, 'tcx, D: Delegate<'tcx>> ExprUseVisitor<'a, 'tcx, D> { /// In general, the way that this works is that we walk down the pattern, /// constructing a `PlaceWithHirId` that represents the path that will be taken /// to reach the value being matched. - #[instrument(skip(self, op), ret, level = "debug")] fn cat_pattern_( &self, mut place_with_id: PlaceWithHirId<'tcx>, @@ -1448,7 +1473,9 @@ impl<'a, 'tcx, D: Delegate<'tcx>> ExprUseVisitor<'a, 'tcx, D> { // Then we see that to get the same result, we must start with // `deref { deref { place_foo }}` instead of `place_foo` since the pattern is now `Some(x,)` // and not `&&Some(x,)`, even though its assigned type is that of `&&Some(x,)`. - for _ in 0..self.typeck_results.pat_adjustments().get(pat.hir_id).map_or(0, |v| v.len()) { + for _ in + 0..self.cx.typeck_results().pat_adjustments().get(pat.hir_id).map_or(0, |v| v.len()) + { debug!("applying adjustment to place_with_id={:?}", place_with_id); place_with_id = self.cat_deref(pat.hir_id, place_with_id)?; } @@ -1513,7 +1540,8 @@ impl<'a, 'tcx, D: Delegate<'tcx>> ExprUseVisitor<'a, 'tcx, D> { for fp in field_pats { let field_ty = self.pat_ty_adjusted(fp.pat)?; let field_index = self - .typeck_results + .cx + .typeck_results() .field_indices() .get(fp.hir_id) .cloned() @@ -1547,11 +1575,11 @@ impl<'a, 'tcx, D: Delegate<'tcx>> ExprUseVisitor<'a, 'tcx, D> { self.cat_pattern_(subplace, subpat, op)?; } PatKind::Deref(subpat) => { - let mutable = self.typeck_results.pat_has_ref_mut_binding(subpat); + let mutable = self.cx.typeck_results().pat_has_ref_mut_binding(subpat); let mutability = if mutable { hir::Mutability::Mut } else { hir::Mutability::Not }; - let re_erased = self.tcx().lifetimes.re_erased; + let re_erased = self.cx.tcx().lifetimes.re_erased; let ty = self.pat_ty_adjusted(subpat)?; - let ty = Ty::new_ref(self.tcx(), re_erased, ty, mutability); + let ty = Ty::new_ref(self.cx.tcx(), re_erased, ty, mutability); // A deref pattern generates a temporary. let place = self.cat_rvalue(pat.hir_id, ty); self.cat_pattern_(place, subpat, op)?; @@ -1561,6 +1589,7 @@ impl<'a, 'tcx, D: Delegate<'tcx>> ExprUseVisitor<'a, 'tcx, D> { let Some(element_ty) = place_with_id.place.ty().builtin_index() else { debug!("explicit index of non-indexable type {:?}", place_with_id); return Err(self + .cx .tcx() .dcx() .span_delayed_bug(pat.span, "explicit index of non-indexable type")); diff --git a/compiler/rustc_hir_typeck/src/upvar.rs b/compiler/rustc_hir_typeck/src/upvar.rs index 2bf4f51a8038a..9f710732a0ef5 100644 --- a/compiler/rustc_hir_typeck/src/upvar.rs +++ b/compiler/rustc_hir_typeck/src/upvar.rs @@ -253,11 +253,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } euv::ExprUseVisitor::new( + &FnCtxt::new(self, self.tcx.param_env(closure_def_id), closure_def_id), &mut delegate, - &self.infcx, - closure_def_id, - self.param_env, - &self.typeck_results.borrow(), ) .consume_body(body); From 55cf09d76126b6d16d22b3619c3f1c3a44cce7e5 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 8 May 2024 14:08:18 -0400 Subject: [PATCH 125/179] Make LateCtxt be a type info delegate for EUV for clippy --- .../rustc_hir_typeck/src/expr_use_visitor.rs | 39 ++++++++++++++++++- src/tools/clippy/clippy_lints/src/escape.rs | 4 +- .../clippy_lints/src/loops/mut_range_bound.rs | 10 ++--- .../src/methods/iter_overeager_cloned.rs | 9 ++--- .../src/needless_pass_by_ref_mut.rs | 11 ++---- .../src/needless_pass_by_value.rs | 4 +- .../src/operators/assign_op_pattern.rs | 19 +-------- src/tools/clippy/clippy_lints/src/unwrap.rs | 10 ++--- src/tools/clippy/clippy_utils/src/sugg.rs | 4 +- src/tools/clippy/clippy_utils/src/usage.rs | 10 ++--- 10 files changed, 59 insertions(+), 61 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs index 627c7b4a6c406..d5770dce6754d 100644 --- a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs +++ b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs @@ -9,6 +9,7 @@ use std::slice::from_ref; use hir::def::DefKind; use hir::pat_util::EnumerateAndAdjustIterator as _; use hir::Expr; +use rustc_lint::LateContext; // Export these here so that Clippy can use them. pub use rustc_middle::hir::place::{Place, PlaceBase, PlaceWithHirId, Projection}; @@ -172,6 +173,36 @@ impl<'tcx> TypeInformationCtxt<'tcx> for &FnCtxt<'_, 'tcx> { } } +impl<'tcx> TypeInformationCtxt<'tcx> for (&LateContext<'tcx>, LocalDefId) { + type TypeckResults<'a> = &'tcx ty::TypeckResults<'tcx> + where + Self: 'a; + + fn typeck_results(&self) -> Self::TypeckResults<'_> { + self.0.maybe_typeck_results().expect("expected typeck results") + } + + fn resolve_vars_if_possible>>(&self, t: T) -> T { + t + } + + fn tainted_by_errors(&self) -> Option { + None + } + + fn type_is_copy_modulo_regions(&self, ty: Ty<'tcx>) -> bool { + ty.is_copy_modulo_regions(self.0.tcx, self.0.param_env) + } + + fn body_owner_def_id(&self) -> LocalDefId { + self.1 + } + + fn tcx(&self) -> TyCtxt<'tcx> { + self.0.tcx + } +} + /// The ExprUseVisitor type /// /// This is the code that actually walks the tree. @@ -200,13 +231,19 @@ macro_rules! return_if_err { }; } +impl<'a, 'tcx, D: Delegate<'tcx>> ExprUseVisitor<'tcx, (&'a LateContext<'tcx>, LocalDefId), D> { + pub fn for_clippy(cx: &'a LateContext<'tcx>, body_def_id: LocalDefId, delegate: D) -> Self { + Self::new((cx, body_def_id), delegate) + } +} + impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx, Cx, D> { /// Creates the ExprUseVisitor, configuring it with the various options provided: /// /// - `delegate` -- who receives the callbacks /// - `param_env` --- parameter environment for trait lookups (esp. pertaining to `Copy`) /// - `typeck_results` --- typeck results for the code being analyzed - pub fn new(cx: Cx, delegate: D) -> Self { + pub(crate) fn new(cx: Cx, delegate: D) -> Self { ExprUseVisitor { delegate: RefCell::new(delegate), upvars: cx.tcx().upvars_mentioned(cx.body_owner_def_id()), diff --git a/src/tools/clippy/clippy_lints/src/escape.rs b/src/tools/clippy/clippy_lints/src/escape.rs index 386d4c3c317f6..6392ca13df18a 100644 --- a/src/tools/clippy/clippy_lints/src/escape.rs +++ b/src/tools/clippy/clippy_lints/src/escape.rs @@ -1,7 +1,6 @@ use clippy_utils::diagnostics::span_lint_hir; use rustc_hir::{intravisit, AssocItemKind, Body, FnDecl, HirId, HirIdSet, Impl, ItemKind, Node, Pat, PatKind}; use rustc_hir_typeck::expr_use_visitor::{Delegate, ExprUseVisitor, PlaceBase, PlaceWithHirId}; -use rustc_infer::infer::TyCtxtInferExt; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::mir::FakeReadCause; use rustc_middle::ty::layout::LayoutOf; @@ -105,8 +104,7 @@ impl<'tcx> LateLintPass<'tcx> for BoxedLocal { too_large_for_stack: self.too_large_for_stack, }; - let infcx = cx.tcx.infer_ctxt().build(); - ExprUseVisitor::new(&mut v, &infcx, fn_def_id, cx.param_env, cx.typeck_results()).consume_body(body); + ExprUseVisitor::for_clippy(cx, fn_def_id, &mut v).consume_body(body); for node in v.set { span_lint_hir( diff --git a/src/tools/clippy/clippy_lints/src/loops/mut_range_bound.rs b/src/tools/clippy/clippy_lints/src/loops/mut_range_bound.rs index 5047092192f42..082c5977cbdee 100644 --- a/src/tools/clippy/clippy_lints/src/loops/mut_range_bound.rs +++ b/src/tools/clippy/clippy_lints/src/loops/mut_range_bound.rs @@ -4,7 +4,6 @@ use clippy_utils::{get_enclosing_block, higher, path_to_local}; use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::{BindingMode, Expr, ExprKind, HirId, Node, PatKind}; use rustc_hir_typeck::expr_use_visitor::{Delegate, ExprUseVisitor, PlaceBase, PlaceWithHirId}; -use rustc_infer::infer::TyCtxtInferExt; use rustc_lint::LateContext; use rustc_middle::mir::FakeReadCause; use rustc_middle::ty; @@ -61,13 +60,10 @@ fn check_for_mutation( span_low: None, span_high: None, }; - let infcx = cx.tcx.infer_ctxt().build(); - ExprUseVisitor::new( - &mut delegate, - &infcx, + ExprUseVisitor::for_clippy( + cx, body.hir_id.owner.def_id, - cx.param_env, - cx.typeck_results(), + &mut delegate, ) .walk_expr(body); diff --git a/src/tools/clippy/clippy_lints/src/methods/iter_overeager_cloned.rs b/src/tools/clippy/clippy_lints/src/methods/iter_overeager_cloned.rs index deac159457a66..d4c709de97f51 100644 --- a/src/tools/clippy/clippy_lints/src/methods/iter_overeager_cloned.rs +++ b/src/tools/clippy/clippy_lints/src/methods/iter_overeager_cloned.rs @@ -69,14 +69,11 @@ pub(super) fn check<'tcx>( let mut delegate = MoveDelegate { used_move: HirIdSet::default(), }; - let infcx = cx.tcx.infer_ctxt().build(); - ExprUseVisitor::new( + ExprUseVisitor::for_clippy( + cx, + closure.def_id, &mut delegate, - &infcx, - closure.body.hir_id.owner.def_id, - cx.param_env, - cx.typeck_results(), ) .consume_body(body); diff --git a/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs b/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs index 9e47c3ad0b7fb..5e786c1277acb 100644 --- a/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs +++ b/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs @@ -11,7 +11,6 @@ use rustc_hir::{ PatKind, }; use rustc_hir_typeck::expr_use_visitor as euv; -use rustc_infer::infer::{InferCtxt, TyCtxtInferExt}; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::mir::FakeReadCause; use rustc_middle::ty::{self, Ty, TyCtxt, UpvarId, UpvarPath}; @@ -102,7 +101,6 @@ fn should_skip<'tcx>( fn check_closures<'tcx>( ctx: &mut MutablyUsedVariablesCtxt<'tcx>, cx: &LateContext<'tcx>, - infcx: &InferCtxt<'tcx>, checked_closures: &mut FxHashSet, closures: FxHashSet, ) { @@ -119,7 +117,7 @@ fn check_closures<'tcx>( .associated_body() .map(|(_, body_id)| hir.body(body_id)) { - euv::ExprUseVisitor::new(ctx, infcx, closure, cx.param_env, cx.typeck_results()).consume_body(body); + euv::ExprUseVisitor::for_clippy(cx, closure, &mut *ctx).consume_body(body); } } } @@ -196,8 +194,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByRefMut<'tcx> { async_closures: FxHashSet::default(), tcx: cx.tcx, }; - let infcx = cx.tcx.infer_ctxt().build(); - euv::ExprUseVisitor::new(&mut ctx, &infcx, fn_def_id, cx.param_env, cx.typeck_results()).consume_body(body); + euv::ExprUseVisitor::for_clippy(cx, fn_def_id, &mut ctx).consume_body(body); let mut checked_closures = FxHashSet::default(); @@ -210,13 +207,13 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByRefMut<'tcx> { } ControlFlow::<()>::Continue(()) }); - check_closures(&mut ctx, cx, &infcx, &mut checked_closures, closures); + check_closures(&mut ctx, cx, &mut checked_closures, closures); if is_async { while !ctx.async_closures.is_empty() { let async_closures = ctx.async_closures.clone(); ctx.async_closures.clear(); - check_closures(&mut ctx, cx, &infcx, &mut checked_closures, async_closures); + check_closures(&mut ctx, cx, &mut checked_closures, async_closures); } } ctx.generate_mutably_used_ids_from_aliases() diff --git a/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs b/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs index 39d374d0d27fd..60523ae0d0e2e 100644 --- a/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs +++ b/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs @@ -13,7 +13,6 @@ use rustc_hir::{ TyKind, }; use rustc_hir_typeck::expr_use_visitor as euv; -use rustc_infer::infer::TyCtxtInferExt; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::mir::FakeReadCause; use rustc_middle::ty::{self, Ty, TypeVisitableExt}; @@ -134,8 +133,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue { // function body. let MovedVariablesCtxt { moved_vars } = { let mut ctx = MovedVariablesCtxt::default(); - let infcx = cx.tcx.infer_ctxt().build(); - euv::ExprUseVisitor::new(&mut ctx, &infcx, fn_def_id, cx.param_env, cx.typeck_results()).consume_body(body); + euv::ExprUseVisitor::for_clippy(cx, fn_def_id, &mut ctx).consume_body(body); ctx }; diff --git a/src/tools/clippy/clippy_lints/src/operators/assign_op_pattern.rs b/src/tools/clippy/clippy_lints/src/operators/assign_op_pattern.rs index 8effe6ab54db5..6d617447bb5fb 100644 --- a/src/tools/clippy/clippy_lints/src/operators/assign_op_pattern.rs +++ b/src/tools/clippy/clippy_lints/src/operators/assign_op_pattern.rs @@ -11,7 +11,6 @@ use rustc_hir_typeck::expr_use_visitor::{Delegate, ExprUseVisitor, PlaceBase, Pl use rustc_lint::LateContext; use rustc_middle::mir::FakeReadCause; use rustc_middle::ty::BorrowKind; -use rustc_trait_selection::infer::TyCtxtInferExt; use super::ASSIGN_OP_PATTERN; @@ -119,14 +118,7 @@ fn imm_borrows_in_expr(cx: &LateContext<'_>, e: &hir::Expr<'_>) -> HirIdSet { } let mut s = S(HirIdSet::default()); - let infcx = cx.tcx.infer_ctxt().build(); - let v = ExprUseVisitor::new( - &mut s, - &infcx, - cx.tcx.hir().body_owner_def_id(cx.enclosing_body.unwrap()), - cx.param_env, - cx.typeck_results(), - ); + let v = ExprUseVisitor::for_clippy(cx, e.hir_id.owner.def_id, &mut s); v.consume_expr(e); s.0 } @@ -151,14 +143,7 @@ fn mut_borrows_in_expr(cx: &LateContext<'_>, e: &hir::Expr<'_>) -> HirIdSet { } let mut s = S(HirIdSet::default()); - let infcx = cx.tcx.infer_ctxt().build(); - let v = ExprUseVisitor::new( - &mut s, - &infcx, - cx.tcx.hir().body_owner_def_id(cx.enclosing_body.unwrap()), - cx.param_env, - cx.typeck_results(), - ); + let v = ExprUseVisitor::for_clippy(cx, e.hir_id.owner.def_id, &mut s); v.consume_expr(e); s.0 } diff --git a/src/tools/clippy/clippy_lints/src/unwrap.rs b/src/tools/clippy/clippy_lints/src/unwrap.rs index 6aec3dfa45cbb..aa5555d65f63d 100644 --- a/src/tools/clippy/clippy_lints/src/unwrap.rs +++ b/src/tools/clippy/clippy_lints/src/unwrap.rs @@ -6,7 +6,6 @@ use rustc_errors::Applicability; use rustc_hir::intravisit::{walk_expr, walk_fn, FnKind, Visitor}; use rustc_hir::{BinOpKind, Body, Expr, ExprKind, FnDecl, HirId, Node, PathSegment, UnOp}; use rustc_hir_typeck::expr_use_visitor::{Delegate, ExprUseVisitor, PlaceWithHirId}; -use rustc_infer::infer::TyCtxtInferExt; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::hir::nested_filter; use rustc_middle::lint::in_external_macro; @@ -252,13 +251,10 @@ impl<'a, 'tcx> UnwrappableVariablesVisitor<'a, 'tcx> { local_id: unwrap_info.local_id, }; - let infcx = self.cx.tcx.infer_ctxt().build(); - let vis = ExprUseVisitor::new( - &mut delegate, - &infcx, + let vis = ExprUseVisitor::for_clippy( + self.cx, cond.hir_id.owner.def_id, - self.cx.param_env, - self.cx.typeck_results(), + &mut delegate, ); vis.walk_expr(cond); vis.walk_expr(branch); diff --git a/src/tools/clippy/clippy_utils/src/sugg.rs b/src/tools/clippy/clippy_utils/src/sugg.rs index 8d6057272c4e7..49b0eb05d2acc 100644 --- a/src/tools/clippy/clippy_utils/src/sugg.rs +++ b/src/tools/clippy/clippy_utils/src/sugg.rs @@ -11,7 +11,6 @@ use rustc_errors::Applicability; use rustc_hir as hir; use rustc_hir::{Closure, ExprKind, HirId, MutTy, TyKind}; use rustc_hir_typeck::expr_use_visitor::{Delegate, ExprUseVisitor, PlaceBase, PlaceWithHirId}; -use rustc_infer::infer::TyCtxtInferExt; use rustc_lint::{EarlyContext, LateContext, LintContext}; use rustc_middle::hir::place::ProjectionKind; use rustc_middle::mir::{FakeReadCause, Mutability}; @@ -831,8 +830,7 @@ pub fn deref_closure_args(cx: &LateContext<'_>, closure: &hir::Expr<'_>) -> Opti applicability: Applicability::MachineApplicable, }; - let infcx = cx.tcx.infer_ctxt().build(); - ExprUseVisitor::new(&mut visitor, &infcx, def_id, cx.param_env, cx.typeck_results()).consume_body(closure_body); + ExprUseVisitor::for_clippy(cx, def_id, &mut visitor).consume_body(closure_body); if !visitor.suggestion_start.is_empty() { return Some(DerefClosure { diff --git a/src/tools/clippy/clippy_utils/src/usage.rs b/src/tools/clippy/clippy_utils/src/usage.rs index a145920aa85ed..d0ab6d434aab6 100644 --- a/src/tools/clippy/clippy_utils/src/usage.rs +++ b/src/tools/clippy/clippy_utils/src/usage.rs @@ -5,7 +5,6 @@ use hir::def::Res; use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::{self as hir, Expr, ExprKind, HirId, HirIdSet}; use rustc_hir_typeck::expr_use_visitor::{Delegate, ExprUseVisitor, Place, PlaceBase, PlaceWithHirId}; -use rustc_infer::infer::TyCtxtInferExt; use rustc_lint::LateContext; use rustc_middle::hir::nested_filter; use rustc_middle::mir::FakeReadCause; @@ -17,13 +16,10 @@ pub fn mutated_variables<'tcx>(expr: &'tcx Expr<'_>, cx: &LateContext<'tcx>) -> used_mutably: HirIdSet::default(), skip: false, }; - let infcx = cx.tcx.infer_ctxt().build(); - ExprUseVisitor::new( - &mut delegate, - &infcx, + ExprUseVisitor::for_clippy( + cx, expr.hir_id.owner.def_id, - cx.param_env, - cx.typeck_results(), + &mut delegate, ) .walk_expr(expr); From 5ab6dca6d36e0df83b7ca6ec36b69a4c22e3625e Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 7 May 2024 16:48:15 -0400 Subject: [PATCH 126/179] Try structurally resolve --- .../rustc_hir_typeck/src/expr_use_visitor.rs | 91 +++++++++++++------ .../typeck/normalize-in-upvar-collection.rs | 15 +++ 2 files changed, 77 insertions(+), 29 deletions(-) create mode 100644 tests/ui/traits/next-solver/typeck/normalize-in-upvar-collection.rs diff --git a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs index d5770dce6754d..702f559b2f390 100644 --- a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs +++ b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs @@ -134,6 +134,8 @@ pub trait TypeInformationCtxt<'tcx> { fn resolve_vars_if_possible>>(&self, t: T) -> T; + fn try_structurally_resolve_type(&self, span: Span, ty: Ty<'tcx>) -> Ty<'tcx>; + fn tainted_by_errors(&self) -> Option; fn type_is_copy_modulo_regions(&self, ty: Ty<'tcx>) -> bool; @@ -156,6 +158,10 @@ impl<'tcx> TypeInformationCtxt<'tcx> for &FnCtxt<'_, 'tcx> { self.infcx.resolve_vars_if_possible(t) } + fn try_structurally_resolve_type(&self, sp: Span, ty: Ty<'tcx>) -> Ty<'tcx> { + (**self).try_structurally_resolve_type(sp, ty) + } + fn tainted_by_errors(&self) -> Option { if let Some(guar) = self.infcx.tainted_by_errors() { Err(guar) } else { Ok(()) } } @@ -182,6 +188,11 @@ impl<'tcx> TypeInformationCtxt<'tcx> for (&LateContext<'tcx>, LocalDefId) { self.0.maybe_typeck_results().expect("expected typeck results") } + fn try_structurally_resolve_type(&self, _span: Span, ty: Ty<'tcx>) -> Ty<'tcx> { + // FIXME: Maybe need to normalize here. + ty + } + fn resolve_vars_if_possible>>(&self, t: T) -> T { t } @@ -543,7 +554,8 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx _ => { // Otherwise, this is a struct/enum variant, and so it's // only a read if we need to read the discriminant. - needs_to_be_read |= is_multivariant_adt(place.place.ty()); + needs_to_be_read |= + self.is_multivariant_adt(place.place.ty(), pat.span); } } } @@ -555,7 +567,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx // perform some reads). let place_ty = place.place.ty(); - needs_to_be_read |= is_multivariant_adt(place_ty); + needs_to_be_read |= self.is_multivariant_adt(place_ty, pat.span); } PatKind::Lit(_) | PatKind::Range(..) => { // If the PatKind is a Lit or a Range then we want @@ -676,7 +688,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx // Select just those fields of the `with` // expression that will actually be used - match with_place.place.ty().kind() { + match self.cx.try_structurally_resolve_type(with_expr.span, with_place.place.ty()).kind() { ty::Adt(adt, args) if adt.is_struct() => { // Consume those fields of the with expression that are needed. for (f_index, with_field) in adt.non_enum_variant().fields.iter_enumerated() { @@ -1099,8 +1111,12 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx // a bind-by-ref means that the base_ty will be the type of the ident itself, // but what we want here is the type of the underlying value being borrowed. // So peel off one-level, turning the &T into T. - match base_ty.builtin_deref(false) { - Some(t) => Ok(t.ty), + match self + .cx + .try_structurally_resolve_type(pat.span, base_ty) + .builtin_deref(false) + { + Some(ty) => Ok(ty), None => { debug!("By-ref binding of non-derefable type"); Err(self @@ -1333,7 +1349,15 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx // Opaque types can't have field projections, but we can instead convert // the current place in-place (heh) to the hidden type, and then apply all // follow up projections on that. - if node_ty != place_ty && matches!(place_ty.kind(), ty::Alias(ty::Opaque, ..)) { + if node_ty != place_ty + && self + .cx + .try_structurally_resolve_type( + self.cx.tcx().hir().span(base_place.hir_id), + place_ty, + ) + .is_impl_trait() + { projections.push(Projection { kind: ProjectionKind::OpaqueCast, ty: node_ty }); } projections.push(Projection { kind, ty }); @@ -1351,7 +1375,9 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx let place_ty = self.expr_ty(expr)?; let base_ty = self.expr_ty_adjusted(base)?; - let ty::Ref(region, _, mutbl) = *base_ty.kind() else { + let ty::Ref(region, _, mutbl) = + *self.cx.try_structurally_resolve_type(base.span, base_ty).kind() + else { span_bug!(expr.span, "cat_overloaded_place: base is not a reference"); }; let ref_ty = Ty::new_ref(self.cx.tcx(), region, place_ty, mutbl); @@ -1366,8 +1392,15 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx base_place: PlaceWithHirId<'tcx>, ) -> McResult> { let base_curr_ty = base_place.place.ty(); - let deref_ty = match base_curr_ty.builtin_deref(true) { - Some(mt) => mt.ty, + let deref_ty = match self + .cx + .try_structurally_resolve_type( + self.cx.tcx().hir().span(base_place.hir_id), + base_curr_ty, + ) + .builtin_deref(true) + { + Some(ty) => ty, None => { debug!("explicit deref of non-derefable type: {:?}", base_curr_ty); return Err(self.cx.tcx().dcx().span_delayed_bug( @@ -1404,7 +1437,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx ) -> McResult { let res = self.cx.typeck_results().qpath_res(qpath, pat_hir_id); let ty = self.cx.typeck_results().node_type(pat_hir_id); - let ty::Adt(adt_def, _) = ty.kind() else { + let ty::Adt(adt_def, _) = self.cx.try_structurally_resolve_type(span, ty).kind() else { return Err(self .cx .tcx() @@ -1438,7 +1471,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx span: Span, ) -> McResult { let ty = self.cx.typeck_results().node_type(pat_hir_id); - match ty.kind() { + match self.cx.try_structurally_resolve_type(span, ty).kind() { ty::Adt(adt_def, _) => Ok(adt_def.variant(variant_index).fields.len()), _ => { self.cx @@ -1453,7 +1486,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx /// Here `pat_hir_id` is the HirId of the pattern itself. fn total_fields_in_tuple(&self, pat_hir_id: HirId, span: Span) -> McResult { let ty = self.cx.typeck_results().node_type(pat_hir_id); - match ty.kind() { + match self.cx.try_structurally_resolve_type(span, ty).kind() { ty::Tuple(args) => Ok(args.len()), _ => Err(self .cx @@ -1668,23 +1701,23 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx Ok(()) } -} -fn is_multivariant_adt(ty: Ty<'_>) -> bool { - if let ty::Adt(def, _) = ty.kind() { - // Note that if a non-exhaustive SingleVariant is defined in another crate, we need - // to assume that more cases will be added to the variant in the future. This mean - // that we should handle non-exhaustive SingleVariant the same way we would handle - // a MultiVariant. - // If the variant is not local it must be defined in another crate. - let is_non_exhaustive = match def.adt_kind() { - AdtKind::Struct | AdtKind::Union => { - def.non_enum_variant().is_field_list_non_exhaustive() - } - AdtKind::Enum => def.is_variant_list_non_exhaustive(), - }; - def.variants().len() > 1 || (!def.did().is_local() && is_non_exhaustive) - } else { - false + fn is_multivariant_adt(&self, ty: Ty<'tcx>, span: Span) -> bool { + if let ty::Adt(def, _) = self.cx.try_structurally_resolve_type(span, ty).kind() { + // Note that if a non-exhaustive SingleVariant is defined in another crate, we need + // to assume that more cases will be added to the variant in the future. This mean + // that we should handle non-exhaustive SingleVariant the same way we would handle + // a MultiVariant. + // If the variant is not local it must be defined in another crate. + let is_non_exhaustive = match def.adt_kind() { + AdtKind::Struct | AdtKind::Union => { + def.non_enum_variant().is_field_list_non_exhaustive() + } + AdtKind::Enum => def.is_variant_list_non_exhaustive(), + }; + def.variants().len() > 1 || (!def.did().is_local() && is_non_exhaustive) + } else { + false + } } } diff --git a/tests/ui/traits/next-solver/typeck/normalize-in-upvar-collection.rs b/tests/ui/traits/next-solver/typeck/normalize-in-upvar-collection.rs new file mode 100644 index 0000000000000..7e4e466fa4d63 --- /dev/null +++ b/tests/ui/traits/next-solver/typeck/normalize-in-upvar-collection.rs @@ -0,0 +1,15 @@ +//@ compile-flags: -Znext-solver +//@ check-pass + +struct Struct { + field: i32, +} + +fn hello(f: impl Fn() -> &'static Box<[i32]>, f2: impl Fn() -> &'static Struct) { + let cl = || { + let x = &f()[0]; + let y = &f2().field; + }; +} + +fn main() {} From fb298e80c3dcf9d5ed81c9b86dedd40256775c1d Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 9 May 2024 11:32:05 -0400 Subject: [PATCH 127/179] Apply nits --- .../rustc_hir_typeck/src/expr_use_visitor.rs | 150 ++++++++++++------ .../typeck/normalize-in-upvar-collection.rs | 4 + 2 files changed, 105 insertions(+), 49 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs index 702f559b2f390..05cedb19eb818 100644 --- a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs +++ b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs @@ -30,8 +30,6 @@ use ty::BorrowKind::ImmBorrow; use crate::fn_ctxt::FnCtxt; -type McResult = Result; - /// This trait defines the callbacks you can expect to receive when /// employing the ExprUseVisitor. pub trait Delegate<'tcx> { @@ -219,6 +217,8 @@ impl<'tcx> TypeInformationCtxt<'tcx> for (&LateContext<'tcx>, LocalDefId) { /// This is the code that actually walks the tree. pub struct ExprUseVisitor<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> { cx: Cx, + /// We use a `RefCell` here so that delegates can mutate themselves, but we can + /// still have calls to our own helper functions. delegate: RefCell, upvars: Option<&'tcx FxIndexMap>, } @@ -517,14 +517,14 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx discr: &Expr<'_>, discr_place: PlaceWithHirId<'tcx>, pats: impl Iterator>, - ) -> McResult<()> { + ) -> Result<(), ErrorGuaranteed> { // Matching should not always be considered a use of the place, hence // discr does not necessarily need to be borrowed. // We only want to borrow discr if the pattern contain something other // than wildcards. let mut needs_to_be_read = false; for pat in pats { - self.cat_pattern(discr_place.clone(), pat, |place, pat| { + self.cat_pattern(discr_place.clone(), pat, &mut |place, pat| { match &pat.kind { PatKind::Binding(.., opt_sub_pat) => { // If the opt_sub_pat is None, then the binding does not count as @@ -836,7 +836,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx debug!("walk_pat(discr_place={:?}, pat={:?}, has_guard={:?})", discr_place, pat, has_guard); let tcx = self.cx.tcx(); - return_if_err!(self.cat_pattern(discr_place.clone(), pat, |place, pat| { + return_if_err!(self.cat_pattern(discr_place.clone(), pat, &mut |place, pat| { if let PatKind::Binding(_, canonical_id, ..) = pat.kind { debug!("walk_pat: binding place={:?} pat={:?}", place, pat); if let Some(bm) = @@ -1021,8 +1021,61 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx } } } +} - fn resolve_type_vars_or_error(&self, id: HirId, ty: Option>) -> McResult> { +/// The job of the categorization methods is to analyze an expression to +/// determine what kind of memory is used in evaluating it (for example, +/// where dereferences occur and what kind of pointer is dereferenced; +/// whether the memory is mutable, etc.). +/// +/// Categorization effectively transforms all of our expressions into +/// expressions of the following forms (the actual enum has many more +/// possibilities, naturally, but they are all variants of these base +/// forms): +/// ```ignore (not-rust) +/// E = rvalue // some computed rvalue +/// | x // address of a local variable or argument +/// | *E // deref of a ptr +/// | E.comp // access to an interior component +/// ``` +/// Imagine a routine ToAddr(Expr) that evaluates an expression and returns an +/// address where the result is to be found. If Expr is a place, then this +/// is the address of the place. If `Expr` is an rvalue, this is the address of +/// some temporary spot in memory where the result is stored. +/// +/// Now, `cat_expr()` classifies the expression `Expr` and the address `A = ToAddr(Expr)` +/// as follows: +/// +/// - `cat`: what kind of expression was this? This is a subset of the +/// full expression forms which only includes those that we care about +/// for the purpose of the analysis. +/// - `mutbl`: mutability of the address `A`. +/// - `ty`: the type of data found at the address `A`. +/// +/// The resulting categorization tree differs somewhat from the expressions +/// themselves. For example, auto-derefs are explicit. Also, an index `a[b]` is +/// decomposed into two operations: a dereference to reach the array data and +/// then an index to jump forward to the relevant item. +/// +/// ## By-reference upvars +/// +/// One part of the codegen which may be non-obvious is that we translate +/// closure upvars into the dereference of a borrowed pointer; this more closely +/// resembles the runtime codegen. So, for example, if we had: +/// +/// let mut x = 3; +/// let y = 5; +/// let inc = || x += y; +/// +/// Then when we categorize `x` (*within* the closure) we would yield a +/// result of `*x'`, effectively, where `x'` is a `Categorization::Upvar` reference +/// tied to `x`. The type of `x'` will be a borrowed pointer. +impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx, Cx, D> { + fn resolve_type_vars_or_error( + &self, + id: HirId, + ty: Option>, + ) -> Result, ErrorGuaranteed> { match ty { Some(ty) => { let ty = self.cx.resolve_vars_if_possible(ty); @@ -1051,15 +1104,15 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx } } - fn node_ty(&self, hir_id: HirId) -> McResult> { + fn node_ty(&self, hir_id: HirId) -> Result, ErrorGuaranteed> { self.resolve_type_vars_or_error(hir_id, self.cx.typeck_results().node_type_opt(hir_id)) } - fn expr_ty(&self, expr: &hir::Expr<'_>) -> McResult> { + fn expr_ty(&self, expr: &hir::Expr<'_>) -> Result, ErrorGuaranteed> { self.resolve_type_vars_or_error(expr.hir_id, self.cx.typeck_results().expr_ty_opt(expr)) } - fn expr_ty_adjusted(&self, expr: &hir::Expr<'_>) -> McResult> { + fn expr_ty_adjusted(&self, expr: &hir::Expr<'_>) -> Result, ErrorGuaranteed> { self.resolve_type_vars_or_error( expr.hir_id, self.cx.typeck_results().expr_ty_adjusted_opt(expr), @@ -1076,7 +1129,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx /// implicit deref patterns attached (e.g., it is really /// `&Some(x)`). In that case, we return the "outermost" type /// (e.g., `&Option`). - fn pat_ty_adjusted(&self, pat: &hir::Pat<'_>) -> McResult> { + fn pat_ty_adjusted(&self, pat: &hir::Pat<'_>) -> Result, ErrorGuaranteed> { // Check for implicit `&` types wrapping the pattern; note // that these are never attached to binding patterns, so // actually this is somewhat "disjoint" from the code below @@ -1091,8 +1144,8 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx self.pat_ty_unadjusted(pat) } - /// Like `pat_ty`, but ignores implicit `&` patterns. - fn pat_ty_unadjusted(&self, pat: &hir::Pat<'_>) -> McResult> { + /// Like `TypeckResults::pat_ty`, but ignores implicit `&` patterns. + fn pat_ty_unadjusted(&self, pat: &hir::Pat<'_>) -> Result, ErrorGuaranteed> { let base_ty = self.node_ty(pat.hir_id)?; trace!(?base_ty); @@ -1134,7 +1187,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx } } - fn cat_expr(&self, expr: &hir::Expr<'_>) -> McResult> { + fn cat_expr(&self, expr: &hir::Expr<'_>) -> Result, ErrorGuaranteed> { self.cat_expr_(expr, self.cx.typeck_results().expr_adjustments(expr)) } @@ -1144,7 +1197,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx &self, expr: &hir::Expr<'_>, adjustments: &[adjustment::Adjustment<'tcx>], - ) -> McResult> { + ) -> Result, ErrorGuaranteed> { match adjustments.split_last() { None => self.cat_expr_unadjusted(expr), Some((adjustment, previous)) => { @@ -1158,7 +1211,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx expr: &hir::Expr<'_>, previous: PlaceWithHirId<'tcx>, adjustment: &adjustment::Adjustment<'tcx>, - ) -> McResult> { + ) -> Result, ErrorGuaranteed> { self.cat_expr_adjusted_with(expr, || Ok(previous), adjustment) } @@ -1167,9 +1220,9 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx expr: &hir::Expr<'_>, previous: F, adjustment: &adjustment::Adjustment<'tcx>, - ) -> McResult> + ) -> Result, ErrorGuaranteed> where - F: FnOnce() -> McResult>, + F: FnOnce() -> Result, ErrorGuaranteed>, { let target = self.cx.resolve_vars_if_possible(adjustment.target); match adjustment.kind { @@ -1194,7 +1247,10 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx } } - fn cat_expr_unadjusted(&self, expr: &hir::Expr<'_>) -> McResult> { + fn cat_expr_unadjusted( + &self, + expr: &hir::Expr<'_>, + ) -> Result, ErrorGuaranteed> { let expr_ty = self.expr_ty(expr)?; match expr.kind { hir::ExprKind::Unary(hir::UnOp::Deref, e_base) => { @@ -1285,7 +1341,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx span: Span, expr_ty: Ty<'tcx>, res: Res, - ) -> McResult> { + ) -> Result, ErrorGuaranteed> { match res { Res::Def( DefKind::Ctor(..) @@ -1319,7 +1375,11 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx /// Note: the actual upvar access contains invisible derefs of closure /// environment and upvar reference as appropriate. Only regionck cares /// about these dereferences, so we let it compute them as needed. - fn cat_upvar(&self, hir_id: HirId, var_id: HirId) -> McResult> { + fn cat_upvar( + &self, + hir_id: HirId, + var_id: HirId, + ) -> Result, ErrorGuaranteed> { let closure_expr_def_id = self.cx.body_owner_def_id(); let upvar_id = ty::UpvarId { @@ -1368,7 +1428,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx &self, expr: &hir::Expr<'_>, base: &hir::Expr<'_>, - ) -> McResult> { + ) -> Result, ErrorGuaranteed> { // Reconstruct the output assuming it's a reference with the // same region and mutability as the receiver. This holds for // `Deref(Mut)::Deref(_mut)` and `Index(Mut)::index(_mut)`. @@ -1390,7 +1450,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx &self, node: HirId, base_place: PlaceWithHirId<'tcx>, - ) -> McResult> { + ) -> Result, ErrorGuaranteed> { let base_curr_ty = base_place.place.ty(); let deref_ty = match self .cx @@ -1415,18 +1475,6 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx Ok(PlaceWithHirId::new(node, base_place.place.base_ty, base_place.place.base, projections)) } - fn cat_pattern( - &self, - place: PlaceWithHirId<'tcx>, - pat: &hir::Pat<'_>, - mut op: F, - ) -> McResult<()> - where - F: FnMut(&PlaceWithHirId<'tcx>, &hir::Pat<'_>), - { - self.cat_pattern_(place, pat, &mut op) - } - /// Returns the variant index for an ADT used within a Struct or TupleStruct pattern /// Here `pat_hir_id` is the HirId of the pattern itself. fn variant_index_for_adt( @@ -1434,7 +1482,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx qpath: &hir::QPath<'_>, pat_hir_id: HirId, span: Span, - ) -> McResult { + ) -> Result { let res = self.cx.typeck_results().qpath_res(qpath, pat_hir_id); let ty = self.cx.typeck_results().node_type(pat_hir_id); let ty::Adt(adt_def, _) = self.cx.try_structurally_resolve_type(span, ty).kind() else { @@ -1469,7 +1517,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx pat_hir_id: HirId, variant_index: VariantIdx, span: Span, - ) -> McResult { + ) -> Result { let ty = self.cx.typeck_results().node_type(pat_hir_id); match self.cx.try_structurally_resolve_type(span, ty).kind() { ty::Adt(adt_def, _) => Ok(adt_def.variant(variant_index).fields.len()), @@ -1484,7 +1532,11 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx /// Returns the total number of fields in a tuple used within a Tuple pattern. /// Here `pat_hir_id` is the HirId of the pattern itself. - fn total_fields_in_tuple(&self, pat_hir_id: HirId, span: Span) -> McResult { + fn total_fields_in_tuple( + &self, + pat_hir_id: HirId, + span: Span, + ) -> Result { let ty = self.cx.typeck_results().node_type(pat_hir_id); match self.cx.try_structurally_resolve_type(span, ty).kind() { ty::Tuple(args) => Ok(args.len()), @@ -1502,12 +1554,12 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx /// In general, the way that this works is that we walk down the pattern, /// constructing a `PlaceWithHirId` that represents the path that will be taken /// to reach the value being matched. - fn cat_pattern_( + fn cat_pattern( &self, mut place_with_id: PlaceWithHirId<'tcx>, pat: &hir::Pat<'_>, op: &mut F, - ) -> McResult<()> + ) -> Result<(), ErrorGuaranteed> where F: FnMut(&PlaceWithHirId<'tcx>, &hir::Pat<'_>), { @@ -1578,7 +1630,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx subpat_ty, projection_kind, ); - self.cat_pattern_(sub_place, subpat, op)?; + self.cat_pattern(sub_place, subpat, op)?; } } @@ -1598,7 +1650,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx subpat_ty, projection_kind, ); - self.cat_pattern_(sub_place, subpat, op)?; + self.cat_pattern(sub_place, subpat, op)?; } } @@ -1623,18 +1675,18 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx field_ty, ProjectionKind::Field(field_index, variant_index), ); - self.cat_pattern_(field_place, fp.pat, op)?; + self.cat_pattern(field_place, fp.pat, op)?; } } PatKind::Or(pats) => { for pat in pats { - self.cat_pattern_(place_with_id.clone(), pat, op)?; + self.cat_pattern(place_with_id.clone(), pat, op)?; } } PatKind::Binding(.., Some(subpat)) => { - self.cat_pattern_(place_with_id, subpat, op)?; + self.cat_pattern(place_with_id, subpat, op)?; } PatKind::Box(subpat) | PatKind::Ref(subpat, _) => { @@ -1642,7 +1694,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx // PatKind::Ref since that information is already contained // in the type. let subplace = self.cat_deref(pat.hir_id, place_with_id)?; - self.cat_pattern_(subplace, subpat, op)?; + self.cat_pattern(subplace, subpat, op)?; } PatKind::Deref(subpat) => { let mutable = self.cx.typeck_results().pat_has_ref_mut_binding(subpat); @@ -1652,7 +1704,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx let ty = Ty::new_ref(self.cx.tcx(), re_erased, ty, mutability); // A deref pattern generates a temporary. let place = self.cat_rvalue(pat.hir_id, ty); - self.cat_pattern_(place, subpat, op)?; + self.cat_pattern(place, subpat, op)?; } PatKind::Slice(before, ref slice, after) => { @@ -1671,7 +1723,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx ProjectionKind::Index, ); for before_pat in before { - self.cat_pattern_(elt_place.clone(), before_pat, op)?; + self.cat_pattern(elt_place.clone(), before_pat, op)?; } if let Some(slice_pat) = *slice { let slice_pat_ty = self.pat_ty_adjusted(slice_pat)?; @@ -1681,10 +1733,10 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx slice_pat_ty, ProjectionKind::Subslice, ); - self.cat_pattern_(slice_place, slice_pat, op)?; + self.cat_pattern(slice_place, slice_pat, op)?; } for after_pat in after { - self.cat_pattern_(elt_place.clone(), after_pat, op)?; + self.cat_pattern(elt_place.clone(), after_pat, op)?; } } diff --git a/tests/ui/traits/next-solver/typeck/normalize-in-upvar-collection.rs b/tests/ui/traits/next-solver/typeck/normalize-in-upvar-collection.rs index 7e4e466fa4d63..6567f2752404a 100644 --- a/tests/ui/traits/next-solver/typeck/normalize-in-upvar-collection.rs +++ b/tests/ui/traits/next-solver/typeck/normalize-in-upvar-collection.rs @@ -1,6 +1,10 @@ //@ compile-flags: -Znext-solver //@ check-pass +// Fixes a regression in icu_provider_adaptors where we weren't normalizing the +// return type of a function type before performing a `Ty::builtin_deref` call, +// leading to an ICE. + struct Struct { field: i32, } From 0627c63ad9a11bda958fab1c4bef7dc2eda9f000 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sun, 12 May 2024 18:20:01 +0200 Subject: [PATCH 128/179] Remove polymorphize calls for statics in a couple more places --- src/global_asm.rs | 2 +- src/inline_asm.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/global_asm.rs b/src/global_asm.rs index 5a0cd3990f2a7..0c99a5ce12f6e 100644 --- a/src/global_asm.rs +++ b/src/global_asm.rs @@ -81,7 +81,7 @@ pub(crate) fn codegen_global_asm_item(tcx: TyCtxt<'_>, global_asm: &mut String, ); } - let instance = Instance::mono(tcx, def_id).polymorphize(tcx); + let instance = Instance::mono(tcx, def_id); let symbol = tcx.symbol_name(instance); global_asm.push_str(symbol.name); } diff --git a/src/inline_asm.rs b/src/inline_asm.rs index 28b92f730da34..f2299e933bb09 100644 --- a/src/inline_asm.rs +++ b/src/inline_asm.rs @@ -127,7 +127,7 @@ pub(crate) fn codegen_inline_asm_terminator<'tcx>( } InlineAsmOperand::SymStatic { def_id } => { assert!(fx.tcx.is_static(def_id)); - let instance = Instance::mono(fx.tcx, def_id).polymorphize(fx.tcx); + let instance = Instance::mono(fx.tcx, def_id); CInlineAsmOperand::Symbol { symbol: fx.tcx.symbol_name(instance).name.to_owned() } } InlineAsmOperand::Label { .. } => { From cba05a7a14b307d31b226a11c2104e53c2ae1291 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sun, 12 May 2024 18:12:48 +0200 Subject: [PATCH 129/179] Support naked functions Fixes rust-lang/rustc_codegen_cranelift#1203 --- build_system/build_sysroot.rs | 2 +- example/mini_core_hello_world.rs | 10 ++ src/base.rs | 37 +++++- src/driver/aot.rs | 7 +- src/driver/jit.rs | 8 +- src/driver/mod.rs | 16 ++- src/inline_asm.rs | 199 +++++++++++++++++++++++++------ 7 files changed, 231 insertions(+), 48 deletions(-) diff --git a/build_system/build_sysroot.rs b/build_system/build_sysroot.rs index 7791df1d53fd2..196ff8fda7544 100644 --- a/build_system/build_sysroot.rs +++ b/build_system/build_sysroot.rs @@ -276,7 +276,7 @@ fn build_clif_sysroot_for_triple( if channel == "release" { build_cmd.arg("--release"); } - build_cmd.arg("--features").arg("compiler-builtins-no-asm backtrace panic-unwind"); + build_cmd.arg("--features").arg("backtrace panic-unwind"); build_cmd.env("CARGO_PROFILE_RELEASE_DEBUG", "true"); build_cmd.env("__CARGO_DEFAULT_LIB_METADATA", "cg_clif"); if compiler.triple.contains("apple") { diff --git a/example/mini_core_hello_world.rs b/example/mini_core_hello_world.rs index efa4be7e15ac3..aab20f672487b 100644 --- a/example/mini_core_hello_world.rs +++ b/example/mini_core_hello_world.rs @@ -4,6 +4,7 @@ never_type, linkage, extern_types, + naked_functions, thread_local, repr_simd, raw_ref_op @@ -340,6 +341,7 @@ fn main() { ))] unsafe { global_asm_test(); + naked_test(); } // Both statics have a reference that points to the same anonymous allocation. @@ -395,6 +397,14 @@ global_asm! { " } +#[cfg(all(not(jit), not(no_unstable_features), target_arch = "x86_64"))] +#[naked] +extern "C" fn naked_test() { + unsafe { + asm!("ret", options(noreturn)); + } +} + #[repr(C)] enum c_void { _1, diff --git a/src/base.rs b/src/base.rs index 8874efadec9d9..5846689643fdd 100644 --- a/src/base.rs +++ b/src/base.rs @@ -6,6 +6,7 @@ use cranelift_frontend::{FunctionBuilder, FunctionBuilderContext}; use cranelift_module::ModuleError; use rustc_ast::InlineAsmOptions; use rustc_index::IndexVec; +use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc_middle::ty::adjustment::PointerCoercion; use rustc_middle::ty::layout::FnAbiOf; use rustc_middle::ty::print::with_no_trimmed_paths; @@ -14,6 +15,7 @@ use rustc_monomorphize::is_call_from_compiler_builtins_to_upstream_monomorphizat use crate::constant::ConstantCx; use crate::debuginfo::{FunctionDebugContext, TypeDebugContext}; +use crate::inline_asm::codegen_naked_asm; use crate::prelude::*; use crate::pretty_clif::CommentWriter; @@ -32,7 +34,7 @@ pub(crate) fn codegen_fn<'tcx>( cached_func: Function, module: &mut dyn Module, instance: Instance<'tcx>, -) -> CodegenedFunction { +) -> Option { debug_assert!(!instance.args.has_infer()); let symbol_name = tcx.symbol_name(instance).name.to_string(); @@ -48,6 +50,37 @@ pub(crate) fn codegen_fn<'tcx>( String::from_utf8_lossy(&buf).into_owned() }); + if tcx.codegen_fn_attrs(instance.def_id()).flags.contains(CodegenFnAttrFlags::NAKED) { + assert_eq!(mir.basic_blocks.len(), 1); + assert!(mir.basic_blocks[START_BLOCK].statements.is_empty()); + + match &mir.basic_blocks[START_BLOCK].terminator().kind { + TerminatorKind::InlineAsm { + template, + operands, + options, + line_spans: _, + targets: _, + unwind: _, + } => { + codegen_naked_asm( + tcx, + cx, + module, + instance, + mir.basic_blocks[START_BLOCK].terminator().source_info.span, + &symbol_name, + template, + operands, + *options, + ); + } + _ => unreachable!(), + } + + return None; + } + // Declare function let sig = get_function_sig(tcx, module.target_config().default_call_conv, instance); let func_id = module.declare_function(&symbol_name, Linkage::Local, &sig).unwrap(); @@ -128,7 +161,7 @@ pub(crate) fn codegen_fn<'tcx>( // Verify function verify_func(tcx, &clif_comments, &func); - CodegenedFunction { symbol_name, func_id, func, clif_comments, func_debug_cx } + Some(CodegenedFunction { symbol_name, func_id, func, clif_comments, func_debug_cx }) } pub(crate) fn compile_fn( diff --git a/src/driver/aot.rs b/src/driver/aot.rs index 2651e56cac45f..fce4690f97dc9 100644 --- a/src/driver/aot.rs +++ b/src/driver/aot.rs @@ -482,15 +482,16 @@ fn module_codegen( for (mono_item, _) in mono_items { match mono_item { MonoItem::Fn(inst) => { - let codegened_function = crate::base::codegen_fn( + if let Some(codegened_function) = crate::base::codegen_fn( tcx, &mut cx, &mut type_dbg, Function::new(), &mut module, inst, - ); - codegened_functions.push(codegened_function); + ) { + codegened_functions.push(codegened_function); + } } MonoItem::Static(def_id) => { let data_id = crate::constant::codegen_static(tcx, &mut module, def_id); diff --git a/src/driver/jit.rs b/src/driver/jit.rs index 6f8be03065fb9..4b149131b61aa 100644 --- a/src/driver/jit.rs +++ b/src/driver/jit.rs @@ -232,16 +232,16 @@ pub(crate) fn codegen_and_compile_fn<'tcx>( crate::PrintOnPanic(|| format!("{:?} {}", instance, tcx.symbol_name(instance).name)); let cached_func = std::mem::replace(&mut cached_context.func, Function::new()); - let codegened_func = crate::base::codegen_fn( + if let Some(codegened_func) = crate::base::codegen_fn( tcx, cx, &mut TypeDebugContext::default(), cached_func, module, instance, - ); - - crate::base::compile_fn(cx, cached_context, module, codegened_func); + ) { + crate::base::compile_fn(cx, cached_context, module, codegened_func); + } }); } diff --git a/src/driver/mod.rs b/src/driver/mod.rs index 12e90b5841034..fb0eed07c1971 100644 --- a/src/driver/mod.rs +++ b/src/driver/mod.rs @@ -5,6 +5,7 @@ //! [`codegen_static`]: crate::constant::codegen_static use rustc_data_structures::profiling::SelfProfilerRef; +use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc_middle::mir::mono::{MonoItem, MonoItemData}; use crate::prelude::*; @@ -33,7 +34,20 @@ fn predefine_mono_items<'tcx>( data.visibility, is_compiler_builtins, ); - module.declare_function(name, linkage, &sig).unwrap(); + let is_naked = tcx + .codegen_fn_attrs(instance.def_id()) + .flags + .contains(CodegenFnAttrFlags::NAKED); + module + .declare_function( + name, + // Naked functions are defined in a separate object + // file from the codegen unit rustc expects them to + // be defined in. + if is_naked { Linkage::Import } else { linkage }, + &sig, + ) + .unwrap(); } MonoItem::Static(_) | MonoItem::GlobalAsm(_) => {} } diff --git a/src/inline_asm.rs b/src/inline_asm.rs index f2299e933bb09..2de804f5e0423 100644 --- a/src/inline_asm.rs +++ b/src/inline_asm.rs @@ -169,6 +169,7 @@ pub(crate) fn codegen_inline_asm_inner<'tcx>( stack_slots_input: Vec::new(), stack_slots_output: Vec::new(), stack_slot_size: Size::from_bytes(0), + is_naked: false, }; asm_gen.allocate_registers(); asm_gen.allocate_stack_slots(); @@ -209,6 +210,121 @@ pub(crate) fn codegen_inline_asm_inner<'tcx>( call_inline_asm(fx, &asm_name, asm_gen.stack_slot_size, inputs, outputs); } +pub(crate) fn codegen_naked_asm<'tcx>( + tcx: TyCtxt<'tcx>, + cx: &mut crate::CodegenCx, + module: &mut dyn Module, + instance: Instance<'tcx>, + span: Span, + symbol_name: &str, + template: &[InlineAsmTemplatePiece], + operands: &[InlineAsmOperand<'tcx>], + options: InlineAsmOptions, +) { + // FIXME add .eh_frame unwind info directives + + let operands = operands + .iter() + .map(|operand| match *operand { + InlineAsmOperand::In { .. } + | InlineAsmOperand::Out { .. } + | InlineAsmOperand::InOut { .. } => { + span_bug!(span, "invalid operand type for naked asm") + } + InlineAsmOperand::Const { ref value } => { + let cv = instance.instantiate_mir_and_normalize_erasing_regions( + tcx, + ty::ParamEnv::reveal_all(), + ty::EarlyBinder::bind(value.const_), + ); + let const_value = cv + .eval(tcx, ty::ParamEnv::reveal_all(), value.span) + .expect("erroneous constant missed by mono item collection"); + + let value = rustc_codegen_ssa::common::asm_const_to_str( + tcx, + span, + const_value, + RevealAllLayoutCx(tcx).layout_of(cv.ty()), + ); + CInlineAsmOperand::Const { value } + } + InlineAsmOperand::SymFn { ref value } => { + if cfg!(not(feature = "inline_asm_sym")) { + tcx.dcx() + .span_err(span, "asm! and global_asm! sym operands are not yet supported"); + } + + let const_ = instance.instantiate_mir_and_normalize_erasing_regions( + tcx, + ty::ParamEnv::reveal_all(), + ty::EarlyBinder::bind(value.const_), + ); + if let ty::FnDef(def_id, args) = *const_.ty().kind() { + let instance = ty::Instance::resolve_for_fn_ptr( + tcx, + ty::ParamEnv::reveal_all(), + def_id, + args, + ) + .unwrap(); + let symbol = tcx.symbol_name(instance); + + // Pass a wrapper rather than the function itself as the function itself may not + // be exported from the main codegen unit and may thus be unreachable from the + // object file created by an external assembler. + let inline_asm_index = cx.inline_asm_index.get(); + cx.inline_asm_index.set(inline_asm_index + 1); + let wrapper_name = format!( + "__inline_asm_{}_wrapper_n{}", + cx.cgu_name.as_str().replace('.', "__").replace('-', "_"), + inline_asm_index + ); + let sig = + get_function_sig(tcx, module.target_config().default_call_conv, instance); + create_wrapper_function( + module, + &mut cx.unwind_context, + sig, + &wrapper_name, + symbol.name, + ); + + CInlineAsmOperand::Symbol { symbol: wrapper_name } + } else { + span_bug!(span, "invalid type for asm sym (fn)"); + } + } + InlineAsmOperand::SymStatic { def_id } => { + assert!(tcx.is_static(def_id)); + let instance = Instance::mono(tcx, def_id); + CInlineAsmOperand::Symbol { symbol: tcx.symbol_name(instance).name.to_owned() } + } + InlineAsmOperand::Label { .. } => { + span_bug!(span, "asm! label operands are not yet supported"); + } + }) + .collect::>(); + + let asm_gen = InlineAssemblyGenerator { + tcx, + arch: tcx.sess.asm_arch.unwrap(), + enclosing_def_id: instance.def_id(), + template, + operands: &operands, + options, + registers: Vec::new(), + stack_slots_clobber: Vec::new(), + stack_slots_input: Vec::new(), + stack_slots_output: Vec::new(), + stack_slot_size: Size::from_bytes(0), + is_naked: true, + }; + + let generated_asm = asm_gen.generate_asm_wrapper(symbol_name); + cx.global_asm.push_str(&generated_asm); +} + struct InlineAssemblyGenerator<'a, 'tcx> { tcx: TyCtxt<'tcx>, arch: InlineAsmArch, @@ -221,10 +337,13 @@ struct InlineAssemblyGenerator<'a, 'tcx> { stack_slots_input: Vec>, stack_slots_output: Vec>, stack_slot_size: Size, + is_naked: bool, } impl<'tcx> InlineAssemblyGenerator<'_, 'tcx> { fn allocate_registers(&mut self) { + assert!(!self.is_naked); + let sess = self.tcx.sess; let map = allocatable_registers( self.arch, @@ -348,6 +467,8 @@ impl<'tcx> InlineAssemblyGenerator<'_, 'tcx> { } fn allocate_stack_slots(&mut self) { + assert!(!self.is_naked); + let mut slot_size = Size::from_bytes(0); let mut slots_clobber = vec![None; self.operands.len()]; let mut slots_input = vec![None; self.operands.len()]; @@ -468,30 +589,32 @@ impl<'tcx> InlineAssemblyGenerator<'_, 'tcx> { if is_x86 { generated_asm.push_str(".intel_syntax noprefix\n"); } - Self::prologue(&mut generated_asm, self.arch); + if !self.is_naked { + Self::prologue(&mut generated_asm, self.arch); + + // Save clobbered registers + if !self.options.contains(InlineAsmOptions::NORETURN) { + for (reg, slot) in self + .registers + .iter() + .zip(self.stack_slots_clobber.iter().copied()) + .filter_map(|(r, s)| r.zip(s)) + { + Self::save_register(&mut generated_asm, self.arch, reg, slot); + } + } - // Save clobbered registers - if !self.options.contains(InlineAsmOptions::NORETURN) { + // Write input registers for (reg, slot) in self .registers .iter() - .zip(self.stack_slots_clobber.iter().copied()) + .zip(self.stack_slots_input.iter().copied()) .filter_map(|(r, s)| r.zip(s)) { - Self::save_register(&mut generated_asm, self.arch, reg, slot); + Self::restore_register(&mut generated_asm, self.arch, reg, slot); } } - // Write input registers - for (reg, slot) in self - .registers - .iter() - .zip(self.stack_slots_input.iter().copied()) - .filter_map(|(r, s)| r.zip(s)) - { - Self::restore_register(&mut generated_asm, self.arch, reg, slot); - } - if is_x86 && self.options.contains(InlineAsmOptions::ATT_SYNTAX) { generated_asm.push_str(".att_syntax\n"); } @@ -553,30 +676,32 @@ impl<'tcx> InlineAssemblyGenerator<'_, 'tcx> { generated_asm.push_str(".intel_syntax noprefix\n"); } - if !self.options.contains(InlineAsmOptions::NORETURN) { - // Read output registers - for (reg, slot) in self - .registers - .iter() - .zip(self.stack_slots_output.iter().copied()) - .filter_map(|(r, s)| r.zip(s)) - { - Self::save_register(&mut generated_asm, self.arch, reg, slot); - } + if !self.is_naked { + if !self.options.contains(InlineAsmOptions::NORETURN) { + // Read output registers + for (reg, slot) in self + .registers + .iter() + .zip(self.stack_slots_output.iter().copied()) + .filter_map(|(r, s)| r.zip(s)) + { + Self::save_register(&mut generated_asm, self.arch, reg, slot); + } - // Restore clobbered registers - for (reg, slot) in self - .registers - .iter() - .zip(self.stack_slots_clobber.iter().copied()) - .filter_map(|(r, s)| r.zip(s)) - { - Self::restore_register(&mut generated_asm, self.arch, reg, slot); - } + // Restore clobbered registers + for (reg, slot) in self + .registers + .iter() + .zip(self.stack_slots_clobber.iter().copied()) + .filter_map(|(r, s)| r.zip(s)) + { + Self::restore_register(&mut generated_asm, self.arch, reg, slot); + } - Self::epilogue(&mut generated_asm, self.arch); - } else { - Self::epilogue_noreturn(&mut generated_asm, self.arch); + Self::epilogue(&mut generated_asm, self.arch); + } else { + Self::epilogue_noreturn(&mut generated_asm, self.arch); + } } if is_x86 { From c697ec41f4b9d8de1e340e777e3001a25ad28a8d Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 9 May 2024 11:33:53 -0400 Subject: [PATCH 130/179] Propagate errors rather than using return_if_err --- .../rustc_hir_typeck/src/expr_use_visitor.rs | 392 +++++++++--------- compiler/rustc_hir_typeck/src/upvar.rs | 2 +- src/tools/clippy/clippy_lints/src/escape.rs | 2 +- src/tools/clippy/clippy_lints/src/lib.rs | 1 + .../clippy_lints/src/loops/mut_range_bound.rs | 2 +- .../src/methods/iter_overeager_cloned.rs | 3 +- .../src/needless_pass_by_ref_mut.rs | 4 +- .../src/needless_pass_by_value.rs | 2 +- .../src/operators/assign_op_pattern.rs | 4 +- src/tools/clippy/clippy_lints/src/unwrap.rs | 4 +- src/tools/clippy/clippy_utils/src/lib.rs | 1 + src/tools/clippy/clippy_utils/src/sugg.rs | 4 +- src/tools/clippy/clippy_utils/src/usage.rs | 3 +- tests/crashes/123901.rs | 8 - .../async-closures/ambiguous-arg.rs | 15 + .../async-closures/ambiguous-arg.stderr | 13 + 16 files changed, 252 insertions(+), 208 deletions(-) delete mode 100644 tests/crashes/123901.rs create mode 100644 tests/ui/async-await/async-closures/ambiguous-arg.rs create mode 100644 tests/ui/async-await/async-closures/ambiguous-arg.stderr diff --git a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs index 05cedb19eb818..589f41948defb 100644 --- a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs +++ b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs @@ -128,13 +128,19 @@ pub trait TypeInformationCtxt<'tcx> { where Self: 'a; + type Error; + fn typeck_results(&self) -> Self::TypeckResults<'_>; fn resolve_vars_if_possible>>(&self, t: T) -> T; fn try_structurally_resolve_type(&self, span: Span, ty: Ty<'tcx>) -> Ty<'tcx>; - fn tainted_by_errors(&self) -> Option; + fn report_error(&self, span: Span, msg: impl ToString) -> Self::Error; + + fn error_reported_in_ty(&self, ty: Ty<'tcx>) -> Result<(), Self::Error>; + + fn tainted_by_errors(&self) -> Result<(), Self::Error>; fn type_is_copy_modulo_regions(&self, ty: Ty<'tcx>) -> bool; @@ -148,6 +154,8 @@ impl<'tcx> TypeInformationCtxt<'tcx> for &FnCtxt<'_, 'tcx> { where Self: 'a; + type Error = ErrorGuaranteed; + fn typeck_results(&self) -> Self::TypeckResults<'_> { self.typeck_results.borrow() } @@ -160,7 +168,15 @@ impl<'tcx> TypeInformationCtxt<'tcx> for &FnCtxt<'_, 'tcx> { (**self).try_structurally_resolve_type(sp, ty) } - fn tainted_by_errors(&self) -> Option { + fn report_error(&self, span: Span, msg: impl ToString) -> Self::Error { + self.tcx.dcx().span_delayed_bug(span, msg.to_string()) + } + + fn error_reported_in_ty(&self, ty: Ty<'tcx>) -> Result<(), Self::Error> { + ty.error_reported() + } + + fn tainted_by_errors(&self) -> Result<(), ErrorGuaranteed> { if let Some(guar) = self.infcx.tainted_by_errors() { Err(guar) } else { Ok(()) } } @@ -182,6 +198,8 @@ impl<'tcx> TypeInformationCtxt<'tcx> for (&LateContext<'tcx>, LocalDefId) { where Self: 'a; + type Error = !; + fn typeck_results(&self) -> Self::TypeckResults<'_> { self.0.maybe_typeck_results().expect("expected typeck results") } @@ -195,8 +213,16 @@ impl<'tcx> TypeInformationCtxt<'tcx> for (&LateContext<'tcx>, LocalDefId) { t } - fn tainted_by_errors(&self) -> Option { - None + fn report_error(&self, span: Span, msg: impl ToString) -> ! { + span_bug!(span, "{}", msg.to_string()) + } + + fn error_reported_in_ty(&self, _ty: Ty<'tcx>) -> Result<(), !> { + Ok(()) + } + + fn tainted_by_errors(&self) -> Result<(), !> { + Ok(()) } fn type_is_copy_modulo_regions(&self, ty: Ty<'tcx>) -> bool { @@ -223,25 +249,6 @@ pub struct ExprUseVisitor<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx> upvars: Option<&'tcx FxIndexMap>, } -/// If the MC results in an error, it's because the type check -/// failed (or will fail, when the error is uncovered and reported -/// during writeback). In this case, we just ignore this part of the -/// code. -/// -/// Note that this macro appears similar to try!(), but, unlike try!(), -/// it does not propagate the error. -macro_rules! return_if_err { - ($inp: expr) => { - match $inp { - Ok(v) => v, - Err(_) => { - debug!("mc reported err"); - return; - } - } - }; -} - impl<'a, 'tcx, D: Delegate<'tcx>> ExprUseVisitor<'tcx, (&'a LateContext<'tcx>, LocalDefId), D> { pub fn for_clippy(cx: &'a LateContext<'tcx>, body_def_id: LocalDefId, delegate: D) -> Self { Self::new((cx, body_def_id), delegate) @@ -262,133 +269,140 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx } } - pub fn consume_body(&self, body: &hir::Body<'_>) { + pub fn consume_body(&self, body: &hir::Body<'_>) -> Result<(), Cx::Error> { for param in body.params { - let param_ty = return_if_err!(self.pat_ty_adjusted(param.pat)); + let param_ty = self.pat_ty_adjusted(param.pat)?; debug!("consume_body: param_ty = {:?}", param_ty); let param_place = self.cat_rvalue(param.hir_id, param_ty); - self.walk_irrefutable_pat(¶m_place, param.pat); + self.walk_irrefutable_pat(¶m_place, param.pat)?; } - self.consume_expr(body.value); + self.consume_expr(body.value)?; + + Ok(()) } fn consume_or_copy(&self, place_with_id: &PlaceWithHirId<'tcx>, diag_expr_id: HirId) { debug!("delegate_consume(place_with_id={:?})", place_with_id); if self.cx.type_is_copy_modulo_regions(place_with_id.place.ty()) { - self.delegate.borrow_mut().copy(place_with_id, diag_expr_id) + self.delegate.borrow_mut().copy(place_with_id, diag_expr_id); } else { - self.delegate.borrow_mut().consume(place_with_id, diag_expr_id) + self.delegate.borrow_mut().consume(place_with_id, diag_expr_id); } } - fn consume_exprs(&self, exprs: &[hir::Expr<'_>]) { + fn consume_exprs(&self, exprs: &[hir::Expr<'_>]) -> Result<(), Cx::Error> { for expr in exprs { - self.consume_expr(expr); + self.consume_expr(expr)?; } + + Ok(()) } // FIXME: It's suspicious that this is public; clippy should probably use `walk_expr`. - pub fn consume_expr(&self, expr: &hir::Expr<'_>) { + pub fn consume_expr(&self, expr: &hir::Expr<'_>) -> Result<(), Cx::Error> { debug!("consume_expr(expr={:?})", expr); - let place_with_id = return_if_err!(self.cat_expr(expr)); + let place_with_id = self.cat_expr(expr)?; self.consume_or_copy(&place_with_id, place_with_id.hir_id); - self.walk_expr(expr); + self.walk_expr(expr)?; + Ok(()) } - fn mutate_expr(&self, expr: &hir::Expr<'_>) { - let place_with_id = return_if_err!(self.cat_expr(expr)); + fn mutate_expr(&self, expr: &hir::Expr<'_>) -> Result<(), Cx::Error> { + let place_with_id = self.cat_expr(expr)?; self.delegate.borrow_mut().mutate(&place_with_id, place_with_id.hir_id); - self.walk_expr(expr); + self.walk_expr(expr)?; + Ok(()) } - fn borrow_expr(&self, expr: &hir::Expr<'_>, bk: ty::BorrowKind) { + fn borrow_expr(&self, expr: &hir::Expr<'_>, bk: ty::BorrowKind) -> Result<(), Cx::Error> { debug!("borrow_expr(expr={:?}, bk={:?})", expr, bk); - let place_with_id = return_if_err!(self.cat_expr(expr)); + let place_with_id = self.cat_expr(expr)?; self.delegate.borrow_mut().borrow(&place_with_id, place_with_id.hir_id, bk); - self.walk_expr(expr) } - pub fn walk_expr(&self, expr: &hir::Expr<'_>) { + pub fn walk_expr(&self, expr: &hir::Expr<'_>) -> Result<(), Cx::Error> { debug!("walk_expr(expr={:?})", expr); - self.walk_adjustment(expr); + self.walk_adjustment(expr)?; match expr.kind { hir::ExprKind::Path(_) => {} - hir::ExprKind::Type(subexpr, _) => self.walk_expr(subexpr), + hir::ExprKind::Type(subexpr, _) => { + self.walk_expr(subexpr)?; + } hir::ExprKind::Unary(hir::UnOp::Deref, base) => { // *base - self.walk_expr(base); + self.walk_expr(base)?; } hir::ExprKind::Field(base, _) => { // base.f - self.walk_expr(base); + self.walk_expr(base)?; } hir::ExprKind::Index(lhs, rhs, _) => { // lhs[rhs] - self.walk_expr(lhs); - self.consume_expr(rhs); + self.walk_expr(lhs)?; + self.consume_expr(rhs)?; } hir::ExprKind::Call(callee, args) => { // callee(args) - self.consume_expr(callee); - self.consume_exprs(args); + self.consume_expr(callee)?; + self.consume_exprs(args)?; } hir::ExprKind::MethodCall(.., receiver, args, _) => { // callee.m(args) - self.consume_expr(receiver); - self.consume_exprs(args); + self.consume_expr(receiver)?; + self.consume_exprs(args)?; } hir::ExprKind::Struct(_, fields, ref opt_with) => { - self.walk_struct_expr(fields, opt_with); + self.walk_struct_expr(fields, opt_with)?; } hir::ExprKind::Tup(exprs) => { - self.consume_exprs(exprs); + self.consume_exprs(exprs)?; } hir::ExprKind::If(cond_expr, then_expr, ref opt_else_expr) => { - self.consume_expr(cond_expr); - self.consume_expr(then_expr); + self.consume_expr(cond_expr)?; + self.consume_expr(then_expr)?; if let Some(else_expr) = *opt_else_expr { - self.consume_expr(else_expr); + self.consume_expr(else_expr)?; } } hir::ExprKind::Let(hir::LetExpr { pat, init, .. }) => { - self.walk_local(init, pat, None, || self.borrow_expr(init, ty::ImmBorrow)) + self.walk_local(init, pat, None, || self.borrow_expr(init, ty::ImmBorrow))?; } hir::ExprKind::Match(discr, arms, _) => { - let discr_place = return_if_err!(self.cat_expr(discr)); - return_if_err!(self.maybe_read_scrutinee( + let discr_place = self.cat_expr(discr)?; + self.maybe_read_scrutinee( discr, discr_place.clone(), arms.iter().map(|arm| arm.pat), - )); + )?; // treatment of the discriminant is handled while walking the arms. for arm in arms { - self.walk_arm(&discr_place, arm); + self.walk_arm(&discr_place, arm)?; } } hir::ExprKind::Array(exprs) => { - self.consume_exprs(exprs); + self.consume_exprs(exprs)?; } hir::ExprKind::AddrOf(_, m, base) => { @@ -396,21 +410,23 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx // make sure that the thing we are pointing out stays valid // for the lifetime `scope_r` of the resulting ptr: let bk = ty::BorrowKind::from_mutbl(m); - self.borrow_expr(base, bk); + self.borrow_expr(base, bk)?; } hir::ExprKind::InlineAsm(asm) => { for (op, _op_sp) in asm.operands { match op { - hir::InlineAsmOperand::In { expr, .. } => self.consume_expr(expr), + hir::InlineAsmOperand::In { expr, .. } => { + self.consume_expr(expr)?; + } hir::InlineAsmOperand::Out { expr: Some(expr), .. } | hir::InlineAsmOperand::InOut { expr, .. } => { - self.mutate_expr(expr); + self.mutate_expr(expr)?; } hir::InlineAsmOperand::SplitInOut { in_expr, out_expr, .. } => { - self.consume_expr(in_expr); + self.consume_expr(in_expr)?; if let Some(out_expr) = out_expr { - self.mutate_expr(out_expr); + self.mutate_expr(out_expr)?; } } hir::InlineAsmOperand::Out { expr: None, .. } @@ -418,7 +434,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx | hir::InlineAsmOperand::SymFn { .. } | hir::InlineAsmOperand::SymStatic { .. } => {} hir::InlineAsmOperand::Label { block } => { - self.walk_block(block); + self.walk_block(block)?; } } } @@ -431,72 +447,74 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx | hir::ExprKind::Err(_) => {} hir::ExprKind::Loop(blk, ..) => { - self.walk_block(blk); + self.walk_block(blk)?; } hir::ExprKind::Unary(_, lhs) => { - self.consume_expr(lhs); + self.consume_expr(lhs)?; } hir::ExprKind::Binary(_, lhs, rhs) => { - self.consume_expr(lhs); - self.consume_expr(rhs); + self.consume_expr(lhs)?; + self.consume_expr(rhs)?; } hir::ExprKind::Block(blk, _) => { - self.walk_block(blk); + self.walk_block(blk)?; } hir::ExprKind::Break(_, ref opt_expr) | hir::ExprKind::Ret(ref opt_expr) => { if let Some(expr) = *opt_expr { - self.consume_expr(expr); + self.consume_expr(expr)?; } } hir::ExprKind::Become(call) => { - self.consume_expr(call); + self.consume_expr(call)?; } hir::ExprKind::Assign(lhs, rhs, _) => { - self.mutate_expr(lhs); - self.consume_expr(rhs); + self.mutate_expr(lhs)?; + self.consume_expr(rhs)?; } hir::ExprKind::Cast(base, _) => { - self.consume_expr(base); + self.consume_expr(base)?; } hir::ExprKind::DropTemps(expr) => { - self.consume_expr(expr); + self.consume_expr(expr)?; } hir::ExprKind::AssignOp(_, lhs, rhs) => { if self.cx.typeck_results().is_method_call(expr) { - self.consume_expr(lhs); + self.consume_expr(lhs)?; } else { - self.mutate_expr(lhs); + self.mutate_expr(lhs)?; } - self.consume_expr(rhs); + self.consume_expr(rhs)?; } hir::ExprKind::Repeat(base, _) => { - self.consume_expr(base); + self.consume_expr(base)?; } hir::ExprKind::Closure(closure) => { - self.walk_captures(closure); + self.walk_captures(closure)?; } hir::ExprKind::Yield(value, _) => { - self.consume_expr(value); + self.consume_expr(value)?; } } + + Ok(()) } - fn walk_stmt(&self, stmt: &hir::Stmt<'_>) { + fn walk_stmt(&self, stmt: &hir::Stmt<'_>) -> Result<(), Cx::Error> { match stmt.kind { hir::StmtKind::Let(hir::LetStmt { pat, init: Some(expr), els, .. }) => { - self.walk_local(expr, pat, *els, || {}) + self.walk_local(expr, pat, *els, || Ok(()))?; } hir::StmtKind::Let(_) => {} @@ -507,9 +525,11 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx } hir::StmtKind::Expr(expr) | hir::StmtKind::Semi(expr) => { - self.consume_expr(expr); + self.consume_expr(expr)?; } } + + Ok(()) } fn maybe_read_scrutinee<'t>( @@ -517,7 +537,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx discr: &Expr<'_>, discr_place: PlaceWithHirId<'tcx>, pats: impl Iterator>, - ) -> Result<(), ErrorGuaranteed> { + ) -> Result<(), Cx::Error> { // Matching should not always be considered a use of the place, hence // discr does not necessarily need to be borrowed. // We only want to borrow discr if the pattern contain something other @@ -597,11 +617,13 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx // being examined } } + + Ok(()) })? } if needs_to_be_read { - self.borrow_expr(discr, ty::ImmBorrow); + self.borrow_expr(discr, ty::ImmBorrow)?; } else { let closure_def_id = match discr_place.place.base { PlaceBase::Upvar(upvar_id) => Some(upvar_id.closure_expr_id), @@ -616,7 +638,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx // We always want to walk the discriminant. We want to make sure, for instance, // that the discriminant has been initialized. - self.walk_expr(discr); + self.walk_expr(discr)?; } Ok(()) } @@ -627,46 +649,46 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx pat: &hir::Pat<'_>, els: Option<&hir::Block<'_>>, mut f: F, - ) where - F: FnMut(), + ) -> Result<(), Cx::Error> + where + F: FnMut() -> Result<(), Cx::Error>, { - self.walk_expr(expr); - let expr_place = return_if_err!(self.cat_expr(expr)); - f(); + self.walk_expr(expr)?; + let expr_place = self.cat_expr(expr)?; + f()?; if let Some(els) = els { // borrowing because we need to test the discriminant - return_if_err!(self.maybe_read_scrutinee( - expr, - expr_place.clone(), - from_ref(pat).iter() - )); - self.walk_block(els) + self.maybe_read_scrutinee(expr, expr_place.clone(), from_ref(pat).iter())?; + self.walk_block(els)?; } - self.walk_irrefutable_pat(&expr_place, pat); + self.walk_irrefutable_pat(&expr_place, pat)?; + Ok(()) } /// Indicates that the value of `blk` will be consumed, meaning either copied or moved /// depending on its type. - fn walk_block(&self, blk: &hir::Block<'_>) { + fn walk_block(&self, blk: &hir::Block<'_>) -> Result<(), Cx::Error> { debug!("walk_block(blk.hir_id={})", blk.hir_id); for stmt in blk.stmts { - self.walk_stmt(stmt); + self.walk_stmt(stmt)?; } if let Some(tail_expr) = blk.expr { - self.consume_expr(tail_expr); + self.consume_expr(tail_expr)?; } + + Ok(()) } fn walk_struct_expr<'hir>( &self, fields: &[hir::ExprField<'_>], opt_with: &Option<&'hir hir::Expr<'_>>, - ) { + ) -> Result<(), Cx::Error> { // Consume the expressions supplying values for each field. for field in fields { - self.consume_expr(field.expr); + self.consume_expr(field.expr)?; // The struct path probably didn't resolve if self.cx.typeck_results().opt_field_index(field.hir_id).is_none() { @@ -680,11 +702,11 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx let with_expr = match *opt_with { Some(w) => &*w, None => { - return; + return Ok(()); } }; - let with_place = return_if_err!(self.cat_expr(with_expr)); + let with_place = self.cat_expr(with_expr)?; // Select just those fields of the `with` // expression that will actually be used @@ -719,16 +741,18 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx // walk the with expression so that complex expressions // are properly handled. - self.walk_expr(with_expr); + self.walk_expr(with_expr)?; + + Ok(()) } /// Invoke the appropriate delegate calls for anything that gets /// consumed or borrowed as part of the automatic adjustment /// process. - fn walk_adjustment(&self, expr: &hir::Expr<'_>) { + fn walk_adjustment(&self, expr: &hir::Expr<'_>) -> Result<(), Cx::Error> { let typeck_results = self.cx.typeck_results(); let adjustments = typeck_results.expr_adjustments(expr); - let mut place_with_id = return_if_err!(self.cat_expr_unadjusted(expr)); + let mut place_with_id = self.cat_expr_unadjusted(expr)?; for adjustment in adjustments { debug!("walk_adjustment expr={:?} adj={:?}", expr, adjustment); match adjustment.kind { @@ -756,8 +780,10 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx self.walk_autoref(expr, &place_with_id, autoref); } } - place_with_id = return_if_err!(self.cat_expr_adjusted(expr, place_with_id, adjustment)); + place_with_id = self.cat_expr_adjusted(expr, place_with_id, adjustment)?; } + + Ok(()) } /// Walks the autoref `autoref` applied to the autoderef'd @@ -795,7 +821,11 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx } } - fn walk_arm(&self, discr_place: &PlaceWithHirId<'tcx>, arm: &hir::Arm<'_>) { + fn walk_arm( + &self, + discr_place: &PlaceWithHirId<'tcx>, + arm: &hir::Arm<'_>, + ) -> Result<(), Cx::Error> { let closure_def_id = match discr_place.place.base { PlaceBase::Upvar(upvar_id) => Some(upvar_id.closure_expr_id), _ => None, @@ -806,18 +836,23 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx FakeReadCause::ForMatchedPlace(closure_def_id), discr_place.hir_id, ); - self.walk_pat(discr_place, arm.pat, arm.guard.is_some()); + self.walk_pat(discr_place, arm.pat, arm.guard.is_some())?; if let Some(ref e) = arm.guard { - self.consume_expr(e) + self.consume_expr(e)?; } - self.consume_expr(arm.body); + self.consume_expr(arm.body)?; + Ok(()) } /// Walks a pat that occurs in isolation (i.e., top-level of fn argument or /// let binding, and *not* a match arm or nested pat.) - fn walk_irrefutable_pat(&self, discr_place: &PlaceWithHirId<'tcx>, pat: &hir::Pat<'_>) { + fn walk_irrefutable_pat( + &self, + discr_place: &PlaceWithHirId<'tcx>, + pat: &hir::Pat<'_>, + ) -> Result<(), Cx::Error> { let closure_def_id = match discr_place.place.base { PlaceBase::Upvar(upvar_id) => Some(upvar_id.closure_expr_id), _ => None, @@ -828,15 +863,21 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx FakeReadCause::ForLet(closure_def_id), discr_place.hir_id, ); - self.walk_pat(discr_place, pat, false); + self.walk_pat(discr_place, pat, false)?; + Ok(()) } /// The core driver for walking a pattern - fn walk_pat(&self, discr_place: &PlaceWithHirId<'tcx>, pat: &hir::Pat<'_>, has_guard: bool) { + fn walk_pat( + &self, + discr_place: &PlaceWithHirId<'tcx>, + pat: &hir::Pat<'_>, + has_guard: bool, + ) -> Result<(), Cx::Error> { debug!("walk_pat(discr_place={:?}, pat={:?}, has_guard={:?})", discr_place, pat, has_guard); let tcx = self.cx.tcx(); - return_if_err!(self.cat_pattern(discr_place.clone(), pat, &mut |place, pat| { + self.cat_pattern(discr_place.clone(), pat, &mut |place, pat| { if let PatKind::Binding(_, canonical_id, ..) = pat.kind { debug!("walk_pat: binding place={:?} pat={:?}", place, pat); if let Some(bm) = @@ -845,7 +886,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx debug!("walk_pat: pat.hir_id={:?} bm={:?}", pat.hir_id, bm); // pat_ty: the type of the binding being produced. - let pat_ty = return_if_err!(self.node_ty(pat.hir_id)); + let pat_ty = self.node_ty(pat.hir_id)?; debug!("walk_pat: pat_ty={:?}", pat_ty); let def = Res::Local(canonical_id); @@ -885,7 +926,9 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx let bk = ty::BorrowKind::from_mutbl(mutability); self.delegate.borrow_mut().borrow(place, discr_place.hir_id, bk); } - })); + + Ok(()) + }) } /// Handle the case where the current body contains a closure. @@ -907,7 +950,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx /// /// - When reporting the Place back to the Delegate, ensure that the UpvarId uses the enclosing /// closure as the DefId. - fn walk_captures(&self, closure_expr: &hir::Closure<'_>) { + fn walk_captures(&self, closure_expr: &hir::Closure<'_>) -> Result<(), Cx::Error> { fn upvar_is_local_variable( upvars: Option<&FxIndexMap>, upvar_id: HirId, @@ -1020,6 +1063,8 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx } } } + + Ok(()) } } @@ -1075,44 +1120,40 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx &self, id: HirId, ty: Option>, - ) -> Result, ErrorGuaranteed> { + ) -> Result, Cx::Error> { match ty { Some(ty) => { let ty = self.cx.resolve_vars_if_possible(ty); self.cx.error_reported_in_ty(ty)?; if ty.is_ty_var() { debug!("resolve_type_vars_or_error: infer var from {:?}", ty); - Err(self.cx.tcx().dcx().span_delayed_bug( - self.cx.tcx().hir().span(id), - "encountered type variable", - )) + Err(self + .cx + .report_error(self.cx.tcx().hir().span(id), "encountered type variable")) } else { Ok(ty) } } None => { - // FIXME - if let Some(guar) = self.cx.tainted_by_errors() { - Err(guar) - } else { - bug!( - "no type for node {} in mem_categorization", - self.cx.tcx().hir().node_to_string(id) - ); - } + // FIXME: We shouldn't be relying on the infcx being tainted. + self.cx.tainted_by_errors()?; + bug!( + "no type for node {} in mem_categorization", + self.cx.tcx().hir().node_to_string(id) + ); } } } - fn node_ty(&self, hir_id: HirId) -> Result, ErrorGuaranteed> { + fn node_ty(&self, hir_id: HirId) -> Result, Cx::Error> { self.resolve_type_vars_or_error(hir_id, self.cx.typeck_results().node_type_opt(hir_id)) } - fn expr_ty(&self, expr: &hir::Expr<'_>) -> Result, ErrorGuaranteed> { + fn expr_ty(&self, expr: &hir::Expr<'_>) -> Result, Cx::Error> { self.resolve_type_vars_or_error(expr.hir_id, self.cx.typeck_results().expr_ty_opt(expr)) } - fn expr_ty_adjusted(&self, expr: &hir::Expr<'_>) -> Result, ErrorGuaranteed> { + fn expr_ty_adjusted(&self, expr: &hir::Expr<'_>) -> Result, Cx::Error> { self.resolve_type_vars_or_error( expr.hir_id, self.cx.typeck_results().expr_ty_adjusted_opt(expr), @@ -1129,7 +1170,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx /// implicit deref patterns attached (e.g., it is really /// `&Some(x)`). In that case, we return the "outermost" type /// (e.g., `&Option`). - fn pat_ty_adjusted(&self, pat: &hir::Pat<'_>) -> Result, ErrorGuaranteed> { + fn pat_ty_adjusted(&self, pat: &hir::Pat<'_>) -> Result, Cx::Error> { // Check for implicit `&` types wrapping the pattern; note // that these are never attached to binding patterns, so // actually this is somewhat "disjoint" from the code below @@ -1145,7 +1186,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx } /// Like `TypeckResults::pat_ty`, but ignores implicit `&` patterns. - fn pat_ty_unadjusted(&self, pat: &hir::Pat<'_>) -> Result, ErrorGuaranteed> { + fn pat_ty_unadjusted(&self, pat: &hir::Pat<'_>) -> Result, Cx::Error> { let base_ty = self.node_ty(pat.hir_id)?; trace!(?base_ty); @@ -1174,9 +1215,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx debug!("By-ref binding of non-derefable type"); Err(self .cx - .tcx() - .dcx() - .span_delayed_bug(pat.span, "by-ref binding of non-derefable type")) + .report_error(pat.span, "by-ref binding of non-derefable type")) } } } else { @@ -1187,7 +1226,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx } } - fn cat_expr(&self, expr: &hir::Expr<'_>) -> Result, ErrorGuaranteed> { + fn cat_expr(&self, expr: &hir::Expr<'_>) -> Result, Cx::Error> { self.cat_expr_(expr, self.cx.typeck_results().expr_adjustments(expr)) } @@ -1197,7 +1236,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx &self, expr: &hir::Expr<'_>, adjustments: &[adjustment::Adjustment<'tcx>], - ) -> Result, ErrorGuaranteed> { + ) -> Result, Cx::Error> { match adjustments.split_last() { None => self.cat_expr_unadjusted(expr), Some((adjustment, previous)) => { @@ -1211,7 +1250,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx expr: &hir::Expr<'_>, previous: PlaceWithHirId<'tcx>, adjustment: &adjustment::Adjustment<'tcx>, - ) -> Result, ErrorGuaranteed> { + ) -> Result, Cx::Error> { self.cat_expr_adjusted_with(expr, || Ok(previous), adjustment) } @@ -1220,9 +1259,9 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx expr: &hir::Expr<'_>, previous: F, adjustment: &adjustment::Adjustment<'tcx>, - ) -> Result, ErrorGuaranteed> + ) -> Result, Cx::Error> where - F: FnOnce() -> Result, ErrorGuaranteed>, + F: FnOnce() -> Result, Cx::Error>, { let target = self.cx.resolve_vars_if_possible(adjustment.target); match adjustment.kind { @@ -1247,10 +1286,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx } } - fn cat_expr_unadjusted( - &self, - expr: &hir::Expr<'_>, - ) -> Result, ErrorGuaranteed> { + fn cat_expr_unadjusted(&self, expr: &hir::Expr<'_>) -> Result, Cx::Error> { let expr_ty = self.expr_ty(expr)?; match expr.kind { hir::ExprKind::Unary(hir::UnOp::Deref, e_base) => { @@ -1341,7 +1377,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx span: Span, expr_ty: Ty<'tcx>, res: Res, - ) -> Result, ErrorGuaranteed> { + ) -> Result, Cx::Error> { match res { Res::Def( DefKind::Ctor(..) @@ -1375,11 +1411,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx /// Note: the actual upvar access contains invisible derefs of closure /// environment and upvar reference as appropriate. Only regionck cares /// about these dereferences, so we let it compute them as needed. - fn cat_upvar( - &self, - hir_id: HirId, - var_id: HirId, - ) -> Result, ErrorGuaranteed> { + fn cat_upvar(&self, hir_id: HirId, var_id: HirId) -> Result, Cx::Error> { let closure_expr_def_id = self.cx.body_owner_def_id(); let upvar_id = ty::UpvarId { @@ -1428,7 +1460,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx &self, expr: &hir::Expr<'_>, base: &hir::Expr<'_>, - ) -> Result, ErrorGuaranteed> { + ) -> Result, Cx::Error> { // Reconstruct the output assuming it's a reference with the // same region and mutability as the receiver. This holds for // `Deref(Mut)::Deref(_mut)` and `Index(Mut)::index(_mut)`. @@ -1450,7 +1482,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx &self, node: HirId, base_place: PlaceWithHirId<'tcx>, - ) -> Result, ErrorGuaranteed> { + ) -> Result, Cx::Error> { let base_curr_ty = base_place.place.ty(); let deref_ty = match self .cx @@ -1463,7 +1495,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx Some(ty) => ty, None => { debug!("explicit deref of non-derefable type: {:?}", base_curr_ty); - return Err(self.cx.tcx().dcx().span_delayed_bug( + return Err(self.cx.report_error( self.cx.tcx().hir().span(node), "explicit deref of non-derefable type", )); @@ -1482,15 +1514,13 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx qpath: &hir::QPath<'_>, pat_hir_id: HirId, span: Span, - ) -> Result { + ) -> Result { let res = self.cx.typeck_results().qpath_res(qpath, pat_hir_id); let ty = self.cx.typeck_results().node_type(pat_hir_id); let ty::Adt(adt_def, _) = self.cx.try_structurally_resolve_type(span, ty).kind() else { return Err(self .cx - .tcx() - .dcx() - .span_delayed_bug(span, "struct or tuple struct pattern not applied to an ADT")); + .report_error(span, "struct or tuple struct pattern not applied to an ADT")); }; match res { @@ -1517,7 +1547,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx pat_hir_id: HirId, variant_index: VariantIdx, span: Span, - ) -> Result { + ) -> Result { let ty = self.cx.typeck_results().node_type(pat_hir_id); match self.cx.try_structurally_resolve_type(span, ty).kind() { ty::Adt(adt_def, _) => Ok(adt_def.variant(variant_index).fields.len()), @@ -1532,19 +1562,11 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx /// Returns the total number of fields in a tuple used within a Tuple pattern. /// Here `pat_hir_id` is the HirId of the pattern itself. - fn total_fields_in_tuple( - &self, - pat_hir_id: HirId, - span: Span, - ) -> Result { + fn total_fields_in_tuple(&self, pat_hir_id: HirId, span: Span) -> Result { let ty = self.cx.typeck_results().node_type(pat_hir_id); match self.cx.try_structurally_resolve_type(span, ty).kind() { ty::Tuple(args) => Ok(args.len()), - _ => Err(self - .cx - .tcx() - .dcx() - .span_delayed_bug(span, "tuple pattern not applied to a tuple")), + _ => Err(self.cx.report_error(span, "tuple pattern not applied to a tuple")), } } @@ -1559,9 +1581,9 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx mut place_with_id: PlaceWithHirId<'tcx>, pat: &hir::Pat<'_>, op: &mut F, - ) -> Result<(), ErrorGuaranteed> + ) -> Result<(), Cx::Error> where - F: FnMut(&PlaceWithHirId<'tcx>, &hir::Pat<'_>), + F: FnMut(&PlaceWithHirId<'tcx>, &hir::Pat<'_>) -> Result<(), Cx::Error>, { // If (pattern) adjustments are active for this pattern, adjust the `PlaceWithHirId` correspondingly. // `PlaceWithHirId`s are constructed differently from patterns. For example, in @@ -1613,7 +1635,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx // `Some(x)` (which matches). Recursing once more, `*&Some(3)` and the pattern `Some(x)` // result in the place `Downcast(*&Some(3)).0` associated to `x` and invoke `op` with // that (where the `ref` on `x` is implied). - op(&place_with_id, pat); + op(&place_with_id, pat)?; match pat.kind { PatKind::Tuple(subpats, dots_pos) => { @@ -1712,9 +1734,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx debug!("explicit index of non-indexable type {:?}", place_with_id); return Err(self .cx - .tcx() - .dcx() - .span_delayed_bug(pat.span, "explicit index of non-indexable type")); + .report_error(pat.span, "explicit index of non-indexable type")); }; let elt_place = self.cat_projection( pat.hir_id, diff --git a/compiler/rustc_hir_typeck/src/upvar.rs b/compiler/rustc_hir_typeck/src/upvar.rs index 9f710732a0ef5..819a8b661167c 100644 --- a/compiler/rustc_hir_typeck/src/upvar.rs +++ b/compiler/rustc_hir_typeck/src/upvar.rs @@ -252,7 +252,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } - euv::ExprUseVisitor::new( + let _ = euv::ExprUseVisitor::new( &FnCtxt::new(self, self.tcx.param_env(closure_def_id), closure_def_id), &mut delegate, ) diff --git a/src/tools/clippy/clippy_lints/src/escape.rs b/src/tools/clippy/clippy_lints/src/escape.rs index 6392ca13df18a..6715de52649d4 100644 --- a/src/tools/clippy/clippy_lints/src/escape.rs +++ b/src/tools/clippy/clippy_lints/src/escape.rs @@ -104,7 +104,7 @@ impl<'tcx> LateLintPass<'tcx> for BoxedLocal { too_large_for_stack: self.too_large_for_stack, }; - ExprUseVisitor::for_clippy(cx, fn_def_id, &mut v).consume_body(body); + ExprUseVisitor::for_clippy(cx, fn_def_id, &mut v).consume_body(body).into_ok(); for node in v.set { span_lint_hir( diff --git a/src/tools/clippy/clippy_lints/src/lib.rs b/src/tools/clippy/clippy_lints/src/lib.rs index 2c44c3881aa77..a8bfbbdd9ecab 100644 --- a/src/tools/clippy/clippy_lints/src/lib.rs +++ b/src/tools/clippy/clippy_lints/src/lib.rs @@ -8,6 +8,7 @@ #![feature(never_type)] #![feature(rustc_private)] #![feature(stmt_expr_attributes)] +#![feature(unwrap_infallible)] #![recursion_limit = "512"] #![cfg_attr(feature = "deny-warnings", deny(warnings))] #![allow( diff --git a/src/tools/clippy/clippy_lints/src/loops/mut_range_bound.rs b/src/tools/clippy/clippy_lints/src/loops/mut_range_bound.rs index 082c5977cbdee..6b9ecf5f14130 100644 --- a/src/tools/clippy/clippy_lints/src/loops/mut_range_bound.rs +++ b/src/tools/clippy/clippy_lints/src/loops/mut_range_bound.rs @@ -65,7 +65,7 @@ fn check_for_mutation( body.hir_id.owner.def_id, &mut delegate, ) - .walk_expr(body); + .walk_expr(body).into_ok(); delegate.mutation_span() } diff --git a/src/tools/clippy/clippy_lints/src/methods/iter_overeager_cloned.rs b/src/tools/clippy/clippy_lints/src/methods/iter_overeager_cloned.rs index d4c709de97f51..a52d38790a2bd 100644 --- a/src/tools/clippy/clippy_lints/src/methods/iter_overeager_cloned.rs +++ b/src/tools/clippy/clippy_lints/src/methods/iter_overeager_cloned.rs @@ -9,7 +9,6 @@ use rustc_lint::LateContext; use rustc_middle::mir::{FakeReadCause, Mutability}; use rustc_middle::ty::{self, BorrowKind}; use rustc_span::sym; -use rustc_trait_selection::infer::TyCtxtInferExt; use super::ITER_OVEREAGER_CLONED; use crate::redundant_clone::REDUNDANT_CLONE; @@ -75,7 +74,7 @@ pub(super) fn check<'tcx>( closure.def_id, &mut delegate, ) - .consume_body(body); + .consume_body(body).into_ok(); let mut to_be_discarded = false; diff --git a/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs b/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs index 5e786c1277acb..9b852f52ea1eb 100644 --- a/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs +++ b/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs @@ -117,7 +117,7 @@ fn check_closures<'tcx>( .associated_body() .map(|(_, body_id)| hir.body(body_id)) { - euv::ExprUseVisitor::for_clippy(cx, closure, &mut *ctx).consume_body(body); + euv::ExprUseVisitor::for_clippy(cx, closure, &mut *ctx).consume_body(body).into_ok(); } } } @@ -194,7 +194,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByRefMut<'tcx> { async_closures: FxHashSet::default(), tcx: cx.tcx, }; - euv::ExprUseVisitor::for_clippy(cx, fn_def_id, &mut ctx).consume_body(body); + euv::ExprUseVisitor::for_clippy(cx, fn_def_id, &mut ctx).consume_body(body).into_ok(); let mut checked_closures = FxHashSet::default(); diff --git a/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs b/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs index 60523ae0d0e2e..0986571d0f281 100644 --- a/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs +++ b/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs @@ -133,7 +133,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue { // function body. let MovedVariablesCtxt { moved_vars } = { let mut ctx = MovedVariablesCtxt::default(); - euv::ExprUseVisitor::for_clippy(cx, fn_def_id, &mut ctx).consume_body(body); + euv::ExprUseVisitor::for_clippy(cx, fn_def_id, &mut ctx).consume_body(body).into_ok(); ctx }; diff --git a/src/tools/clippy/clippy_lints/src/operators/assign_op_pattern.rs b/src/tools/clippy/clippy_lints/src/operators/assign_op_pattern.rs index 6d617447bb5fb..910e584a7a0f9 100644 --- a/src/tools/clippy/clippy_lints/src/operators/assign_op_pattern.rs +++ b/src/tools/clippy/clippy_lints/src/operators/assign_op_pattern.rs @@ -119,7 +119,7 @@ fn imm_borrows_in_expr(cx: &LateContext<'_>, e: &hir::Expr<'_>) -> HirIdSet { let mut s = S(HirIdSet::default()); let v = ExprUseVisitor::for_clippy(cx, e.hir_id.owner.def_id, &mut s); - v.consume_expr(e); + v.consume_expr(e).into_ok(); s.0 } @@ -144,6 +144,6 @@ fn mut_borrows_in_expr(cx: &LateContext<'_>, e: &hir::Expr<'_>) -> HirIdSet { let mut s = S(HirIdSet::default()); let v = ExprUseVisitor::for_clippy(cx, e.hir_id.owner.def_id, &mut s); - v.consume_expr(e); + v.consume_expr(e).into_ok(); s.0 } diff --git a/src/tools/clippy/clippy_lints/src/unwrap.rs b/src/tools/clippy/clippy_lints/src/unwrap.rs index aa5555d65f63d..5b2841dcd8330 100644 --- a/src/tools/clippy/clippy_lints/src/unwrap.rs +++ b/src/tools/clippy/clippy_lints/src/unwrap.rs @@ -256,8 +256,8 @@ impl<'a, 'tcx> UnwrappableVariablesVisitor<'a, 'tcx> { cond.hir_id.owner.def_id, &mut delegate, ); - vis.walk_expr(cond); - vis.walk_expr(branch); + vis.walk_expr(cond).into_ok(); + vis.walk_expr(branch).into_ok(); if delegate.is_mutated { // if the variable is mutated, we don't know whether it can be unwrapped. diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs index a49414a058b1c..99d7aba2f7a15 100644 --- a/src/tools/clippy/clippy_utils/src/lib.rs +++ b/src/tools/clippy/clippy_utils/src/lib.rs @@ -7,6 +7,7 @@ #![feature(never_type)] #![feature(rustc_private)] #![feature(assert_matches)] +#![feature(unwrap_infallible)] #![recursion_limit = "512"] #![cfg_attr(feature = "deny-warnings", deny(warnings))] #![allow( diff --git a/src/tools/clippy/clippy_utils/src/sugg.rs b/src/tools/clippy/clippy_utils/src/sugg.rs index 49b0eb05d2acc..bf03c6c16015c 100644 --- a/src/tools/clippy/clippy_utils/src/sugg.rs +++ b/src/tools/clippy/clippy_utils/src/sugg.rs @@ -830,7 +830,9 @@ pub fn deref_closure_args(cx: &LateContext<'_>, closure: &hir::Expr<'_>) -> Opti applicability: Applicability::MachineApplicable, }; - ExprUseVisitor::for_clippy(cx, def_id, &mut visitor).consume_body(closure_body); + ExprUseVisitor::for_clippy(cx, def_id, &mut visitor) + .consume_body(closure_body) + .into_ok(); if !visitor.suggestion_start.is_empty() { return Some(DerefClosure { diff --git a/src/tools/clippy/clippy_utils/src/usage.rs b/src/tools/clippy/clippy_utils/src/usage.rs index d0ab6d434aab6..9abb4ef9b8d3a 100644 --- a/src/tools/clippy/clippy_utils/src/usage.rs +++ b/src/tools/clippy/clippy_utils/src/usage.rs @@ -21,7 +21,8 @@ pub fn mutated_variables<'tcx>(expr: &'tcx Expr<'_>, cx: &LateContext<'tcx>) -> expr.hir_id.owner.def_id, &mut delegate, ) - .walk_expr(expr); + .walk_expr(expr) + .into_ok(); if delegate.skip { return None; diff --git a/tests/crashes/123901.rs b/tests/crashes/123901.rs deleted file mode 100644 index 06722f0bf2925..0000000000000 --- a/tests/crashes/123901.rs +++ /dev/null @@ -1,8 +0,0 @@ -//@ known-bug: #123901 -//@ edition:2021 - -pub fn test(test: &u64, temp: &u64) { - async |check, a, b| { - temp.abs_diff(12); - }; -} diff --git a/tests/ui/async-await/async-closures/ambiguous-arg.rs b/tests/ui/async-await/async-closures/ambiguous-arg.rs new file mode 100644 index 0000000000000..d76a1cf953e46 --- /dev/null +++ b/tests/ui/async-await/async-closures/ambiguous-arg.rs @@ -0,0 +1,15 @@ +//@ edition:2021 + +// Regression test for #123901. We previously ICE'd as we silently +// swallowed an in the `ExprUseVisitor`. + +#![feature(async_closure)] + +pub fn test(test: &u64, temp: &u64) { + async |check, a, b| { + //~^ ERROR type annotations needed + temp.abs_diff(12); + }; +} + +fn main() {} diff --git a/tests/ui/async-await/async-closures/ambiguous-arg.stderr b/tests/ui/async-await/async-closures/ambiguous-arg.stderr new file mode 100644 index 0000000000000..01f72e94eccf7 --- /dev/null +++ b/tests/ui/async-await/async-closures/ambiguous-arg.stderr @@ -0,0 +1,13 @@ +error[E0282]: type annotations needed + --> $DIR/ambiguous-arg.rs:9:25 + | +LL | async |check, a, b| { + | _________________________^ +LL | | +LL | | temp.abs_diff(12); +LL | | }; + | |_____^ cannot infer type + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0282`. From df88c118673c430fadefd98f7a29f436e63f14a2 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sun, 12 May 2024 18:57:24 +0200 Subject: [PATCH 131/179] Use the target cpu from the target spec on x86_64 when -Ctarget-cpu isn't used Fixes rust-lang/rustc_codegen_cranelift#1148 --- src/lib.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index e72951b6f3447..39bbad16b0c00 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -331,9 +331,9 @@ fn build_isa(sess: &Session, backend_config: &BackendConfig) -> Arc Date: Sun, 12 May 2024 19:07:11 +0200 Subject: [PATCH 132/179] docs: fix typo in platform-support docs --- src/doc/rustc/src/platform-support/x86_64-unknown-linux-none.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustc/src/platform-support/x86_64-unknown-linux-none.md b/src/doc/rustc/src/platform-support/x86_64-unknown-linux-none.md index ef8fd3aa2e384..90bafa7e4fba8 100644 --- a/src/doc/rustc/src/platform-support/x86_64-unknown-linux-none.md +++ b/src/doc/rustc/src/platform-support/x86_64-unknown-linux-none.md @@ -2,7 +2,7 @@ **Tier: 3** -Freestanding x86-64 linux binary with no depedency on libc. +Freestanding x86-64 linux binary with no dependency on libc. ## Target maintainers From 68854b798ebda70014985d26722e7f6820254658 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Sun, 12 May 2024 13:24:36 -0700 Subject: [PATCH 133/179] Add AST pretty-printer tests for let-else --- tests/ui/macros/stringify.rs | 15 +++++++++++++++ .../{pretty-let-else.rs => let-else-hir.rs} | 0 ...pretty-let-else.stdout => let-else-hir.stdout} | 0 tests/ui/unpretty/let-else.rs | 11 +++++++++++ tests/ui/unpretty/let-else.stdout | 15 +++++++++++++++ 5 files changed, 41 insertions(+) rename tests/ui/unpretty/{pretty-let-else.rs => let-else-hir.rs} (100%) rename tests/ui/unpretty/{pretty-let-else.stdout => let-else-hir.stdout} (100%) create mode 100644 tests/ui/unpretty/let-else.rs create mode 100644 tests/ui/unpretty/let-else.stdout diff --git a/tests/ui/macros/stringify.rs b/tests/ui/macros/stringify.rs index 472cb4d417be8..6b215ba525deb 100644 --- a/tests/ui/macros/stringify.rs +++ b/tests/ui/macros/stringify.rs @@ -675,6 +675,11 @@ fn test_stmt() { "let (a, b): (u32, u32) = (1, 2);", "let (a, b): (u32, u32) = (1, 2)" ); + c2!(stmt, + [ let _ = f() else { return; } ], + "let _ = f() else { return; };", + "let _ = f() else { return; }", + ); macro_rules! c2_let_expr_minus_one { ([ $expr:expr ], $stmt_expected:expr, $tokens_expected:expr $(,)?) => { c2!(stmt, [ let _ = $expr - 1 ], $stmt_expected, $tokens_expected); @@ -685,6 +690,16 @@ fn test_stmt() { "let _ = match void {} - 1;", "let _ = match void {} - 1", ); + macro_rules! c2_let_expr_else_return { + ([ $expr:expr ], $stmt_expected:expr, $tokens_expected:expr $(,)?) => { + c2!(stmt, [ let _ = $expr else { return; } ], $stmt_expected, $tokens_expected); + }; + } + c2_let_expr_else_return!( + [ f() ], + "let _ = f() else { return; };", + "let _ = f() else { return; }", + ); // StmtKind::Item c1!(stmt, [ struct S; ], "struct S;"); diff --git a/tests/ui/unpretty/pretty-let-else.rs b/tests/ui/unpretty/let-else-hir.rs similarity index 100% rename from tests/ui/unpretty/pretty-let-else.rs rename to tests/ui/unpretty/let-else-hir.rs diff --git a/tests/ui/unpretty/pretty-let-else.stdout b/tests/ui/unpretty/let-else-hir.stdout similarity index 100% rename from tests/ui/unpretty/pretty-let-else.stdout rename to tests/ui/unpretty/let-else-hir.stdout diff --git a/tests/ui/unpretty/let-else.rs b/tests/ui/unpretty/let-else.rs new file mode 100644 index 0000000000000..4db6eca99b18f --- /dev/null +++ b/tests/ui/unpretty/let-else.rs @@ -0,0 +1,11 @@ +//@ compile-flags: -Zunpretty=expanded +//@ check-pass + +macro_rules! expr { + ($e:expr) => { $e }; +} + +fn main() { + let _ = expr!(1 + 1) else { return; }; + let _ = expr!(loop {}) else { return; }; +} diff --git a/tests/ui/unpretty/let-else.stdout b/tests/ui/unpretty/let-else.stdout new file mode 100644 index 0000000000000..5f6972cd4295f --- /dev/null +++ b/tests/ui/unpretty/let-else.stdout @@ -0,0 +1,15 @@ +#![feature(prelude_import)] +#![no_std] +#[prelude_import] +use ::std::prelude::rust_2015::*; +#[macro_use] +extern crate std; +//@ compile-flags: -Zunpretty=expanded +//@ check-pass + +macro_rules! expr { ($e:expr) => { $e }; } + +fn main() { + let _ = 1 + 1 else { return; }; + let _ = loop {} else { return; }; +} From 94cc82c088b9301dc4dcf84ce127a64bbd77dddf Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Sun, 12 May 2024 13:39:43 -0700 Subject: [PATCH 134/179] Pretty-print let-else with added parenthesization when needed --- compiler/rustc_ast_pretty/src/pprust/state.rs | 6 +++++- tests/ui/unpretty/let-else.stdout | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index 2c176828c841f..b7bdb2e14a6da 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -1238,7 +1238,11 @@ impl<'a> State<'a> { if let Some((init, els)) = loc.kind.init_else_opt() { self.nbsp(); self.word_space("="); - self.print_expr(init, FixupContext::default()); + self.print_expr_cond_paren( + init, + els.is_some() && classify::expr_trailing_brace(init).is_some(), + FixupContext::default(), + ); if let Some(els) = els { self.cbox(INDENT_UNIT); self.ibox(INDENT_UNIT); diff --git a/tests/ui/unpretty/let-else.stdout b/tests/ui/unpretty/let-else.stdout index 5f6972cd4295f..4bc4d9e085f97 100644 --- a/tests/ui/unpretty/let-else.stdout +++ b/tests/ui/unpretty/let-else.stdout @@ -11,5 +11,5 @@ macro_rules! expr { ($e:expr) => { $e }; } fn main() { let _ = 1 + 1 else { return; }; - let _ = loop {} else { return; }; + let _ = (loop {}) else { return; }; } From f12e9357955c915bb5b34f5917eb016647410c71 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 8 May 2024 19:16:20 +1000 Subject: [PATCH 135/179] Remove a stray backtick in an error explanation. --- compiler/rustc_error_codes/src/error_codes/E0457.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_error_codes/src/error_codes/E0457.md b/compiler/rustc_error_codes/src/error_codes/E0457.md index e2dbf53a0f8c2..47bff4bc49f96 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0457.md +++ b/compiler/rustc_error_codes/src/error_codes/E0457.md @@ -1,4 +1,4 @@ -#### Note: this error code is no longer emitted by the compiler` +#### Note: this error code is no longer emitted by the compiler Plugin `..` only found in rlib format, but must be available in dylib format. From 4497d345a8196554021f6d145b86bfc814c954d3 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 8 May 2024 19:03:14 +1000 Subject: [PATCH 136/179] Remove `extern crate rustc_middle` from `rustc_const_eval`. This requires exporting the interpreter macros so they can be used with `use crate::interpret::*`. --- .../src/const_eval/dummy_machine.rs | 5 ++- .../rustc_const_eval/src/const_eval/error.rs | 1 + .../src/const_eval/eval_queries.rs | 3 +- .../src/const_eval/machine.rs | 6 ++- .../rustc_const_eval/src/const_eval/mod.rs | 1 + .../src/const_eval/valtrees.rs | 1 + .../rustc_const_eval/src/interpret/cast.rs | 4 +- .../src/interpret/discriminant.rs | 5 ++- .../src/interpret/eval_context.rs | 8 ++-- .../rustc_const_eval/src/interpret/intern.rs | 2 +- .../src/interpret/intrinsics.rs | 8 ++-- .../rustc_const_eval/src/interpret/machine.rs | 6 +-- .../rustc_const_eval/src/interpret/memory.rs | 8 ++-- .../rustc_const_eval/src/interpret/operand.rs | 7 ++-- .../src/interpret/operator.rs | 3 +- .../rustc_const_eval/src/interpret/place.rs | 8 ++-- .../src/interpret/projection.rs | 6 ++- .../rustc_const_eval/src/interpret/step.rs | 1 + .../src/interpret/terminator.rs | 6 ++- .../rustc_const_eval/src/interpret/util.rs | 3 +- .../src/interpret/validity.rs | 7 ++-- .../rustc_const_eval/src/interpret/visitor.rs | 2 +- compiler/rustc_const_eval/src/lib.rs | 2 - .../src/transform/check_consts/check.rs | 1 + .../src/transform/check_consts/mod.rs | 1 + .../src/transform/check_consts/ops.rs | 1 + .../src/transform/check_consts/qualifs.rs | 1 + .../src/transform/validate.rs | 1 + .../src/util/caller_location.rs | 1 + .../src/util/check_validity_requirement.rs | 1 + .../rustc_const_eval/src/util/type_name.rs | 1 + .../rustc_middle/src/mir/interpret/mod.rs | 38 +++++++++++++------ 32 files changed, 101 insertions(+), 48 deletions(-) diff --git a/compiler/rustc_const_eval/src/const_eval/dummy_machine.rs b/compiler/rustc_const_eval/src/const_eval/dummy_machine.rs index afc60d33647a7..94c9f056b302e 100644 --- a/compiler/rustc_const_eval/src/const_eval/dummy_machine.rs +++ b/compiler/rustc_const_eval/src/const_eval/dummy_machine.rs @@ -1,9 +1,12 @@ -use crate::interpret::{self, HasStaticRootDefId, ImmTy, Immediate, InterpCx, PointerArithmetic}; +use crate::interpret::{ + self, throw_machine_stop, HasStaticRootDefId, ImmTy, Immediate, InterpCx, PointerArithmetic, +}; use rustc_middle::mir::interpret::{AllocId, ConstAllocation, InterpResult}; use rustc_middle::mir::*; use rustc_middle::query::TyCtxtAt; use rustc_middle::ty; use rustc_middle::ty::layout::TyAndLayout; +use rustc_middle::{bug, span_bug}; use rustc_span::def_id::DefId; /// Macro for machine-specific `InterpError` without allocation. diff --git a/compiler/rustc_const_eval/src/const_eval/error.rs b/compiler/rustc_const_eval/src/const_eval/error.rs index 2c9eb393e4a14..08c9609eacfa4 100644 --- a/compiler/rustc_const_eval/src/const_eval/error.rs +++ b/compiler/rustc_const_eval/src/const_eval/error.rs @@ -11,6 +11,7 @@ use rustc_span::{Span, Symbol}; use super::CompileTimeInterpreter; use crate::errors::{self, FrameNote, ReportErrorExt}; +use crate::interpret::{err_inval, err_machine_stop}; use crate::interpret::{ErrorHandled, Frame, InterpError, InterpErrorInfo, MachineStopType}; /// The CTFE machine has some custom error kinds. diff --git a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs index d9f329c8b0e0f..6a9a21bbd8e06 100644 --- a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs +++ b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs @@ -3,6 +3,7 @@ use std::sync::atomic::Ordering::Relaxed; use either::{Left, Right}; use rustc_hir::def::DefKind; +use rustc_middle::bug; use rustc_middle::mir::interpret::{AllocId, ErrorHandled, InterpErrorInfo}; use rustc_middle::mir::{self, ConstAlloc, ConstValue}; use rustc_middle::query::TyCtxtAt; @@ -24,7 +25,7 @@ use crate::interpret::{ InternKind, InterpCx, InterpError, InterpResult, MPlaceTy, MemoryKind, OpTy, RefTracking, StackPopCleanup, }; -use crate::interpret::{eval_nullary_intrinsic, InternResult}; +use crate::interpret::{eval_nullary_intrinsic, throw_exhaust, InternResult}; use crate::CTRL_C_RECEIVED; // Returns a pointer to where the result lives diff --git a/compiler/rustc_const_eval/src/const_eval/machine.rs b/compiler/rustc_const_eval/src/const_eval/machine.rs index 6e6fa70107b7e..836e548ae2b7f 100644 --- a/compiler/rustc_const_eval/src/const_eval/machine.rs +++ b/compiler/rustc_const_eval/src/const_eval/machine.rs @@ -10,6 +10,7 @@ use rustc_hir::def::DefKind; use rustc_hir::def_id::DefId; use rustc_hir::def_id::LocalDefId; use rustc_hir::LangItem; +use rustc_middle::bug; use rustc_middle::mir; use rustc_middle::mir::AssertMessage; use rustc_middle::query::TyCtxtAt; @@ -24,8 +25,9 @@ use rustc_target::spec::abi::Abi as CallAbi; use crate::errors::{LongRunning, LongRunningWarn}; use crate::fluent_generated as fluent; use crate::interpret::{ - self, compile_time_machine, AllocId, AllocRange, ConstAllocation, CtfeProvenance, FnArg, FnVal, - Frame, ImmTy, InterpCx, InterpResult, MPlaceTy, OpTy, Pointer, PointerArithmetic, Scalar, + self, compile_time_machine, err_ub, throw_exhaust, throw_inval, throw_ub_custom, + throw_unsup_format, AllocId, AllocRange, ConstAllocation, CtfeProvenance, FnArg, FnVal, Frame, + ImmTy, InterpCx, InterpResult, MPlaceTy, OpTy, Pointer, PointerArithmetic, Scalar, }; use super::error::*; diff --git a/compiler/rustc_const_eval/src/const_eval/mod.rs b/compiler/rustc_const_eval/src/const_eval/mod.rs index 8efc67bcb0c4d..a5c8c0bb82ad7 100644 --- a/compiler/rustc_const_eval/src/const_eval/mod.rs +++ b/compiler/rustc_const_eval/src/const_eval/mod.rs @@ -1,5 +1,6 @@ // Not in interpret to make sure we do not use private implementation details +use rustc_middle::bug; use rustc_middle::mir; use rustc_middle::mir::interpret::InterpErrorInfo; use rustc_middle::query::{Key, TyCtxtAt}; diff --git a/compiler/rustc_const_eval/src/const_eval/valtrees.rs b/compiler/rustc_const_eval/src/const_eval/valtrees.rs index dcfce4e35e05d..fbf2ca5ab0a62 100644 --- a/compiler/rustc_const_eval/src/const_eval/valtrees.rs +++ b/compiler/rustc_const_eval/src/const_eval/valtrees.rs @@ -1,4 +1,5 @@ use rustc_data_structures::stack::ensure_sufficient_stack; +use rustc_middle::bug; use rustc_middle::mir; use rustc_middle::mir::interpret::{EvalToValTreeResult, GlobalId}; use rustc_middle::ty::layout::{LayoutCx, LayoutOf, TyAndLayout}; diff --git a/compiler/rustc_const_eval/src/interpret/cast.rs b/compiler/rustc_const_eval/src/interpret/cast.rs index 76e59ea90559f..799e12f9ac97b 100644 --- a/compiler/rustc_const_eval/src/interpret/cast.rs +++ b/compiler/rustc_const_eval/src/interpret/cast.rs @@ -7,11 +7,13 @@ use rustc_middle::mir::CastKind; use rustc_middle::ty::adjustment::PointerCoercion; use rustc_middle::ty::layout::{IntegerExt, LayoutOf, TyAndLayout}; use rustc_middle::ty::{self, FloatTy, Ty}; +use rustc_middle::{bug, span_bug}; use rustc_target::abi::Integer; use rustc_type_ir::TyKind::*; use super::{ - util::ensure_monomorphic_enough, FnVal, ImmTy, Immediate, InterpCx, Machine, OpTy, PlaceTy, + err_inval, throw_ub, throw_ub_custom, util::ensure_monomorphic_enough, FnVal, ImmTy, Immediate, + InterpCx, Machine, OpTy, PlaceTy, }; use crate::fluent_generated as fluent; diff --git a/compiler/rustc_const_eval/src/interpret/discriminant.rs b/compiler/rustc_const_eval/src/interpret/discriminant.rs index caacc6f57d3c2..8ddc741de239a 100644 --- a/compiler/rustc_const_eval/src/interpret/discriminant.rs +++ b/compiler/rustc_const_eval/src/interpret/discriminant.rs @@ -1,12 +1,15 @@ //! Functions for reading and writing discriminants of multi-variant layouts (enums and coroutines). use rustc_middle::mir; +use rustc_middle::span_bug; use rustc_middle::ty::layout::{LayoutOf, PrimitiveExt}; use rustc_middle::ty::{self, ScalarInt, Ty}; use rustc_target::abi::{self, TagEncoding}; use rustc_target::abi::{VariantIdx, Variants}; -use super::{ImmTy, InterpCx, InterpResult, Machine, Readable, Scalar, Writeable}; +use super::{ + err_ub, throw_ub, ImmTy, InterpCx, InterpResult, Machine, Readable, Scalar, Writeable, +}; impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { /// Writes the discriminant of the given variant. diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs index 126d64329f815..344bb7cd98be9 100644 --- a/compiler/rustc_const_eval/src/interpret/eval_context.rs +++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs @@ -17,15 +17,17 @@ use rustc_middle::ty::layout::{ TyAndLayout, }; use rustc_middle::ty::{self, GenericArgsRef, ParamEnv, Ty, TyCtxt, TypeFoldable, Variance}; +use rustc_middle::{bug, span_bug}; use rustc_mir_dataflow::storage::always_storage_live_locals; use rustc_session::Limit; use rustc_span::Span; use rustc_target::abi::{call::FnAbi, Align, HasDataLayout, Size, TargetDataLayout}; use super::{ - GlobalId, Immediate, InterpErrorInfo, InterpResult, MPlaceTy, Machine, MemPlace, MemPlaceMeta, - Memory, MemoryKind, OpTy, Operand, Place, PlaceTy, Pointer, PointerArithmetic, Projectable, - Provenance, Scalar, StackPopJump, + err_inval, throw_inval, throw_ub, throw_ub_custom, throw_unsup, GlobalId, Immediate, + InterpErrorInfo, InterpResult, MPlaceTy, Machine, MemPlace, MemPlaceMeta, Memory, MemoryKind, + OpTy, Operand, Place, PlaceTy, Pointer, PointerArithmetic, Projectable, Provenance, Scalar, + StackPopJump, }; use crate::errors; use crate::util; diff --git a/compiler/rustc_const_eval/src/interpret/intern.rs b/compiler/rustc_const_eval/src/interpret/intern.rs index d4168273f29fb..3565b4fb51657 100644 --- a/compiler/rustc_const_eval/src/interpret/intern.rs +++ b/compiler/rustc_const_eval/src/interpret/intern.rs @@ -24,7 +24,7 @@ use rustc_middle::ty::layout::TyAndLayout; use rustc_span::def_id::LocalDefId; use rustc_span::sym; -use super::{AllocId, Allocation, InterpCx, MPlaceTy, Machine, MemoryKind, PlaceTy}; +use super::{err_ub, AllocId, Allocation, InterpCx, MPlaceTy, Machine, MemoryKind, PlaceTy}; use crate::const_eval; use crate::errors::NestedStaticInThreadLocal; diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs index 52c31629d547c..dce4d56f7e007 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs @@ -8,6 +8,7 @@ use rustc_middle::ty::layout::{LayoutOf as _, ValidityRequirement}; use rustc_middle::ty::GenericArgsRef; use rustc_middle::ty::{Ty, TyCtxt}; use rustc_middle::{ + bug, mir::{self, BinOp, ConstValue, NonDivergingIntrinsic}, ty::layout::TyAndLayout, }; @@ -15,9 +16,10 @@ use rustc_span::symbol::{sym, Symbol}; use rustc_target::abi::Size; use super::{ - memory::MemoryKind, util::ensure_monomorphic_enough, Allocation, CheckInAllocMsg, - ConstAllocation, GlobalId, ImmTy, InterpCx, InterpResult, MPlaceTy, Machine, OpTy, Pointer, - PointerArithmetic, Scalar, + err_inval, err_ub_custom, err_unsup_format, memory::MemoryKind, throw_inval, throw_ub_custom, + throw_ub_format, util::ensure_monomorphic_enough, Allocation, CheckInAllocMsg, ConstAllocation, + GlobalId, ImmTy, InterpCx, InterpResult, MPlaceTy, Machine, OpTy, Pointer, PointerArithmetic, + Scalar, }; use crate::fluent_generated as fluent; diff --git a/compiler/rustc_const_eval/src/interpret/machine.rs b/compiler/rustc_const_eval/src/interpret/machine.rs index 8405d0746dfd1..2eaebc1924bc6 100644 --- a/compiler/rustc_const_eval/src/interpret/machine.rs +++ b/compiler/rustc_const_eval/src/interpret/machine.rs @@ -18,9 +18,9 @@ use rustc_target::abi::{Align, Size}; use rustc_target::spec::abi::Abi as CallAbi; use super::{ - AllocBytes, AllocId, AllocKind, AllocRange, Allocation, ConstAllocation, CtfeProvenance, FnArg, - Frame, ImmTy, InterpCx, InterpResult, MPlaceTy, MemoryKind, Misalignment, OpTy, PlaceTy, - Pointer, Provenance, + throw_unsup, throw_unsup_format, AllocBytes, AllocId, AllocKind, AllocRange, Allocation, + ConstAllocation, CtfeProvenance, FnArg, Frame, ImmTy, InterpCx, InterpResult, MPlaceTy, + MemoryKind, Misalignment, OpTy, PlaceTy, Pointer, Provenance, }; /// Data returned by Machine::stack_pop, diff --git a/compiler/rustc_const_eval/src/interpret/memory.rs b/compiler/rustc_const_eval/src/interpret/memory.rs index 594e3b3212f2e..350fd480fbaae 100644 --- a/compiler/rustc_const_eval/src/interpret/memory.rs +++ b/compiler/rustc_const_eval/src/interpret/memory.rs @@ -16,6 +16,7 @@ use std::ptr; use rustc_ast::Mutability; use rustc_data_structures::fx::{FxHashSet, FxIndexMap}; use rustc_hir::def::DefKind; +use rustc_middle::bug; use rustc_middle::mir::display_allocation; use rustc_middle::ty::{self, Instance, ParamEnv, Ty, TyCtxt}; use rustc_target::abi::{Align, HasDataLayout, Size}; @@ -23,9 +24,10 @@ use rustc_target::abi::{Align, HasDataLayout, Size}; use crate::fluent_generated as fluent; use super::{ - alloc_range, AllocBytes, AllocId, AllocMap, AllocRange, Allocation, CheckAlignMsg, - CheckInAllocMsg, CtfeProvenance, GlobalAlloc, InterpCx, InterpResult, Machine, MayLeak, - Misalignment, Pointer, PointerArithmetic, Provenance, Scalar, + alloc_range, err_ub, err_ub_custom, throw_ub, throw_ub_custom, throw_unsup, throw_unsup_format, + AllocBytes, AllocId, AllocMap, AllocRange, Allocation, CheckAlignMsg, CheckInAllocMsg, + CtfeProvenance, GlobalAlloc, InterpCx, InterpResult, Machine, MayLeak, Misalignment, Pointer, + PointerArithmetic, Provenance, Scalar, }; #[derive(Debug, PartialEq, Copy, Clone)] diff --git a/compiler/rustc_const_eval/src/interpret/operand.rs b/compiler/rustc_const_eval/src/interpret/operand.rs index 718c91b2f7676..bad9732f48310 100644 --- a/compiler/rustc_const_eval/src/interpret/operand.rs +++ b/compiler/rustc_const_eval/src/interpret/operand.rs @@ -10,13 +10,14 @@ use rustc_middle::mir::interpret::ScalarSizeMismatch; use rustc_middle::ty::layout::{LayoutOf, TyAndLayout}; use rustc_middle::ty::print::{FmtPrinter, PrettyPrinter}; use rustc_middle::ty::{ConstInt, ScalarInt, Ty, TyCtxt}; +use rustc_middle::{bug, span_bug}; use rustc_middle::{mir, ty}; use rustc_target::abi::{self, Abi, HasDataLayout, Size}; use super::{ - alloc_range, from_known_layout, mir_assign_valid_types, CtfeProvenance, InterpCx, InterpResult, - MPlaceTy, Machine, MemPlace, MemPlaceMeta, OffsetMode, PlaceTy, Pointer, Projectable, - Provenance, Scalar, + alloc_range, err_ub, from_known_layout, mir_assign_valid_types, throw_ub, CtfeProvenance, + InterpCx, InterpResult, MPlaceTy, Machine, MemPlace, MemPlaceMeta, OffsetMode, PlaceTy, + Pointer, Projectable, Provenance, Scalar, }; /// An `Immediate` represents a single immediate self-contained Rust value. diff --git a/compiler/rustc_const_eval/src/interpret/operator.rs b/compiler/rustc_const_eval/src/interpret/operator.rs index 2d5dbbd58b3b0..5f59e3d887e46 100644 --- a/compiler/rustc_const_eval/src/interpret/operator.rs +++ b/compiler/rustc_const_eval/src/interpret/operator.rs @@ -3,10 +3,11 @@ use rustc_middle::mir; use rustc_middle::mir::interpret::{InterpResult, Scalar}; use rustc_middle::ty::layout::{LayoutOf, TyAndLayout}; use rustc_middle::ty::{self, FloatTy, ScalarInt, Ty}; +use rustc_middle::{bug, span_bug}; use rustc_span::symbol::sym; use rustc_target::abi::Abi; -use super::{ImmTy, Immediate, InterpCx, Machine, PlaceTy}; +use super::{err_ub, throw_ub, throw_ub_custom, ImmTy, Immediate, InterpCx, Machine, PlaceTy}; use crate::fluent_generated as fluent; diff --git a/compiler/rustc_const_eval/src/interpret/place.rs b/compiler/rustc_const_eval/src/interpret/place.rs index 809aca18990f8..9ced825853bd2 100644 --- a/compiler/rustc_const_eval/src/interpret/place.rs +++ b/compiler/rustc_const_eval/src/interpret/place.rs @@ -11,12 +11,14 @@ use rustc_middle::mir; use rustc_middle::ty; use rustc_middle::ty::layout::{LayoutOf, TyAndLayout}; use rustc_middle::ty::Ty; +use rustc_middle::{bug, span_bug}; use rustc_target::abi::{Abi, Align, HasDataLayout, Size}; use super::{ - alloc_range, mir_assign_valid_types, AllocRef, AllocRefMut, CheckAlignMsg, CtfeProvenance, - ImmTy, Immediate, InterpCx, InterpResult, Machine, MemoryKind, Misalignment, OffsetMode, OpTy, - Operand, Pointer, PointerArithmetic, Projectable, Provenance, Readable, Scalar, + alloc_range, mir_assign_valid_types, throw_ub, AllocRef, AllocRefMut, CheckAlignMsg, + CtfeProvenance, ImmTy, Immediate, InterpCx, InterpResult, Machine, MemoryKind, Misalignment, + OffsetMode, OpTy, Operand, Pointer, PointerArithmetic, Projectable, Provenance, Readable, + Scalar, }; #[derive(Copy, Clone, Hash, PartialEq, Eq, Debug)] diff --git a/compiler/rustc_const_eval/src/interpret/projection.rs b/compiler/rustc_const_eval/src/interpret/projection.rs index 5ff78f7b8c90b..0a2fedb48401c 100644 --- a/compiler/rustc_const_eval/src/interpret/projection.rs +++ b/compiler/rustc_const_eval/src/interpret/projection.rs @@ -14,10 +14,14 @@ use rustc_middle::mir; use rustc_middle::ty; use rustc_middle::ty::layout::{LayoutOf, TyAndLayout}; use rustc_middle::ty::Ty; +use rustc_middle::{bug, span_bug}; use rustc_target::abi::Size; use rustc_target::abi::{self, VariantIdx}; -use super::{InterpCx, InterpResult, MPlaceTy, Machine, MemPlaceMeta, OpTy, Provenance, Scalar}; +use super::{ + throw_ub, throw_unsup_format, InterpCx, InterpResult, MPlaceTy, Machine, MemPlaceMeta, OpTy, + Provenance, Scalar, +}; /// Describes the constraints placed on offset-projections. #[derive(Copy, Clone, Debug)] diff --git a/compiler/rustc_const_eval/src/interpret/step.rs b/compiler/rustc_const_eval/src/interpret/step.rs index b29034e991e30..ee415c380de17 100644 --- a/compiler/rustc_const_eval/src/interpret/step.rs +++ b/compiler/rustc_const_eval/src/interpret/step.rs @@ -7,6 +7,7 @@ use either::Either; use rustc_index::IndexSlice; use rustc_middle::mir; use rustc_middle::ty::layout::LayoutOf; +use rustc_middle::{bug, span_bug}; use rustc_target::abi::{FieldIdx, FIRST_VARIANT}; use super::{ diff --git a/compiler/rustc_const_eval/src/interpret/terminator.rs b/compiler/rustc_const_eval/src/interpret/terminator.rs index b474003087ba3..b82c18578588b 100644 --- a/compiler/rustc_const_eval/src/interpret/terminator.rs +++ b/compiler/rustc_const_eval/src/interpret/terminator.rs @@ -2,6 +2,7 @@ use std::borrow::Cow; use either::Either; +use rustc_middle::span_bug; use rustc_middle::{ mir, ty::{ @@ -19,8 +20,9 @@ use rustc_target::abi::{ use rustc_target::spec::abi::Abi; use super::{ - CtfeProvenance, FnVal, ImmTy, InterpCx, InterpResult, MPlaceTy, Machine, OpTy, PlaceTy, - Projectable, Provenance, Scalar, StackPopCleanup, + throw_ub, throw_ub_custom, throw_unsup_format, CtfeProvenance, FnVal, ImmTy, InterpCx, + InterpResult, MPlaceTy, Machine, OpTy, PlaceTy, Projectable, Provenance, Scalar, + StackPopCleanup, }; use crate::fluent_generated as fluent; diff --git a/compiler/rustc_const_eval/src/interpret/util.rs b/compiler/rustc_const_eval/src/interpret/util.rs index c83ef14c03fe7..e304d1e1cc5e4 100644 --- a/compiler/rustc_const_eval/src/interpret/util.rs +++ b/compiler/rustc_const_eval/src/interpret/util.rs @@ -1,5 +1,4 @@ use crate::const_eval::{CompileTimeEvalContext, CompileTimeInterpreter, InterpretationResult}; -use crate::interpret::{MemPlaceMeta, MemoryKind}; use rustc_hir::def_id::LocalDefId; use rustc_middle::mir; use rustc_middle::mir::interpret::{Allocation, InterpResult, Pointer}; @@ -9,7 +8,7 @@ use rustc_middle::ty::{ }; use std::ops::ControlFlow; -use super::{InterpCx, MPlaceTy}; +use super::{throw_inval, InterpCx, MPlaceTy, MemPlaceMeta, MemoryKind}; /// Checks whether a type contains generic parameters which must be instantiated. /// diff --git a/compiler/rustc_const_eval/src/interpret/validity.rs b/compiler/rustc_const_eval/src/interpret/validity.rs index 14566719ccd72..2bd4d9dc07a51 100644 --- a/compiler/rustc_const_eval/src/interpret/validity.rs +++ b/compiler/rustc_const_eval/src/interpret/validity.rs @@ -13,6 +13,7 @@ use hir::def::DefKind; use rustc_ast::Mutability; use rustc_data_structures::fx::FxHashSet; use rustc_hir as hir; +use rustc_middle::bug; use rustc_middle::mir::interpret::{ ExpectedKind, InterpError, InvalidMetaKind, Misalignment, PointerKind, Provenance, ValidationErrorInfo, ValidationErrorKind, ValidationErrorKind::*, @@ -27,9 +28,9 @@ use rustc_target::abi::{ use std::hash::Hash; use super::{ - format_interp_error, machine::AllocMap, AllocId, CheckInAllocMsg, GlobalAlloc, ImmTy, - Immediate, InterpCx, InterpResult, MPlaceTy, Machine, MemPlaceMeta, OpTy, Pointer, Projectable, - Scalar, ValueVisitor, + err_ub, format_interp_error, machine::AllocMap, throw_ub, AllocId, CheckInAllocMsg, + GlobalAlloc, ImmTy, Immediate, InterpCx, InterpResult, MPlaceTy, Machine, MemPlaceMeta, OpTy, + Pointer, Projectable, Scalar, ValueVisitor, }; // for the validation errors diff --git a/compiler/rustc_const_eval/src/interpret/visitor.rs b/compiler/rustc_const_eval/src/interpret/visitor.rs index 84557b8e2d600..59bcc5174cb2b 100644 --- a/compiler/rustc_const_eval/src/interpret/visitor.rs +++ b/compiler/rustc_const_eval/src/interpret/visitor.rs @@ -9,7 +9,7 @@ use rustc_target::abi::{FieldsShape, VariantIdx, Variants}; use std::num::NonZero; -use super::{InterpCx, MPlaceTy, Machine, Projectable}; +use super::{throw_inval, InterpCx, MPlaceTy, Machine, Projectable}; /// How to traverse a value and what to do when we are at the leaves. pub trait ValueVisitor<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>>: Sized { diff --git a/compiler/rustc_const_eval/src/lib.rs b/compiler/rustc_const_eval/src/lib.rs index d27d42737cd6c..a525b838afa24 100644 --- a/compiler/rustc_const_eval/src/lib.rs +++ b/compiler/rustc_const_eval/src/lib.rs @@ -22,8 +22,6 @@ Rust MIR: a lowered representation of Rust. #[macro_use] extern crate tracing; -#[macro_use] -extern crate rustc_middle; pub mod const_eval; mod errors; diff --git a/compiler/rustc_const_eval/src/transform/check_consts/check.rs b/compiler/rustc_const_eval/src/transform/check_consts/check.rs index 46cc9f69373f5..5edf5bb39dd4c 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs @@ -8,6 +8,7 @@ use rustc_infer::infer::TyCtxtInferExt; use rustc_infer::traits::ObligationCause; use rustc_middle::mir::visit::{MutatingUseContext, NonMutatingUseContext, PlaceContext, Visitor}; use rustc_middle::mir::*; +use rustc_middle::span_bug; use rustc_middle::ty::{self, adjustment::PointerCoercion, Ty, TyCtxt}; use rustc_middle::ty::{Instance, InstanceDef, TypeVisitableExt}; use rustc_mir_dataflow::Analysis; diff --git a/compiler/rustc_const_eval/src/transform/check_consts/mod.rs b/compiler/rustc_const_eval/src/transform/check_consts/mod.rs index 12e7ec15e3292..308b90cd470d4 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/mod.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/mod.rs @@ -8,6 +8,7 @@ use rustc_attr as attr; use rustc_errors::DiagCtxt; use rustc_hir as hir; use rustc_hir::def_id::{DefId, LocalDefId}; +use rustc_middle::bug; use rustc_middle::mir; use rustc_middle::ty::{self, PolyFnSig, TyCtxt}; use rustc_span::Symbol; diff --git a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs index 247a2889dc588..8775685e8c73b 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs @@ -8,6 +8,7 @@ use rustc_hir::def_id::DefId; use rustc_infer::infer::TyCtxtInferExt; use rustc_infer::traits::{ImplSource, Obligation, ObligationCause}; use rustc_middle::mir::{self, CallSource}; +use rustc_middle::span_bug; use rustc_middle::ty::print::{with_no_trimmed_paths, PrintTraitRefExt as _}; use rustc_middle::ty::{ self, suggest_constraining_type_param, Closure, FnDef, FnPtr, GenericArgKind, GenericArgsRef, diff --git a/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs b/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs index 1847847d9d2ae..eae0e2f27dbdb 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs @@ -5,6 +5,7 @@ use rustc_errors::ErrorGuaranteed; use rustc_hir::LangItem; use rustc_infer::infer::TyCtxtInferExt; +use rustc_middle::bug; use rustc_middle::mir; use rustc_middle::mir::*; use rustc_middle::traits::BuiltinImplSource; diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs index c95166d84e933..fdc7f6a69cba1 100644 --- a/compiler/rustc_const_eval/src/transform/validate.rs +++ b/compiler/rustc_const_eval/src/transform/validate.rs @@ -9,6 +9,7 @@ use rustc_middle::mir::interpret::Scalar; use rustc_middle::mir::visit::{NonUseContext, PlaceContext, Visitor}; use rustc_middle::mir::*; use rustc_middle::ty::{self, InstanceDef, ParamEnv, Ty, TyCtxt, TypeVisitableExt, Variance}; +use rustc_middle::{bug, span_bug}; use rustc_target::abi::{Size, FIRST_VARIANT}; use rustc_target::spec::abi::Abi; diff --git a/compiler/rustc_const_eval/src/util/caller_location.rs b/compiler/rustc_const_eval/src/util/caller_location.rs index af9a4a4271d74..403bc1eca1346 100644 --- a/compiler/rustc_const_eval/src/util/caller_location.rs +++ b/compiler/rustc_const_eval/src/util/caller_location.rs @@ -1,4 +1,5 @@ use rustc_hir::LangItem; +use rustc_middle::bug; use rustc_middle::mir; use rustc_middle::query::TyCtxtAt; use rustc_middle::ty::layout::LayoutOf; diff --git a/compiler/rustc_const_eval/src/util/check_validity_requirement.rs b/compiler/rustc_const_eval/src/util/check_validity_requirement.rs index 36597507f4747..68fb122a765da 100644 --- a/compiler/rustc_const_eval/src/util/check_validity_requirement.rs +++ b/compiler/rustc_const_eval/src/util/check_validity_requirement.rs @@ -1,3 +1,4 @@ +use rustc_middle::bug; use rustc_middle::ty::layout::{LayoutCx, LayoutError, LayoutOf, TyAndLayout, ValidityRequirement}; use rustc_middle::ty::{ParamEnv, ParamEnvAnd, Ty, TyCtxt}; use rustc_target::abi::{Abi, FieldsShape, Scalar, Variants}; diff --git a/compiler/rustc_const_eval/src/util/type_name.rs b/compiler/rustc_const_eval/src/util/type_name.rs index e474b952938a6..01e517250f77e 100644 --- a/compiler/rustc_const_eval/src/util/type_name.rs +++ b/compiler/rustc_const_eval/src/util/type_name.rs @@ -1,6 +1,7 @@ use rustc_data_structures::intern::Interned; use rustc_hir::def_id::CrateNum; use rustc_hir::definitions::DisambiguatedDefPathData; +use rustc_middle::bug; use rustc_middle::ty::{ self, print::{PrettyPrinter, Print, PrintError, Printer}, diff --git a/compiler/rustc_middle/src/mir/interpret/mod.rs b/compiler/rustc_middle/src/mir/interpret/mod.rs index 38cb1d5f9a074..20afe52c1f31c 100644 --- a/compiler/rustc_middle/src/mir/interpret/mod.rs +++ b/compiler/rustc_middle/src/mir/interpret/mod.rs @@ -8,11 +8,13 @@ macro_rules! err_unsup { ) }; } +pub use err_unsup; #[macro_export] macro_rules! err_unsup_format { - ($($tt:tt)*) => { err_unsup!(Unsupported(format!($($tt)*))) }; + ($($tt:tt)*) => { $crate::err_unsup!(Unsupported(format!($($tt)*))) }; } +pub use err_unsup_format; #[macro_export] macro_rules! err_inval { @@ -22,6 +24,7 @@ macro_rules! err_inval { ) }; } +pub use err_inval; #[macro_export] macro_rules! err_ub { @@ -31,11 +34,13 @@ macro_rules! err_ub { ) }; } +pub use err_ub; #[macro_export] macro_rules! err_ub_format { ($($tt:tt)*) => { err_ub!(Ub(format!($($tt)*))) }; } +pub use err_ub_format; #[macro_export] macro_rules! err_exhaust { @@ -45,6 +50,7 @@ macro_rules! err_exhaust { ) }; } +pub use err_exhaust; #[macro_export] macro_rules! err_machine_stop { @@ -52,42 +58,50 @@ macro_rules! err_machine_stop { $crate::mir::interpret::InterpError::MachineStop(Box::new($($tt)*)) }; } +pub use err_machine_stop; // In the `throw_*` macros, avoid `return` to make them work with `try {}`. #[macro_export] macro_rules! throw_unsup { - ($($tt:tt)*) => { do yeet err_unsup!($($tt)*) }; + ($($tt:tt)*) => { do yeet $crate::err_unsup!($($tt)*) }; } +pub use throw_unsup; #[macro_export] macro_rules! throw_unsup_format { - ($($tt:tt)*) => { throw_unsup!(Unsupported(format!($($tt)*))) }; + ($($tt:tt)*) => { $crate::throw_unsup!(Unsupported(format!($($tt)*))) }; } +pub use throw_unsup_format; #[macro_export] macro_rules! throw_inval { - ($($tt:tt)*) => { do yeet err_inval!($($tt)*) }; + ($($tt:tt)*) => { do yeet $crate::err_inval!($($tt)*) }; } +pub use throw_inval; #[macro_export] macro_rules! throw_ub { - ($($tt:tt)*) => { do yeet err_ub!($($tt)*) }; + ($($tt:tt)*) => { do yeet $crate::err_ub!($($tt)*) }; } +pub use throw_ub; #[macro_export] macro_rules! throw_ub_format { - ($($tt:tt)*) => { throw_ub!(Ub(format!($($tt)*))) }; + ($($tt:tt)*) => { $crate::throw_ub!(Ub(format!($($tt)*))) }; } +pub use throw_ub_format; #[macro_export] macro_rules! throw_exhaust { - ($($tt:tt)*) => { do yeet err_exhaust!($($tt)*) }; + ($($tt:tt)*) => { do yeet $crate::err_exhaust!($($tt)*) }; } +pub use throw_exhaust; #[macro_export] macro_rules! throw_machine_stop { - ($($tt:tt)*) => { do yeet err_machine_stop!($($tt)*) }; + ($($tt:tt)*) => { do yeet $crate::err_machine_stop!($($tt)*) }; } +pub use throw_machine_stop; #[macro_export] macro_rules! err_ub_custom { @@ -95,8 +109,8 @@ macro_rules! err_ub_custom { $( let ($($name,)*) = ($($value,)*); )? - err_ub!(Custom( - rustc_middle::error::CustomSubdiagnostic { + $crate::err_ub!(Custom( + $crate::error::CustomSubdiagnostic { msg: || $msg, add_args: Box::new(move |mut set_arg| { $($( @@ -107,11 +121,13 @@ macro_rules! err_ub_custom { )) }}; } +pub use err_ub_custom; #[macro_export] macro_rules! throw_ub_custom { - ($($tt:tt)*) => { do yeet err_ub_custom!($($tt)*) }; + ($($tt:tt)*) => { do yeet $crate::err_ub_custom!($($tt)*) }; } +pub use throw_ub_custom; mod allocation; mod error; From f59348ff096fcea61e71f7249ad0fefda92fa53b Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 8 May 2024 16:40:46 +1000 Subject: [PATCH 137/179] Remove `extern crate rustc_middle` from `rustc_hir_analysis`. --- compiler/rustc_hir_analysis/src/check/check.rs | 1 + compiler/rustc_hir_analysis/src/check/compare_impl_item.rs | 1 + .../rustc_hir_analysis/src/check/compare_impl_item/refine.rs | 1 + compiler/rustc_hir_analysis/src/check/entry.rs | 1 + compiler/rustc_hir_analysis/src/check/intrinsic.rs | 1 + compiler/rustc_hir_analysis/src/check/intrinsicck.rs | 1 + compiler/rustc_hir_analysis/src/check/mod.rs | 1 + compiler/rustc_hir_analysis/src/check/region.rs | 1 + compiler/rustc_hir_analysis/src/check/wfcheck.rs | 1 + compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs | 1 + compiler/rustc_hir_analysis/src/coherence/orphan.rs | 1 + compiler/rustc_hir_analysis/src/collect.rs | 1 + compiler/rustc_hir_analysis/src/collect/item_bounds.rs | 1 + compiler/rustc_hir_analysis/src/collect/predicates_of.rs | 1 + compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs | 2 +- compiler/rustc_hir_analysis/src/collect/type_of.rs | 1 + compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs | 1 + compiler/rustc_hir_analysis/src/constrained_generic_params.rs | 1 + compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs | 1 + compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs | 1 + compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs | 1 + .../rustc_hir_analysis/src/hir_ty_lowering/object_safety.rs | 1 + compiler/rustc_hir_analysis/src/hir_wf_check.rs | 1 + compiler/rustc_hir_analysis/src/lib.rs | 3 --- compiler/rustc_hir_analysis/src/outlives/test.rs | 1 + compiler/rustc_hir_analysis/src/outlives/utils.rs | 1 + compiler/rustc_hir_analysis/src/variance/constraints.rs | 1 + compiler/rustc_hir_analysis/src/variance/mod.rs | 1 + 28 files changed, 27 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index fb9d97ba08b01..652c18850737f 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -14,6 +14,7 @@ use rustc_infer::traits::Obligation; use rustc_lint_defs::builtin::REPR_TRANSPARENT_EXTERNAL_PRIVATE_FIELDS; use rustc_middle::middle::resolve_bound_vars::ResolvedArg; use rustc_middle::middle::stability::EvalResult; +use rustc_middle::span_bug; use rustc_middle::ty::fold::BottomUpFolder; use rustc_middle::ty::layout::{LayoutError, MAX_SIMD_LANES}; use rustc_middle::ty::util::{Discr, InspectCoroutineFields, IntTypeExt}; diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index db223f9d80f39..8352d1d7a901e 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -19,6 +19,7 @@ use rustc_middle::ty::{ self, GenericArgs, Ty, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt, }; use rustc_middle::ty::{GenericParamDefKind, TyCtxt}; +use rustc_middle::{bug, span_bug}; use rustc_span::Span; use rustc_trait_selection::regions::InferCtxtRegionExt; use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt; diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs index a2a20082bb03e..ca08eeea22750 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs @@ -3,6 +3,7 @@ use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_infer::infer::{outlives::env::OutlivesEnvironment, TyCtxtInferExt}; use rustc_lint_defs::builtin::{REFINING_IMPL_TRAIT_INTERNAL, REFINING_IMPL_TRAIT_REACHABLE}; +use rustc_middle::span_bug; use rustc_middle::traits::{ObligationCause, Reveal}; use rustc_middle::ty::{ self, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperVisitable, TypeVisitable, TypeVisitor, diff --git a/compiler/rustc_hir_analysis/src/check/entry.rs b/compiler/rustc_hir_analysis/src/check/entry.rs index d5908cf285118..e44e8e67da3e6 100644 --- a/compiler/rustc_hir_analysis/src/check/entry.rs +++ b/compiler/rustc_hir_analysis/src/check/entry.rs @@ -1,6 +1,7 @@ use rustc_hir as hir; use rustc_hir::Node; use rustc_infer::infer::TyCtxtInferExt; +use rustc_middle::span_bug; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_session::config::EntryFnType; use rustc_span::def_id::{DefId, LocalDefId, CRATE_DEF_ID}; diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs index eb1fa1baecca0..00ff470a0a7d7 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs @@ -9,6 +9,7 @@ use crate::errors::{ use rustc_errors::{codes::*, struct_span_code_err, DiagMessage}; use rustc_hir as hir; +use rustc_middle::bug; use rustc_middle::traits::{ObligationCause, ObligationCauseCode}; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_span::def_id::LocalDefId; diff --git a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs index 45ccd0fa2e068..b09de1a4a0989 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs @@ -1,6 +1,7 @@ use rustc_ast::InlineAsmTemplatePiece; use rustc_data_structures::fx::FxIndexSet; use rustc_hir as hir; +use rustc_middle::bug; use rustc_middle::ty::{self, Article, FloatTy, IntTy, Ty, TyCtxt, TypeVisitableExt, UintTy}; use rustc_session::lint; use rustc_span::def_id::LocalDefId; diff --git a/compiler/rustc_hir_analysis/src/check/mod.rs b/compiler/rustc_hir_analysis/src/check/mod.rs index eb0ffc19d4540..9c5c0a766b4e3 100644 --- a/compiler/rustc_hir_analysis/src/check/mod.rs +++ b/compiler/rustc_hir_analysis/src/check/mod.rs @@ -90,6 +90,7 @@ use rustc_middle::query::Providers; use rustc_middle::ty::error::{ExpectedFound, TypeError}; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_middle::ty::{GenericArgs, GenericArgsRef}; +use rustc_middle::{bug, span_bug}; use rustc_session::parse::feature_err; use rustc_span::symbol::{kw, sym, Ident}; use rustc_span::{def_id::CRATE_DEF_ID, BytePos, Span, Symbol, DUMMY_SP}; diff --git a/compiler/rustc_hir_analysis/src/check/region.rs b/compiler/rustc_hir_analysis/src/check/region.rs index d2ea51f65f98a..4540310937d02 100644 --- a/compiler/rustc_hir_analysis/src/check/region.rs +++ b/compiler/rustc_hir_analysis/src/check/region.rs @@ -13,6 +13,7 @@ use rustc_hir::def_id::DefId; use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::{Arm, Block, Expr, LetStmt, Pat, PatKind, Stmt}; use rustc_index::Idx; +use rustc_middle::bug; use rustc_middle::middle::region::*; use rustc_middle::ty::TyCtxt; use rustc_span::source_map; diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index e50af9605fd0d..b918a8c32d8af 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -24,6 +24,7 @@ use rustc_middle::ty::{ TypeVisitable, TypeVisitableExt, TypeVisitor, }; use rustc_middle::ty::{GenericArgKind, GenericArgs}; +use rustc_middle::{bug, span_bug}; use rustc_session::parse::feature_err; use rustc_span::symbol::{sym, Ident}; use rustc_span::{Span, DUMMY_SP}; diff --git a/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs b/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs index 4a85e9983f471..e2d3ff558cf7d 100644 --- a/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs +++ b/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs @@ -10,6 +10,7 @@ use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LocalDefId}; +use rustc_middle::bug; use rustc_middle::ty::fast_reject::{simplify_type, SimplifiedType, TreatParams}; use rustc_middle::ty::{self, CrateInherentImpls, Ty, TyCtxt}; use rustc_span::symbol::sym; diff --git a/compiler/rustc_hir_analysis/src/coherence/orphan.rs b/compiler/rustc_hir_analysis/src/coherence/orphan.rs index 8e1b2e8e65c52..bdac0d9b0b407 100644 --- a/compiler/rustc_hir_analysis/src/coherence/orphan.rs +++ b/compiler/rustc_hir_analysis/src/coherence/orphan.rs @@ -10,6 +10,7 @@ use rustc_lint_defs::builtin::UNCOVERED_PARAM_IN_PROJECTION; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_middle::ty::{TypeFoldable, TypeFolder, TypeSuperFoldable}; use rustc_middle::ty::{TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor}; +use rustc_middle::{bug, span_bug}; use rustc_span::def_id::{DefId, LocalDefId}; use rustc_trait_selection::traits::{self, IsFirstInputType, UncoveredTyParams}; use rustc_trait_selection::traits::{OrphanCheckErr, OrphanCheckMode}; diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index 566f818f89958..0b9f7fd41fb91 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -30,6 +30,7 @@ use rustc_middle::hir::nested_filter; use rustc_middle::query::Providers; use rustc_middle::ty::util::{Discr, IntTypeExt}; use rustc_middle::ty::{self, AdtKind, Const, IsSuggestable, ToPredicate, Ty, TyCtxt}; +use rustc_middle::{bug, span_bug}; use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::{Span, DUMMY_SP}; use rustc_target::abi::FieldIdx; diff --git a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs index 02291cc603e13..3c89c2b23fc14 100644 --- a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs +++ b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs @@ -5,6 +5,7 @@ use rustc_hir as hir; use rustc_infer::traits::util; use rustc_middle::ty::GenericArgs; use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable}; +use rustc_middle::{bug, span_bug}; use rustc_span::def_id::{DefId, LocalDefId}; use rustc_span::Span; diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs index 7e82571d172f1..8e79b36060c81 100644 --- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs @@ -10,6 +10,7 @@ use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::intravisit::{self, Visitor}; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_middle::ty::{GenericPredicates, ImplTraitInTraitData, ToPredicate}; +use rustc_middle::{bug, span_bug}; use rustc_span::symbol::Ident; use rustc_span::{Span, DUMMY_SP}; diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs index 3ef132a3e8c97..5c7733065c611 100644 --- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs +++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs @@ -15,11 +15,11 @@ use rustc_hir::def_id::LocalDefId; use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::{GenericArg, GenericParam, GenericParamKind, HirId, HirIdMap, LifetimeName, Node}; use rustc_macros::extension; -use rustc_middle::bug; use rustc_middle::hir::nested_filter; use rustc_middle::middle::resolve_bound_vars::*; use rustc_middle::query::Providers; use rustc_middle::ty::{self, TyCtxt, TypeSuperVisitable, TypeVisitor}; +use rustc_middle::{bug, span_bug}; use rustc_span::def_id::DefId; use rustc_span::symbol::{sym, Ident}; use rustc_span::Span; diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs index 24a5349858ade..1475e53c47c29 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs @@ -7,6 +7,7 @@ use rustc_middle::query::plumbing::CyclePlaceholder; use rustc_middle::ty::print::with_forced_trimmed_paths; use rustc_middle::ty::util::IntTypeExt; use rustc_middle::ty::{self, IsSuggestable, Ty, TyCtxt, TypeVisitableExt}; +use rustc_middle::{bug, span_bug}; use rustc_span::symbol::Ident; use rustc_span::{Span, DUMMY_SP}; diff --git a/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs b/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs index b5765913cb857..1bec8c496ad1e 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs @@ -3,6 +3,7 @@ use rustc_hir::def::DefKind; use rustc_hir::def_id::{LocalDefId, CRATE_DEF_ID}; use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::{self as hir, def, Expr, ImplItem, Item, Node, TraitItem}; +use rustc_middle::bug; use rustc_middle::hir::nested_filter; use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt}; use rustc_span::{sym, ErrorGuaranteed, DUMMY_SP}; diff --git a/compiler/rustc_hir_analysis/src/constrained_generic_params.rs b/compiler/rustc_hir_analysis/src/constrained_generic_params.rs index 3b8bb0731fbd8..b50c11aaa9a8d 100644 --- a/compiler/rustc_hir_analysis/src/constrained_generic_params.rs +++ b/compiler/rustc_hir_analysis/src/constrained_generic_params.rs @@ -1,4 +1,5 @@ use rustc_data_structures::fx::FxHashSet; +use rustc_middle::bug; use rustc_middle::ty::visit::{TypeSuperVisitable, TypeVisitor}; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_span::Span; diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs index de12475678ca3..6786c9afd0d16 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs @@ -5,6 +5,7 @@ use rustc_errors::{codes::*, struct_span_code_err}; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{DefId, LocalDefId}; +use rustc_middle::bug; use rustc_middle::ty::print::PrintTraitRefExt as _; use rustc_middle::ty::{self as ty, IsSuggestable, Ty, TyCtxt}; use rustc_span::symbol::Ident; diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs index 38dfa8d57d34b..211da237f8aa9 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs @@ -16,6 +16,7 @@ use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_infer::traits::FulfillmentError; +use rustc_middle::bug; use rustc_middle::query::Key; use rustc_middle::ty::print::PrintTraitRefExt as _; use rustc_middle::ty::GenericParamDefKind; diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs index 591d554d335e1..d16648b9e8f68 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -44,6 +44,7 @@ use rustc_middle::ty::{ self, Const, GenericArgKind, GenericArgsRef, GenericParamDefKind, ParamEnv, Ty, TyCtxt, TypeVisitableExt, }; +use rustc_middle::{bug, span_bug}; use rustc_session::lint::builtin::AMBIGUOUS_ASSOCIATED_ITEMS; use rustc_span::edit_distance::find_best_match_for_name; use rustc_span::symbol::{kw, Ident, Symbol}; diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/object_safety.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/object_safety.rs index 37d4d4ec35581..b8d4ee58e2e60 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/object_safety.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/object_safety.rs @@ -6,6 +6,7 @@ use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::DefId; use rustc_lint_defs::builtin::UNUSED_ASSOCIATED_TYPE_BOUNDS; +use rustc_middle::span_bug; use rustc_middle::ty::fold::BottomUpFolder; use rustc_middle::ty::{self, ExistentialPredicateStableCmpExt as _, Ty, TyCtxt, TypeFoldable}; use rustc_middle::ty::{DynKind, ToPredicate}; diff --git a/compiler/rustc_hir_analysis/src/hir_wf_check.rs b/compiler/rustc_hir_analysis/src/hir_wf_check.rs index d6ba5fa9b5b04..10101aa046e50 100644 --- a/compiler/rustc_hir_analysis/src/hir_wf_check.rs +++ b/compiler/rustc_hir_analysis/src/hir_wf_check.rs @@ -4,6 +4,7 @@ use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::{ForeignItem, ForeignItemKind}; use rustc_infer::infer::TyCtxtInferExt; use rustc_infer::traits::{ObligationCause, WellFormedLoc}; +use rustc_middle::bug; use rustc_middle::query::Providers; use rustc_middle::ty::{self, TyCtxt}; use rustc_span::def_id::LocalDefId; diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index e75740837f8d4..654ef4baeb39e 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs @@ -75,9 +75,6 @@ This API is completely unstable and subject to change. #[macro_use] extern crate tracing; -#[macro_use] -extern crate rustc_middle; - // These are used by Clippy. pub mod check; diff --git a/compiler/rustc_hir_analysis/src/outlives/test.rs b/compiler/rustc_hir_analysis/src/outlives/test.rs index 60cd8c39fa022..e9b6c679bd5a4 100644 --- a/compiler/rustc_hir_analysis/src/outlives/test.rs +++ b/compiler/rustc_hir_analysis/src/outlives/test.rs @@ -1,3 +1,4 @@ +use rustc_middle::bug; use rustc_middle::ty::{self, TyCtxt}; use rustc_span::{symbol::sym, ErrorGuaranteed}; diff --git a/compiler/rustc_hir_analysis/src/outlives/utils.rs b/compiler/rustc_hir_analysis/src/outlives/utils.rs index d3bb22d715d7b..95290bbecf2c4 100644 --- a/compiler/rustc_hir_analysis/src/outlives/utils.rs +++ b/compiler/rustc_hir_analysis/src/outlives/utils.rs @@ -2,6 +2,7 @@ use rustc_data_structures::fx::FxIndexMap; use rustc_infer::infer::outlives::components::{push_outlives_components, Component}; use rustc_middle::ty::{self, Region, Ty, TyCtxt}; use rustc_middle::ty::{GenericArg, GenericArgKind}; +use rustc_middle::{bug, span_bug}; use rustc_span::Span; use smallvec::smallvec; diff --git a/compiler/rustc_hir_analysis/src/variance/constraints.rs b/compiler/rustc_hir_analysis/src/variance/constraints.rs index eeb8b02850521..730e989edaed8 100644 --- a/compiler/rustc_hir_analysis/src/variance/constraints.rs +++ b/compiler/rustc_hir_analysis/src/variance/constraints.rs @@ -8,6 +8,7 @@ use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_middle::ty::{GenericArgKind, GenericArgsRef}; +use rustc_middle::{bug, span_bug}; use super::terms::VarianceTerm::*; use super::terms::*; diff --git a/compiler/rustc_hir_analysis/src/variance/mod.rs b/compiler/rustc_hir_analysis/src/variance/mod.rs index 27fdea01c2b27..c7e2050453dcf 100644 --- a/compiler/rustc_hir_analysis/src/variance/mod.rs +++ b/compiler/rustc_hir_analysis/src/variance/mod.rs @@ -8,6 +8,7 @@ use rustc_arena::DroplessArena; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_middle::query::Providers; +use rustc_middle::span_bug; use rustc_middle::ty::{self, CrateVariancesMap, GenericArgsRef, Ty, TyCtxt}; use rustc_middle::ty::{TypeSuperVisitable, TypeVisitable}; From 9b7d254d4949e5af2082a7cd58679057c46bfad1 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 8 May 2024 16:45:43 +1000 Subject: [PATCH 138/179] Remove `extern crate rustc_middle` from `rustc_hir_typeck`. --- compiler/rustc_hir_typeck/src/callee.rs | 1 + compiler/rustc_hir_typeck/src/cast.rs | 1 + compiler/rustc_hir_typeck/src/closure.rs | 1 + compiler/rustc_hir_typeck/src/coercion.rs | 1 + compiler/rustc_hir_typeck/src/demand.rs | 1 + compiler/rustc_hir_typeck/src/expr.rs | 1 + compiler/rustc_hir_typeck/src/expr_use_visitor.rs | 1 + compiler/rustc_hir_typeck/src/fallback.rs | 1 + compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs | 1 + compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs | 1 + compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs | 1 + compiler/rustc_hir_typeck/src/intrinsicck.rs | 1 + compiler/rustc_hir_typeck/src/lib.rs | 4 +--- compiler/rustc_hir_typeck/src/method/confirm.rs | 1 + compiler/rustc_hir_typeck/src/method/mod.rs | 1 + compiler/rustc_hir_typeck/src/method/prelude2021.rs | 1 + compiler/rustc_hir_typeck/src/method/probe.rs | 1 + compiler/rustc_hir_typeck/src/method/suggest.rs | 1 + compiler/rustc_hir_typeck/src/op.rs | 1 + compiler/rustc_hir_typeck/src/pat.rs | 1 + compiler/rustc_hir_typeck/src/place_op.rs | 1 + compiler/rustc_hir_typeck/src/rvalue_scopes.rs | 1 + compiler/rustc_hir_typeck/src/typeck_root_ctxt.rs | 1 + compiler/rustc_hir_typeck/src/upvar.rs | 1 + compiler/rustc_hir_typeck/src/writeback.rs | 1 + 25 files changed, 25 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs index defb557867b79..1347e850d6fba 100644 --- a/compiler/rustc_hir_typeck/src/callee.rs +++ b/compiler/rustc_hir_typeck/src/callee.rs @@ -19,6 +19,7 @@ use rustc_middle::ty::adjustment::{ }; use rustc_middle::ty::GenericArgsRef; use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt}; +use rustc_middle::{bug, span_bug}; use rustc_span::def_id::LocalDefId; use rustc_span::symbol::{sym, Ident}; use rustc_span::Span; diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs index 92f74281ab982..316a2bf08cb03 100644 --- a/compiler/rustc_hir_typeck/src/cast.rs +++ b/compiler/rustc_hir_typeck/src/cast.rs @@ -36,6 +36,7 @@ use hir::ExprKind; use rustc_errors::{codes::*, Applicability, Diag, ErrorGuaranteed}; use rustc_hir as hir; use rustc_macros::{TypeFoldable, TypeVisitable}; +use rustc_middle::bug; use rustc_middle::mir::Mutability; use rustc_middle::ty::adjustment::AllowTwoPhase; use rustc_middle::ty::cast::{CastKind, CastTy}; diff --git a/compiler/rustc_hir_typeck/src/closure.rs b/compiler/rustc_hir_typeck/src/closure.rs index f52f95db6d342..2ff46689d4a76 100644 --- a/compiler/rustc_hir_typeck/src/closure.rs +++ b/compiler/rustc_hir_typeck/src/closure.rs @@ -10,6 +10,7 @@ use rustc_infer::infer::{BoundRegionConversionTime, DefineOpaqueTypes}; use rustc_infer::infer::{InferOk, InferResult}; use rustc_infer::traits::ObligationCauseCode; use rustc_macros::{TypeFoldable, TypeVisitable}; +use rustc_middle::span_bug; use rustc_middle::ty::visit::{TypeVisitable, TypeVisitableExt}; use rustc_middle::ty::GenericArgs; use rustc_middle::ty::{self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitor}; diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index 88ba937e4b5bc..8d93f402f10c5 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -45,6 +45,7 @@ use rustc_infer::infer::{Coercion, DefineOpaqueTypes, InferOk, InferResult}; use rustc_infer::traits::{IfExpressionCause, MatchExpressionArmCause}; use rustc_infer::traits::{Obligation, PredicateObligation}; use rustc_middle::lint::in_external_macro; +use rustc_middle::span_bug; use rustc_middle::traits::BuiltinImplSource; use rustc_middle::ty::adjustment::{ Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability, PointerCoercion, diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs index b211249173324..706f6f875bf64 100644 --- a/compiler/rustc_hir_typeck/src/demand.rs +++ b/compiler/rustc_hir_typeck/src/demand.rs @@ -5,6 +5,7 @@ use rustc_hir as hir; use rustc_hir::def::Res; use rustc_hir::intravisit::Visitor; use rustc_infer::infer::{DefineOpaqueTypes, InferOk}; +use rustc_middle::bug; use rustc_middle::ty::adjustment::AllowTwoPhase; use rustc_middle::ty::error::{ExpectedFound, TypeError}; use rustc_middle::ty::fold::BottomUpFolder; diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index cdf17f3a1131c..f283c0138052e 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -45,6 +45,7 @@ use rustc_middle::ty::adjustment::{Adjust, Adjustment, AllowTwoPhase}; use rustc_middle::ty::error::{ExpectedFound, TypeError::Sorts}; use rustc_middle::ty::GenericArgsRef; use rustc_middle::ty::{self, AdtKind, Ty, TypeVisitableExt}; +use rustc_middle::{bug, span_bug}; use rustc_session::errors::ExprParenthesesNeeded; use rustc_session::parse::feature_err; use rustc_span::edit_distance::find_best_match_for_name; diff --git a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs index 589f41948defb..1864c7e6ef82d 100644 --- a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs +++ b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs @@ -18,6 +18,7 @@ use rustc_hir as hir; use rustc_hir::def::{CtorOf, Res}; use rustc_hir::def_id::LocalDefId; use rustc_hir::{HirId, PatKind}; +use rustc_middle::{bug, span_bug}; use rustc_middle::hir::place::ProjectionKind; use rustc_middle::mir::FakeReadCause; use rustc_middle::ty::{ diff --git a/compiler/rustc_hir_typeck/src/fallback.rs b/compiler/rustc_hir_typeck/src/fallback.rs index f240a53a67974..c79b6be656066 100644 --- a/compiler/rustc_hir_typeck/src/fallback.rs +++ b/compiler/rustc_hir_typeck/src/fallback.rs @@ -9,6 +9,7 @@ use rustc_hir as hir; use rustc_hir::intravisit::Visitor; use rustc_hir::HirId; use rustc_infer::infer::{DefineOpaqueTypes, InferOk}; +use rustc_middle::bug; use rustc_middle::ty::{self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable}; use rustc_session::lint; use rustc_span::DUMMY_SP; diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index b32cab6d3f71f..6e8ef04445215 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -29,6 +29,7 @@ use rustc_middle::ty::{ self, AdtKind, CanonicalUserType, GenericParamDefKind, IsIdentity, Ty, TyCtxt, UserType, }; use rustc_middle::ty::{GenericArgKind, GenericArgsRef, UserArgs, UserSelfTy}; +use rustc_middle::{bug, span_bug}; use rustc_session::lint; use rustc_span::def_id::LocalDefId; use rustc_span::hygiene::DesugaringKind; diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index 5fa715dc7618b..aea34407a2d55 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -36,6 +36,7 @@ use rustc_infer::infer::{DefineOpaqueTypes, InferOk}; use rustc_middle::ty::adjustment::AllowTwoPhase; use rustc_middle::ty::visit::TypeVisitableExt; use rustc_middle::ty::{self, IsSuggestable, Ty, TyCtxt}; +use rustc_middle::{bug, span_bug}; use rustc_session::Session; use rustc_span::symbol::{kw, Ident}; use rustc_span::{sym, BytePos, Span, DUMMY_SP}; diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index f1b719f24c7ac..11f288391c3bd 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -25,6 +25,7 @@ use rustc_hir_analysis::hir_ty_lowering::HirTyLowerer; use rustc_infer::traits; use rustc_middle::lint::in_external_macro; use rustc_middle::middle::stability::EvalResult; +use rustc_middle::span_bug; use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::{ self, suggest_constraining_type_params, Article, Binder, IsSuggestable, ToPredicate, Ty, diff --git a/compiler/rustc_hir_typeck/src/intrinsicck.rs b/compiler/rustc_hir_typeck/src/intrinsicck.rs index 62711e40049a4..fb8863c143f76 100644 --- a/compiler/rustc_hir_typeck/src/intrinsicck.rs +++ b/compiler/rustc_hir_typeck/src/intrinsicck.rs @@ -2,6 +2,7 @@ use hir::HirId; use rustc_errors::{codes::*, struct_span_code_err}; use rustc_hir as hir; use rustc_index::Idx; +use rustc_middle::bug; use rustc_middle::ty::layout::{LayoutError, SizeSkeleton}; use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt}; use rustc_target::abi::{Pointer, VariantIdx}; diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index 296560dd5baba..6892da7a5e23d 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -10,9 +10,6 @@ #[macro_use] extern crate tracing; -#[macro_use] -extern crate rustc_middle; - mod _match; mod autoderef; mod callee; @@ -62,6 +59,7 @@ use rustc_hir_analysis::hir_ty_lowering::HirTyLowerer; use rustc_infer::traits::{ObligationCauseCode, ObligationInspector, WellFormedLoc}; use rustc_middle::query::Providers; use rustc_middle::ty::{self, Ty, TyCtxt}; +use rustc_middle::{bug, span_bug}; use rustc_session::config; use rustc_span::def_id::LocalDefId; use rustc_span::Span; diff --git a/compiler/rustc_hir_typeck/src/method/confirm.rs b/compiler/rustc_hir_typeck/src/method/confirm.rs index 007ec7ff378ab..7425405853483 100644 --- a/compiler/rustc_hir_typeck/src/method/confirm.rs +++ b/compiler/rustc_hir_typeck/src/method/confirm.rs @@ -16,6 +16,7 @@ use rustc_middle::ty::fold::TypeFoldable; use rustc_middle::ty::{ self, GenericArgs, GenericArgsRef, GenericParamDefKind, Ty, TyCtxt, UserArgs, UserType, }; +use rustc_middle::{bug, span_bug}; use rustc_span::{Span, DUMMY_SP}; use rustc_trait_selection::traits; diff --git a/compiler/rustc_hir_typeck/src/method/mod.rs b/compiler/rustc_hir_typeck/src/method/mod.rs index ec613f3d14e72..f82182fa0583c 100644 --- a/compiler/rustc_hir_typeck/src/method/mod.rs +++ b/compiler/rustc_hir_typeck/src/method/mod.rs @@ -20,6 +20,7 @@ use rustc_middle::query::Providers; use rustc_middle::traits::ObligationCause; use rustc_middle::ty::{self, GenericParamDefKind, Ty, TypeVisitableExt}; use rustc_middle::ty::{GenericArgs, GenericArgsRef}; +use rustc_middle::{bug, span_bug}; use rustc_span::symbol::Ident; use rustc_span::Span; use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt; diff --git a/compiler/rustc_hir_typeck/src/method/prelude2021.rs b/compiler/rustc_hir_typeck/src/method/prelude2021.rs index 305aaf3b8ddd5..a305461344d4d 100644 --- a/compiler/rustc_hir_typeck/src/method/prelude2021.rs +++ b/compiler/rustc_hir_typeck/src/method/prelude2021.rs @@ -7,6 +7,7 @@ use hir::HirId; use hir::ItemKind; use rustc_errors::Applicability; use rustc_hir as hir; +use rustc_middle::span_bug; use rustc_middle::ty::{self, Ty}; use rustc_session::lint::builtin::RUST_2021_PRELUDE_COLLISIONS; use rustc_span::symbol::kw::{Empty, Underscore}; diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index e9446b862fa0d..81e179c90900c 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -24,6 +24,7 @@ use rustc_middle::ty::GenericParamDefKind; use rustc_middle::ty::ToPredicate; use rustc_middle::ty::{self, ParamEnvAnd, Ty, TyCtxt, TypeVisitableExt}; use rustc_middle::ty::{GenericArgs, GenericArgsRef}; +use rustc_middle::{bug, span_bug}; use rustc_session::lint; use rustc_span::def_id::DefId; use rustc_span::def_id::LocalDefId; diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 0483bd0357675..e8a15eb0ca33e 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -23,6 +23,7 @@ use rustc_hir::PatKind::Binding; use rustc_hir::PathSegment; use rustc_hir::{ExprKind, Node, QPath}; use rustc_infer::infer::{self, RegionVariableOrigin}; +use rustc_middle::bug; use rustc_middle::ty::fast_reject::DeepRejectCtxt; use rustc_middle::ty::fast_reject::{simplify_type, TreatParams}; use rustc_middle::ty::print::{ diff --git a/compiler/rustc_hir_typeck/src/op.rs b/compiler/rustc_hir_typeck/src/op.rs index dca1cda069408..e371775be0aa4 100644 --- a/compiler/rustc_hir_typeck/src/op.rs +++ b/compiler/rustc_hir_typeck/src/op.rs @@ -13,6 +13,7 @@ use rustc_middle::ty::adjustment::{ }; use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::{self, IsSuggestable, Ty, TyCtxt, TypeVisitableExt}; +use rustc_middle::{bug, span_bug}; use rustc_session::errors::ExprParenthesesNeeded; use rustc_span::source_map::Spanned; use rustc_span::symbol::{sym, Ident}; diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index 259336f438d64..ae1ca546b9526 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -11,6 +11,7 @@ use rustc_hir::{self as hir, BindingMode, ByRef, HirId, Mutability, Pat, PatKind use rustc_infer::infer; use rustc_middle::mir::interpret::ErrorHandled; use rustc_middle::ty::{self, Ty, TypeVisitableExt}; +use rustc_middle::{bug, span_bug}; use rustc_session::lint::builtin::NON_EXHAUSTIVE_OMITTED_PATTERNS; use rustc_span::edit_distance::find_best_match_for_name; use rustc_span::hygiene::DesugaringKind; diff --git a/compiler/rustc_hir_typeck/src/place_op.rs b/compiler/rustc_hir_typeck/src/place_op.rs index 374279722ba28..515e1b5ed0e0b 100644 --- a/compiler/rustc_hir_typeck/src/place_op.rs +++ b/compiler/rustc_hir_typeck/src/place_op.rs @@ -5,6 +5,7 @@ use rustc_errors::Applicability; use rustc_hir as hir; use rustc_hir_analysis::autoderef::Autoderef; use rustc_infer::infer::InferOk; +use rustc_middle::span_bug; use rustc_middle::ty::adjustment::{Adjust, Adjustment, OverloadedDeref, PointerCoercion}; use rustc_middle::ty::adjustment::{AllowTwoPhase, AutoBorrow, AutoBorrowMutability}; use rustc_middle::ty::{self, Ty}; diff --git a/compiler/rustc_hir_typeck/src/rvalue_scopes.rs b/compiler/rustc_hir_typeck/src/rvalue_scopes.rs index 34ce0ab1f8b98..805f36d9b97a1 100644 --- a/compiler/rustc_hir_typeck/src/rvalue_scopes.rs +++ b/compiler/rustc_hir_typeck/src/rvalue_scopes.rs @@ -2,6 +2,7 @@ use super::FnCtxt; use hir::def_id::DefId; use hir::Node; use rustc_hir as hir; +use rustc_middle::bug; use rustc_middle::middle::region::{RvalueCandidateType, Scope, ScopeTree}; use rustc_middle::ty::RvalueScopes; diff --git a/compiler/rustc_hir_typeck/src/typeck_root_ctxt.rs b/compiler/rustc_hir_typeck/src/typeck_root_ctxt.rs index 31ce271a5fc48..19d6481cc1b8b 100644 --- a/compiler/rustc_hir_typeck/src/typeck_root_ctxt.rs +++ b/compiler/rustc_hir_typeck/src/typeck_root_ctxt.rs @@ -5,6 +5,7 @@ use rustc_hir as hir; use rustc_hir::def_id::LocalDefId; use rustc_hir::{HirId, HirIdMap}; use rustc_infer::infer::{InferCtxt, InferOk, TyCtxtInferExt}; +use rustc_middle::span_bug; use rustc_middle::ty::visit::TypeVisitableExt; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_span::def_id::LocalDefIdMap; diff --git a/compiler/rustc_hir_typeck/src/upvar.rs b/compiler/rustc_hir_typeck/src/upvar.rs index 819a8b661167c..d313c0eafe101 100644 --- a/compiler/rustc_hir_typeck/src/upvar.rs +++ b/compiler/rustc_hir_typeck/src/upvar.rs @@ -47,6 +47,7 @@ use rustc_middle::ty::{ self, ClosureSizeProfileData, Ty, TyCtxt, TypeVisitableExt as _, TypeckResults, UpvarArgs, UpvarCapture, }; +use rustc_middle::{bug, span_bug}; use rustc_session::lint; use rustc_span::sym; use rustc_span::{BytePos, Pos, Span, Symbol}; diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs index 0a40ffb0d5aab..fe717fae60311 100644 --- a/compiler/rustc_hir_typeck/src/writeback.rs +++ b/compiler/rustc_hir_typeck/src/writeback.rs @@ -9,6 +9,7 @@ use rustc_hir as hir; use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::HirId; use rustc_infer::infer::error_reporting::TypeAnnotationNeeded::E0282; +use rustc_middle::span_bug; use rustc_middle::traits::ObligationCause; use rustc_middle::ty::adjustment::{Adjust, Adjustment, PointerCoercion}; use rustc_middle::ty::fold::{TypeFoldable, TypeFolder}; From 34e247af1ee905d12f87f8099dd38647e8bfecb4 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 8 May 2024 18:06:19 +1000 Subject: [PATCH 139/179] Remove `extern crate rustc_middle` from `rustc_infer`. --- compiler/rustc_infer/src/errors/note_and_explain.rs | 1 + compiler/rustc_infer/src/infer/at.rs | 1 + compiler/rustc_infer/src/infer/canonical/canonicalizer.rs | 1 + compiler/rustc_infer/src/infer/canonical/instantiate.rs | 1 + compiler/rustc_infer/src/infer/canonical/query_response.rs | 1 + compiler/rustc_infer/src/infer/error_reporting/mod.rs | 1 + .../rustc_infer/src/infer/error_reporting/need_type_info.rs | 1 + .../nice_region_error/mismatched_static_lifetime.rs | 1 + .../error_reporting/nice_region_error/placeholder_error.rs | 1 + compiler/rustc_infer/src/infer/freshen.rs | 1 + compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs | 1 + compiler/rustc_infer/src/infer/mod.rs | 1 + compiler/rustc_infer/src/infer/opaque_types/table.rs | 1 + compiler/rustc_infer/src/infer/outlives/env.rs | 1 + compiler/rustc_infer/src/infer/outlives/obligations.rs | 1 + compiler/rustc_infer/src/infer/region_constraints/leak_check.rs | 1 + compiler/rustc_infer/src/infer/region_constraints/mod.rs | 1 + compiler/rustc_infer/src/infer/relate/combine.rs | 1 + compiler/rustc_infer/src/infer/relate/generalize.rs | 1 + compiler/rustc_infer/src/infer/resolve.rs | 1 + compiler/rustc_infer/src/infer/type_variable.rs | 1 + compiler/rustc_infer/src/lib.rs | 2 -- 22 files changed, 21 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_infer/src/errors/note_and_explain.rs b/compiler/rustc_infer/src/errors/note_and_explain.rs index c7f07ebed973f..f0b336ca04615 100644 --- a/compiler/rustc_infer/src/errors/note_and_explain.rs +++ b/compiler/rustc_infer/src/errors/note_and_explain.rs @@ -1,6 +1,7 @@ use crate::fluent_generated as fluent; use crate::infer::error_reporting::nice_region_error::find_anon_type; use rustc_errors::{Diag, EmissionGuarantee, IntoDiagArg, SubdiagMessageOp, Subdiagnostic}; +use rustc_middle::bug; use rustc_middle::ty::{self, TyCtxt}; use rustc_span::{symbol::kw, Span}; diff --git a/compiler/rustc_infer/src/infer/at.rs b/compiler/rustc_infer/src/infer/at.rs index 0f21d3966c40b..57b58006e2364 100644 --- a/compiler/rustc_infer/src/infer/at.rs +++ b/compiler/rustc_infer/src/infer/at.rs @@ -27,6 +27,7 @@ use super::*; +use rustc_middle::bug; use rustc_middle::ty::relate::{Relate, TypeRelation}; use rustc_middle::ty::{Const, ImplSubject}; diff --git a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs index 4d712e9ffd372..27b06c4b73e9d 100644 --- a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs +++ b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs @@ -9,6 +9,7 @@ use crate::infer::canonical::{ Canonical, CanonicalTyVarKind, CanonicalVarInfo, CanonicalVarKind, OriginalQueryValues, }; use crate::infer::InferCtxt; +use rustc_middle::bug; use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable}; use rustc_middle::ty::GenericArg; use rustc_middle::ty::{self, BoundVar, InferConst, List, Ty, TyCtxt, TypeFlags, TypeVisitableExt}; diff --git a/compiler/rustc_infer/src/infer/canonical/instantiate.rs b/compiler/rustc_infer/src/infer/canonical/instantiate.rs index f95cc13623cd1..de0e15ef3def1 100644 --- a/compiler/rustc_infer/src/infer/canonical/instantiate.rs +++ b/compiler/rustc_infer/src/infer/canonical/instantiate.rs @@ -8,6 +8,7 @@ use crate::infer::canonical::{Canonical, CanonicalVarValues}; use rustc_macros::extension; +use rustc_middle::bug; use rustc_middle::ty::fold::{FnMutDelegate, TypeFoldable}; use rustc_middle::ty::GenericArgKind; use rustc_middle::ty::{self, TyCtxt}; diff --git a/compiler/rustc_infer/src/infer/canonical/query_response.rs b/compiler/rustc_infer/src/infer/canonical/query_response.rs index b948067e750eb..1732913e19150 100644 --- a/compiler/rustc_infer/src/infer/canonical/query_response.rs +++ b/compiler/rustc_infer/src/infer/canonical/query_response.rs @@ -25,6 +25,7 @@ use rustc_middle::mir::ConstraintCategory; use rustc_middle::ty::fold::TypeFoldable; use rustc_middle::ty::{self, BoundVar, Ty, TyCtxt}; use rustc_middle::ty::{GenericArg, GenericArgKind}; +use rustc_middle::{bug, span_bug}; use std::fmt::Debug; use std::iter; diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 3488517a4ef9b..4cb0bf83aacdd 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -69,6 +69,7 @@ use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::intravisit::Visitor; use rustc_hir::lang_items::LangItem; use rustc_macros::extension; +use rustc_middle::bug; use rustc_middle::dep_graph::DepContext; use rustc_middle::ty::print::{with_forced_trimmed_paths, PrintError, PrintTraitRefExt as _}; use rustc_middle::ty::relate::{self, RelateResult, TypeRelation}; diff --git a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs index 415f0eee8c510..b4decbf14a233 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs @@ -11,6 +11,7 @@ use rustc_hir::def::{CtorOf, DefKind, Namespace}; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::{Body, Closure, Expr, ExprKind, FnRetTy, HirId, LetStmt, LocalSource}; +use rustc_middle::bug; use rustc_middle::hir::nested_filter; use rustc_middle::infer::unify_key::ConstVariableValue; use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow}; diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mismatched_static_lifetime.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mismatched_static_lifetime.rs index fdfce7f8f73c7..45dce0a0e3307 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mismatched_static_lifetime.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mismatched_static_lifetime.rs @@ -13,6 +13,7 @@ use rustc_data_structures::fx::FxIndexSet; use rustc_errors::{ErrorGuaranteed, MultiSpan}; use rustc_hir as hir; use rustc_hir::intravisit::Visitor; +use rustc_middle::bug; use rustc_middle::ty::TypeVisitor; impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs index 31d45133eb0bc..8859772848fa6 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs @@ -11,6 +11,7 @@ use rustc_data_structures::intern::Interned; use rustc_errors::{Diag, IntoDiagArg}; use rustc_hir::def::Namespace; use rustc_hir::def_id::{DefId, CRATE_DEF_ID}; +use rustc_middle::bug; use rustc_middle::ty::error::ExpectedFound; use rustc_middle::ty::print::{FmtPrinter, Print, PrintTraitRefExt as _, RegionHighlightMode}; use rustc_middle::ty::GenericArgsRef; diff --git a/compiler/rustc_infer/src/infer/freshen.rs b/compiler/rustc_infer/src/infer/freshen.rs index ef9c407acef5c..b2d89523ea840 100644 --- a/compiler/rustc_infer/src/infer/freshen.rs +++ b/compiler/rustc_infer/src/infer/freshen.rs @@ -32,6 +32,7 @@ //! inferencer knows "so far". use super::InferCtxt; use rustc_data_structures::fx::FxHashMap; +use rustc_middle::bug; use rustc_middle::infer::unify_key::ToType; use rustc_middle::ty::fold::TypeFolder; use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, TypeSuperFoldable, TypeVisitableExt}; diff --git a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs index 5ae7f8bf5048b..72944c9c7de68 100644 --- a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs +++ b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs @@ -20,6 +20,7 @@ use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_middle::ty::{ReBound, RePlaceholder, ReVar}; use rustc_middle::ty::{ReEarlyParam, ReErased, ReError, ReLateParam, ReStatic}; use rustc_middle::ty::{Region, RegionVid}; +use rustc_middle::{bug, span_bug}; use rustc_span::Span; use std::fmt; diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index ce82296a8aadd..efd883d0d8301 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -44,6 +44,7 @@ use rustc_middle::ty::visit::TypeVisitableExt; use rustc_middle::ty::{self, GenericParamDefKind, InferConst, InferTy, Ty, TyCtxt}; use rustc_middle::ty::{ConstVid, EffectVid, FloatVid, IntVid, TyVid}; use rustc_middle::ty::{GenericArg, GenericArgKind, GenericArgs, GenericArgsRef}; +use rustc_middle::{bug, span_bug}; use rustc_span::symbol::Symbol; use rustc_span::Span; use snapshot::undo_log::InferCtxtUndoLogs; diff --git a/compiler/rustc_infer/src/infer/opaque_types/table.rs b/compiler/rustc_infer/src/infer/opaque_types/table.rs index a7ddf47543628..e07d181e4e0a3 100644 --- a/compiler/rustc_infer/src/infer/opaque_types/table.rs +++ b/compiler/rustc_infer/src/infer/opaque_types/table.rs @@ -1,4 +1,5 @@ use rustc_data_structures::undo_log::UndoLogs; +use rustc_middle::bug; use rustc_middle::ty::{self, OpaqueHiddenType, OpaqueTypeKey, Ty}; use crate::infer::snapshot::undo_log::{InferCtxtUndoLogs, UndoLog}; diff --git a/compiler/rustc_infer/src/infer/outlives/env.rs b/compiler/rustc_infer/src/infer/outlives/env.rs index f8dbfdde30c50..c44a5082f68bd 100644 --- a/compiler/rustc_infer/src/infer/outlives/env.rs +++ b/compiler/rustc_infer/src/infer/outlives/env.rs @@ -3,6 +3,7 @@ use crate::infer::GenericKind; use crate::traits::query::OutlivesBound; use rustc_data_structures::fx::FxIndexSet; use rustc_data_structures::transitive_relation::TransitiveRelationBuilder; +use rustc_middle::bug; use rustc_middle::ty::{self, Region}; use super::explicit_outlives_bounds; diff --git a/compiler/rustc_infer/src/infer/outlives/obligations.rs b/compiler/rustc_infer/src/infer/outlives/obligations.rs index e0d23d7629f99..32c790523b64c 100644 --- a/compiler/rustc_infer/src/infer/outlives/obligations.rs +++ b/compiler/rustc_infer/src/infer/outlives/obligations.rs @@ -67,6 +67,7 @@ use crate::infer::snapshot::undo_log::UndoLog; use crate::infer::{self, GenericKind, InferCtxt, RegionObligation, SubregionOrigin, VerifyBound}; use crate::traits::{ObligationCause, ObligationCauseCode}; use rustc_data_structures::undo_log::UndoLogs; +use rustc_middle::bug; use rustc_middle::mir::ConstraintCategory; use rustc_middle::traits::query::NoSolution; use rustc_middle::ty::{ diff --git a/compiler/rustc_infer/src/infer/region_constraints/leak_check.rs b/compiler/rustc_infer/src/infer/region_constraints/leak_check.rs index 6e8efa3e7c182..255ca52d3e98c 100644 --- a/compiler/rustc_infer/src/infer/region_constraints/leak_check.rs +++ b/compiler/rustc_infer/src/infer/region_constraints/leak_check.rs @@ -3,6 +3,7 @@ use crate::infer::snapshot::CombinedSnapshot; use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::graph::{scc::Sccs, vec_graph::VecGraph}; use rustc_index::Idx; +use rustc_middle::span_bug; use rustc_middle::ty::error::TypeError; use rustc_middle::ty::relate::RelateResult; diff --git a/compiler/rustc_infer/src/infer/region_constraints/mod.rs b/compiler/rustc_infer/src/infer/region_constraints/mod.rs index 223e6e3d34416..6f755e07ff17d 100644 --- a/compiler/rustc_infer/src/infer/region_constraints/mod.rs +++ b/compiler/rustc_infer/src/infer/region_constraints/mod.rs @@ -17,6 +17,7 @@ use rustc_middle::ty::ReStatic; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_middle::ty::{ReBound, ReVar}; use rustc_middle::ty::{Region, RegionVid}; +use rustc_middle::{bug, span_bug}; use rustc_span::Span; use std::ops::Range; diff --git a/compiler/rustc_infer/src/infer/relate/combine.rs b/compiler/rustc_infer/src/infer/relate/combine.rs index 8a3125f9dedf8..c1baadfa8df7e 100644 --- a/compiler/rustc_infer/src/infer/relate/combine.rs +++ b/compiler/rustc_infer/src/infer/relate/combine.rs @@ -24,6 +24,7 @@ use super::type_relating::TypeRelating; use super::StructurallyRelateAliases; use crate::infer::{DefineOpaqueTypes, InferCtxt, TypeTrace}; use crate::traits::{Obligation, PredicateObligations}; +use rustc_middle::bug; use rustc_middle::infer::canonical::OriginalQueryValues; use rustc_middle::infer::unify_key::EffectVarValue; use rustc_middle::ty::error::{ExpectedFound, TypeError}; diff --git a/compiler/rustc_infer/src/infer/relate/generalize.rs b/compiler/rustc_infer/src/infer/relate/generalize.rs index 5880ca788bce9..104c16eac0258 100644 --- a/compiler/rustc_infer/src/infer/relate/generalize.rs +++ b/compiler/rustc_infer/src/infer/relate/generalize.rs @@ -6,6 +6,7 @@ use crate::infer::{InferCtxt, ObligationEmittingRelation, RegionVariableOrigin}; use rustc_data_structures::sso::SsoHashMap; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_hir::def_id::DefId; +use rustc_middle::bug; use rustc_middle::infer::unify_key::ConstVariableValue; use rustc_middle::ty::error::TypeError; use rustc_middle::ty::relate::{self, Relate, RelateResult, TypeRelation}; diff --git a/compiler/rustc_infer/src/infer/resolve.rs b/compiler/rustc_infer/src/infer/resolve.rs index 758aac004dcfd..61b13dd9a54fd 100644 --- a/compiler/rustc_infer/src/infer/resolve.rs +++ b/compiler/rustc_infer/src/infer/resolve.rs @@ -1,4 +1,5 @@ use super::{FixupError, FixupResult, InferCtxt}; +use rustc_middle::bug; use rustc_middle::ty::fold::{FallibleTypeFolder, TypeFolder, TypeSuperFoldable}; use rustc_middle::ty::visit::TypeVisitableExt; use rustc_middle::ty::{self, Const, InferConst, Ty, TyCtxt, TypeFoldable}; diff --git a/compiler/rustc_infer/src/infer/type_variable.rs b/compiler/rustc_infer/src/infer/type_variable.rs index 96afa257ebbad..b56b39e61f0c8 100644 --- a/compiler/rustc_infer/src/infer/type_variable.rs +++ b/compiler/rustc_infer/src/infer/type_variable.rs @@ -1,6 +1,7 @@ use rustc_data_structures::undo_log::Rollback; use rustc_hir::def_id::DefId; use rustc_index::IndexVec; +use rustc_middle::bug; use rustc_middle::ty::{self, Ty, TyVid}; use rustc_span::Span; diff --git a/compiler/rustc_infer/src/lib.rs b/compiler/rustc_infer/src/lib.rs index 0299af61d45ca..28d908abf83ed 100644 --- a/compiler/rustc_infer/src/lib.rs +++ b/compiler/rustc_infer/src/lib.rs @@ -31,8 +31,6 @@ #[macro_use] extern crate tracing; -#[macro_use] -extern crate rustc_middle; mod errors; pub mod infer; From 00cfb45b54671cfe5a7b52f5fa18239cd994ba79 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 8 May 2024 18:10:16 +1000 Subject: [PATCH 140/179] Remove `extern crate rustc_middle` from `rustc_metadata`. --- compiler/rustc_metadata/src/creader.rs | 1 + compiler/rustc_metadata/src/dependency_format.rs | 1 + compiler/rustc_metadata/src/lib.rs | 3 --- compiler/rustc_metadata/src/rmeta/decoder.rs | 1 + compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs | 1 + compiler/rustc_metadata/src/rmeta/encoder.rs | 1 + compiler/rustc_metadata/src/rmeta/mod.rs | 1 + 7 files changed, 6 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs index 888c2427d8f46..e3205fc1d30e1 100644 --- a/compiler/rustc_metadata/src/creader.rs +++ b/compiler/rustc_metadata/src/creader.rs @@ -16,6 +16,7 @@ use rustc_fs_util::try_canonicalize; use rustc_hir::def_id::{CrateNum, LocalDefId, StableCrateId, LOCAL_CRATE}; use rustc_hir::definitions::Definitions; use rustc_index::IndexVec; +use rustc_middle::bug; use rustc_middle::ty::{TyCtxt, TyCtxtFeed}; use rustc_session::config::{self, CrateType, ExternLocation}; use rustc_session::cstore::{CrateDepKind, CrateSource, ExternCrate, ExternCrateSource}; diff --git a/compiler/rustc_metadata/src/dependency_format.rs b/compiler/rustc_metadata/src/dependency_format.rs index 4d1bd45541231..99181f9c8605c 100644 --- a/compiler/rustc_metadata/src/dependency_format.rs +++ b/compiler/rustc_metadata/src/dependency_format.rs @@ -59,6 +59,7 @@ use crate::errors::{ use rustc_data_structures::fx::FxHashMap; use rustc_hir::def_id::CrateNum; +use rustc_middle::bug; use rustc_middle::middle::dependency_format::{Dependencies, DependencyList, Linkage}; use rustc_middle::ty::TyCtxt; use rustc_session::config::CrateType; diff --git a/compiler/rustc_metadata/src/lib.rs b/compiler/rustc_metadata/src/lib.rs index c8162a1f0eead..99584845e49ae 100644 --- a/compiler/rustc_metadata/src/lib.rs +++ b/compiler/rustc_metadata/src/lib.rs @@ -19,9 +19,6 @@ extern crate proc_macro; -#[macro_use] -extern crate rustc_middle; - #[macro_use] extern crate tracing; diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index 2a33088513b75..bb68c6eaf092e 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -21,6 +21,7 @@ use rustc_middle::middle::lib_features::LibFeatures; use rustc_middle::mir::interpret::{AllocDecodingSession, AllocDecodingState}; use rustc_middle::ty::codec::TyDecoder; use rustc_middle::ty::Visibility; +use rustc_middle::{bug, implement_ty_decoder}; use rustc_serialize::opaque::MemDecoder; use rustc_serialize::{Decodable, Decoder}; use rustc_session::cstore::{CrateSource, ExternCrate}; diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index 531b2e05411a0..c783149a69514 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -11,6 +11,7 @@ use rustc_hir::def::{CtorKind, DefKind, Res}; use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LOCAL_CRATE}; use rustc_hir::definitions::{DefKey, DefPath, DefPathHash}; use rustc_middle::arena::ArenaAllocatable; +use rustc_middle::bug; use rustc_middle::metadata::ModChild; use rustc_middle::middle::exported_symbols::ExportedSymbol; use rustc_middle::middle::stability::DeprecationEntry; diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 7c96a6fa9a978..db0dc6d9064b7 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -20,6 +20,7 @@ use rustc_middle::ty::codec::TyEncoder; use rustc_middle::ty::fast_reject::{self, TreatParams}; use rustc_middle::ty::{AssocItemContainer, SymbolName}; use rustc_middle::util::common::to_readable_str; +use rustc_middle::{bug, span_bug}; use rustc_serialize::{opaque, Decodable, Decoder, Encodable, Encoder}; use rustc_session::config::{CrateType, OptLevel}; use rustc_span::hygiene::HygieneEncodeContext; diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index c9cb2f5a2405c..79e4ff81093b0 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -24,6 +24,7 @@ use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs; use rustc_middle::middle::exported_symbols::{ExportedSymbol, SymbolExportInfo}; use rustc_middle::middle::resolve_bound_vars::ObjectLifetimeDefault; use rustc_middle::mir; +use rustc_middle::trivially_parameterized_over_tcx; use rustc_middle::ty::fast_reject::SimplifiedType; use rustc_middle::ty::{self, ReprOptions, Ty, UnusedGenericParams}; use rustc_middle::ty::{DeducedParamAttrs, ParameterizedOverTcx, TyCtxt}; From 900bcacf3a877a28b14d070d64f4b4b549238dc8 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 8 May 2024 19:31:05 +1000 Subject: [PATCH 141/179] Remove `extern crate rustc_middle` from `rustc_mir_build`. --- compiler/rustc_mir_build/src/build/block.rs | 1 + .../rustc_mir_build/src/build/coverageinfo/mcdc.rs | 1 + compiler/rustc_mir_build/src/build/custom/mod.rs | 1 + .../rustc_mir_build/src/build/expr/as_constant.rs | 1 + compiler/rustc_mir_build/src/build/expr/as_place.rs | 1 + compiler/rustc_mir_build/src/build/expr/as_rvalue.rs | 1 + compiler/rustc_mir_build/src/build/expr/into.rs | 1 + compiler/rustc_mir_build/src/build/matches/mod.rs | 1 + compiler/rustc_mir_build/src/build/matches/test.rs | 1 + compiler/rustc_mir_build/src/build/mod.rs | 1 + compiler/rustc_mir_build/src/build/scope.rs | 1 + compiler/rustc_mir_build/src/check_unsafety.rs | 1 + compiler/rustc_mir_build/src/lib.rs | 2 -- compiler/rustc_mir_build/src/thir/constant.rs | 1 + compiler/rustc_mir_build/src/thir/cx/expr.rs | 1 + compiler/rustc_mir_build/src/thir/cx/mod.rs | 1 + .../rustc_mir_build/src/thir/pattern/check_match.rs | 12 ++++++------ .../rustc_mir_build/src/thir/pattern/const_to_pat.rs | 1 + compiler/rustc_mir_build/src/thir/pattern/mod.rs | 1 + compiler/rustc_mir_build/src/thir/util.rs | 1 + 20 files changed, 24 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_mir_build/src/build/block.rs b/compiler/rustc_mir_build/src/build/block.rs index 00e99f330f727..6ae98e15946d7 100644 --- a/compiler/rustc_mir_build/src/build/block.rs +++ b/compiler/rustc_mir_build/src/build/block.rs @@ -1,6 +1,7 @@ use crate::build::ForGuard::OutsideGuard; use crate::build::{BlockAnd, BlockAndExtension, BlockFrame, Builder}; use rustc_middle::middle::region::Scope; +use rustc_middle::span_bug; use rustc_middle::thir::*; use rustc_middle::{mir::*, ty}; use rustc_span::Span; diff --git a/compiler/rustc_mir_build/src/build/coverageinfo/mcdc.rs b/compiler/rustc_mir_build/src/build/coverageinfo/mcdc.rs index 566dba460d43b..9cfb25e663d11 100644 --- a/compiler/rustc_mir_build/src/build/coverageinfo/mcdc.rs +++ b/compiler/rustc_mir_build/src/build/coverageinfo/mcdc.rs @@ -1,5 +1,6 @@ use std::collections::VecDeque; +use rustc_middle::bug; use rustc_middle::mir::coverage::{ BlockMarkerId, ConditionId, ConditionInfo, MCDCBranchSpan, MCDCDecisionSpan, }; diff --git a/compiler/rustc_mir_build/src/build/custom/mod.rs b/compiler/rustc_mir_build/src/build/custom/mod.rs index 30877e38318d6..a0a512a2effcf 100644 --- a/compiler/rustc_mir_build/src/build/custom/mod.rs +++ b/compiler/rustc_mir_build/src/build/custom/mod.rs @@ -24,6 +24,7 @@ use rustc_hir::HirId; use rustc_index::{IndexSlice, IndexVec}; use rustc_middle::{ mir::*, + span_bug, thir::*, ty::{ParamEnv, Ty, TyCtxt}, }; diff --git a/compiler/rustc_mir_build/src/build/expr/as_constant.rs b/compiler/rustc_mir_build/src/build/expr/as_constant.rs index a557f61b016bc..817f5f787b1b1 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_constant.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_constant.rs @@ -9,6 +9,7 @@ use rustc_middle::thir::*; use rustc_middle::ty::{ self, CanonicalUserType, CanonicalUserTypeAnnotation, TyCtxt, UserTypeAnnotationIndex, }; +use rustc_middle::{bug, span_bug}; use rustc_target::abi::Size; impl<'a, 'tcx> Builder<'a, 'tcx> { diff --git a/compiler/rustc_mir_build/src/build/expr/as_place.rs b/compiler/rustc_mir_build/src/build/expr/as_place.rs index 060b328ef48ae..9963629fc52f7 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_place.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_place.rs @@ -4,6 +4,7 @@ use crate::build::expr::category::Category; use crate::build::ForGuard::{OutsideGuard, RefWithinGuard}; use crate::build::{BlockAnd, BlockAndExtension, Builder, Capture, CaptureMap}; use rustc_hir::def_id::LocalDefId; +use rustc_middle::bug; use rustc_middle::hir::place::Projection as HirProjection; use rustc_middle::hir::place::ProjectionKind as HirProjectionKind; use rustc_middle::middle::region; diff --git a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs index 260ab058e600c..0b2248d049afc 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs @@ -9,6 +9,7 @@ use crate::build::expr::as_place::PlaceBase; use crate::build::expr::category::{Category, RvalueFunc}; use crate::build::{BlockAnd, BlockAndExtension, Builder, NeedsTemporary}; use rustc_hir::lang_items::LangItem; +use rustc_middle::bug; use rustc_middle::middle::region; use rustc_middle::mir::interpret::Scalar; use rustc_middle::mir::*; diff --git a/compiler/rustc_mir_build/src/build/expr/into.rs b/compiler/rustc_mir_build/src/build/expr/into.rs index c8360b6a5fdd2..f8c910730456c 100644 --- a/compiler/rustc_mir_build/src/build/expr/into.rs +++ b/compiler/rustc_mir_build/src/build/expr/into.rs @@ -7,6 +7,7 @@ use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_hir as hir; use rustc_middle::mir::*; +use rustc_middle::span_bug; use rustc_middle::thir::*; use rustc_middle::ty::CanonicalUserTypeAnnotation; use rustc_span::source_map::Spanned; diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs index 7cf4fac731b41..3fc719394bf9e 100644 --- a/compiler/rustc_mir_build/src/build/matches/mod.rs +++ b/compiler/rustc_mir_build/src/build/matches/mod.rs @@ -12,6 +12,7 @@ use crate::build::{BlockAnd, BlockAndExtension, Builder}; use crate::build::{GuardFrame, GuardFrameLocal, LocalsForNode}; use rustc_data_structures::{fx::FxIndexMap, stack::ensure_sufficient_stack}; use rustc_hir::{BindingMode, ByRef}; +use rustc_middle::bug; use rustc_middle::middle::region; use rustc_middle::mir::{self, *}; use rustc_middle::thir::{self, *}; diff --git a/compiler/rustc_mir_build/src/build/matches/test.rs b/compiler/rustc_mir_build/src/build/matches/test.rs index 7f65697fa4b2b..f3faeb4158eef 100644 --- a/compiler/rustc_mir_build/src/build/matches/test.rs +++ b/compiler/rustc_mir_build/src/build/matches/test.rs @@ -13,6 +13,7 @@ use rustc_middle::mir::*; use rustc_middle::ty::util::IntTypeExt; use rustc_middle::ty::GenericArg; use rustc_middle::ty::{self, adjustment::PointerCoercion, Ty, TyCtxt}; +use rustc_middle::{bug, span_bug}; use rustc_span::def_id::DefId; use rustc_span::source_map::Spanned; use rustc_span::symbol::{sym, Symbol}; diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs index 794e7ebb7b431..92cd7f75d6283 100644 --- a/compiler/rustc_mir_build/src/build/mod.rs +++ b/compiler/rustc_mir_build/src/build/mod.rs @@ -20,6 +20,7 @@ use rustc_middle::mir::*; use rustc_middle::query::TyCtxtAt; use rustc_middle::thir::{self, ExprId, LintLevel, LocalVarId, Param, ParamId, PatKind, Thir}; use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt}; +use rustc_middle::{bug, span_bug}; use rustc_span::symbol::sym; use rustc_span::Span; use rustc_span::Symbol; diff --git a/compiler/rustc_mir_build/src/build/scope.rs b/compiler/rustc_mir_build/src/build/scope.rs index 2d31e84aba7da..be32363fec528 100644 --- a/compiler/rustc_mir_build/src/build/scope.rs +++ b/compiler/rustc_mir_build/src/build/scope.rs @@ -90,6 +90,7 @@ use rustc_index::{IndexSlice, IndexVec}; use rustc_middle::middle::region; use rustc_middle::mir::*; use rustc_middle::thir::{ExprId, LintLevel}; +use rustc_middle::{bug, span_bug}; use rustc_session::lint::Level; use rustc_span::source_map::Spanned; use rustc_span::{Span, DUMMY_SP}; diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs index 227d19c3e43c5..b9990d65ec77c 100644 --- a/compiler/rustc_mir_build/src/check_unsafety.rs +++ b/compiler/rustc_mir_build/src/check_unsafety.rs @@ -4,6 +4,7 @@ use crate::errors::*; use rustc_errors::DiagArgValue; use rustc_hir::{self as hir, BindingMode, ByRef, HirId, Mutability}; use rustc_middle::mir::BorrowKind; +use rustc_middle::span_bug; use rustc_middle::thir::visit::Visitor; use rustc_middle::thir::*; use rustc_middle::ty::print::with_no_trimmed_paths; diff --git a/compiler/rustc_mir_build/src/lib.rs b/compiler/rustc_mir_build/src/lib.rs index e79e3b887fb43..2e1cb0e1b5e05 100644 --- a/compiler/rustc_mir_build/src/lib.rs +++ b/compiler/rustc_mir_build/src/lib.rs @@ -12,8 +12,6 @@ #[macro_use] extern crate tracing; -#[macro_use] -extern crate rustc_middle; mod build; mod check_unsafety; diff --git a/compiler/rustc_mir_build/src/thir/constant.rs b/compiler/rustc_mir_build/src/thir/constant.rs index 65cc13286afc4..03c7c1fd6ec60 100644 --- a/compiler/rustc_mir_build/src/thir/constant.rs +++ b/compiler/rustc_mir_build/src/thir/constant.rs @@ -1,4 +1,5 @@ use rustc_ast as ast; +use rustc_middle::bug; use rustc_middle::mir::interpret::{LitToConstError, LitToConstInput}; use rustc_middle::ty::{self, ParamEnv, ScalarInt, TyCtxt}; diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs index c697e16217bd4..b77666669605d 100644 --- a/compiler/rustc_mir_build/src/thir/cx/expr.rs +++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs @@ -21,6 +21,7 @@ use rustc_middle::ty::GenericArgs; use rustc_middle::ty::{ self, AdtKind, InlineConstArgs, InlineConstArgsParts, ScalarInt, Ty, UpvarArgs, UserType, }; +use rustc_middle::{bug, span_bug}; use rustc_span::source_map::Spanned; use rustc_span::{sym, Span, DUMMY_SP}; use rustc_target::abi::{FieldIdx, FIRST_VARIANT}; diff --git a/compiler/rustc_mir_build/src/thir/cx/mod.rs b/compiler/rustc_mir_build/src/thir/cx/mod.rs index 79738b5403548..d1d21f88aef6a 100644 --- a/compiler/rustc_mir_build/src/thir/cx/mod.rs +++ b/compiler/rustc_mir_build/src/thir/cx/mod.rs @@ -13,6 +13,7 @@ use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::lang_items::LangItem; use rustc_hir::HirId; use rustc_hir::Node; +use rustc_middle::bug; use rustc_middle::middle::region; use rustc_middle::thir::*; use rustc_middle::ty::{self, RvalueScopes, TyCtxt}; diff --git a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs index 25ab904670618..592f0dcf4ef55 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs @@ -1,9 +1,3 @@ -use rustc_pattern_analysis::errors::Uncovered; -use rustc_pattern_analysis::rustc::{ - Constructor, DeconstructedPat, MatchArm, RustcPatCtxt as PatCtxt, Usefulness, UsefulnessReport, - WitnessPat, -}; - use crate::errors::*; use rustc_arena::{DroplessArena, TypedArena}; @@ -14,11 +8,17 @@ use rustc_errors::{codes::*, struct_span_code_err, Applicability, ErrorGuarantee use rustc_hir::def::*; use rustc_hir::def_id::LocalDefId; use rustc_hir::{self as hir, BindingMode, ByRef, HirId}; +use rustc_middle::bug; use rustc_middle::middle::limits::get_limit_size; use rustc_middle::thir::visit::Visitor; use rustc_middle::thir::*; use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::{self, AdtDef, Ty, TyCtxt}; +use rustc_pattern_analysis::errors::Uncovered; +use rustc_pattern_analysis::rustc::{ + Constructor, DeconstructedPat, MatchArm, RustcPatCtxt as PatCtxt, Usefulness, UsefulnessReport, + WitnessPat, +}; use rustc_session::lint::builtin::{ BINDINGS_WITH_VARIANT_NAME, IRREFUTABLE_LET_PATTERNS, UNREACHABLE_PATTERNS, }; diff --git a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs index 65c53be8ddd9a..c6f81c3cb9976 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs @@ -4,6 +4,7 @@ use rustc_index::Idx; use rustc_infer::infer::{InferCtxt, TyCtxtInferExt}; use rustc_infer::traits::Obligation; use rustc_middle::mir; +use rustc_middle::span_bug; use rustc_middle::thir::{FieldPat, Pat, PatKind}; use rustc_middle::ty::{self, Ty, TyCtxt, ValTree}; use rustc_session::lint; diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index 5c016682d8d2d..0fe29fbde0d15 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -20,6 +20,7 @@ use rustc_middle::thir::{ }; use rustc_middle::ty::layout::IntegerExt; use rustc_middle::ty::{self, CanonicalUserTypeAnnotation, Ty, TyCtxt, TypeVisitableExt}; +use rustc_middle::{bug, span_bug}; use rustc_span::def_id::LocalDefId; use rustc_span::{ErrorGuaranteed, Span}; use rustc_target::abi::{FieldIdx, Integer}; diff --git a/compiler/rustc_mir_build/src/thir/util.rs b/compiler/rustc_mir_build/src/thir/util.rs index 52c9cf14ac872..340eb3c2eea0f 100644 --- a/compiler/rustc_mir_build/src/thir/util.rs +++ b/compiler/rustc_mir_build/src/thir/util.rs @@ -1,4 +1,5 @@ use rustc_hir as hir; +use rustc_middle::bug; use rustc_middle::ty::{self, CanonicalUserType, TyCtxt, UserType}; pub(crate) trait UserAnnotatedTyHelpers<'tcx> { From d49d4ae192d4e5dd3504de320d4ec116a672f437 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 8 May 2024 19:46:29 +1000 Subject: [PATCH 142/179] Remove `extern crate rustc_middle` from `rustc_mir_transform`. --- compiler/rustc_mir_transform/src/abort_unwinding_calls.rs | 1 + compiler/rustc_mir_transform/src/check_packed_ref.rs | 1 + compiler/rustc_mir_transform/src/coroutine.rs | 1 + compiler/rustc_mir_transform/src/coroutine/by_move_body.rs | 1 + compiler/rustc_mir_transform/src/coverage/counters.rs | 1 + compiler/rustc_mir_transform/src/coverage/graph.rs | 1 + compiler/rustc_mir_transform/src/coverage/spans.rs | 1 + compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs | 1 + compiler/rustc_mir_transform/src/coverage/tests.rs | 1 + compiler/rustc_mir_transform/src/dataflow_const_prop.rs | 1 + compiler/rustc_mir_transform/src/dead_store_elimination.rs | 1 + compiler/rustc_mir_transform/src/dest_prop.rs | 1 + compiler/rustc_mir_transform/src/elaborate_box_derefs.rs | 1 + compiler/rustc_mir_transform/src/ffi_unwind_calls.rs | 1 + compiler/rustc_mir_transform/src/gvn.rs | 1 + compiler/rustc_mir_transform/src/inline.rs | 1 + compiler/rustc_mir_transform/src/instsimplify.rs | 1 + compiler/rustc_mir_transform/src/jump_threading.rs | 1 + compiler/rustc_mir_transform/src/known_panics_lint.rs | 1 + compiler/rustc_mir_transform/src/lib.rs | 3 +-- compiler/rustc_mir_transform/src/lower_intrinsics.rs | 1 + compiler/rustc_mir_transform/src/nrvo.rs | 1 + compiler/rustc_mir_transform/src/promote_consts.rs | 1 + compiler/rustc_mir_transform/src/ref_prop.rs | 1 + compiler/rustc_mir_transform/src/shim.rs | 1 + compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs | 1 + .../rustc_mir_transform/src/simplify_comparison_integral.rs | 1 + compiler/rustc_mir_transform/src/sroa.rs | 1 + compiler/rustc_mir_transform/src/ssa.rs | 1 + compiler/rustc_mir_transform/src/unreachable_enum_branching.rs | 1 + compiler/rustc_mir_transform/src/unreachable_prop.rs | 1 + 31 files changed, 31 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_mir_transform/src/abort_unwinding_calls.rs b/compiler/rustc_mir_transform/src/abort_unwinding_calls.rs index ba70a4453d659..d43fca3dc7efe 100644 --- a/compiler/rustc_mir_transform/src/abort_unwinding_calls.rs +++ b/compiler/rustc_mir_transform/src/abort_unwinding_calls.rs @@ -1,5 +1,6 @@ use rustc_ast::InlineAsmOptions; use rustc_middle::mir::*; +use rustc_middle::span_bug; use rustc_middle::ty::layout; use rustc_middle::ty::{self, TyCtxt}; use rustc_target::spec::abi::Abi; diff --git a/compiler/rustc_mir_transform/src/check_packed_ref.rs b/compiler/rustc_mir_transform/src/check_packed_ref.rs index a405ed6088d82..5f67bd75c48a2 100644 --- a/compiler/rustc_mir_transform/src/check_packed_ref.rs +++ b/compiler/rustc_mir_transform/src/check_packed_ref.rs @@ -1,5 +1,6 @@ use rustc_middle::mir::visit::{PlaceContext, Visitor}; use rustc_middle::mir::*; +use rustc_middle::span_bug; use rustc_middle::ty::{self, TyCtxt}; use crate::MirLint; diff --git a/compiler/rustc_mir_transform/src/coroutine.rs b/compiler/rustc_mir_transform/src/coroutine.rs index 3008016863e4c..a3e6e5a5a915c 100644 --- a/compiler/rustc_mir_transform/src/coroutine.rs +++ b/compiler/rustc_mir_transform/src/coroutine.rs @@ -70,6 +70,7 @@ use rustc_middle::mir::*; use rustc_middle::ty::CoroutineArgs; use rustc_middle::ty::InstanceDef; use rustc_middle::ty::{self, Ty, TyCtxt}; +use rustc_middle::{bug, span_bug}; use rustc_mir_dataflow::impls::{ MaybeBorrowedLocals, MaybeLiveLocals, MaybeRequiresStorage, MaybeStorageLive, }; diff --git a/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs b/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs index 3d6c1a952041c..10c0567eb4b7b 100644 --- a/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs +++ b/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs @@ -71,6 +71,7 @@ use rustc_data_structures::unord::UnordMap; use rustc_hir as hir; +use rustc_middle::bug; use rustc_middle::hir::place::{Projection, ProjectionKind}; use rustc_middle::mir::visit::MutVisitor; use rustc_middle::mir::{self, dump_mir, MirPass}; diff --git a/compiler/rustc_mir_transform/src/coverage/counters.rs b/compiler/rustc_mir_transform/src/coverage/counters.rs index 6e73a476421f2..b98554ec00fa2 100644 --- a/compiler/rustc_mir_transform/src/coverage/counters.rs +++ b/compiler/rustc_mir_transform/src/coverage/counters.rs @@ -4,6 +4,7 @@ use rustc_data_structures::captures::Captures; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::graph::DirectedGraph; use rustc_index::IndexVec; +use rustc_middle::bug; use rustc_middle::mir::coverage::{CounterId, CovTerm, Expression, ExpressionId, Op}; use crate::coverage::graph::{BasicCoverageBlock, CoverageGraph, TraverseCoverageGraphWithLoops}; diff --git a/compiler/rustc_mir_transform/src/coverage/graph.rs b/compiler/rustc_mir_transform/src/coverage/graph.rs index 1895735ab3523..fd74a2a97e2c2 100644 --- a/compiler/rustc_mir_transform/src/coverage/graph.rs +++ b/compiler/rustc_mir_transform/src/coverage/graph.rs @@ -4,6 +4,7 @@ use rustc_data_structures::graph::dominators::{self, Dominators}; use rustc_data_structures::graph::{self, DirectedGraph, StartNode}; use rustc_index::bit_set::BitSet; use rustc_index::IndexVec; +use rustc_middle::bug; use rustc_middle::mir::{self, BasicBlock, Terminator, TerminatorKind}; use std::cmp::Ordering; diff --git a/compiler/rustc_mir_transform/src/coverage/spans.rs b/compiler/rustc_mir_transform/src/coverage/spans.rs index a0570c45f9630..f2f76ac70c20d 100644 --- a/compiler/rustc_mir_transform/src/coverage/spans.rs +++ b/compiler/rustc_mir_transform/src/coverage/spans.rs @@ -1,3 +1,4 @@ +use rustc_middle::bug; use rustc_middle::mir; use rustc_span::{BytePos, Span}; diff --git a/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs b/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs index 4ce37b5defcee..d1727a94a35e3 100644 --- a/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs +++ b/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs @@ -1,5 +1,6 @@ use rustc_data_structures::captures::Captures; use rustc_data_structures::fx::FxHashSet; +use rustc_middle::bug; use rustc_middle::mir::coverage::CoverageKind; use rustc_middle::mir::{ self, AggregateKind, FakeReadCause, Rvalue, Statement, StatementKind, Terminator, diff --git a/compiler/rustc_mir_transform/src/coverage/tests.rs b/compiler/rustc_mir_transform/src/coverage/tests.rs index cf1a2b399f951..ca64688e6b87b 100644 --- a/compiler/rustc_mir_transform/src/coverage/tests.rs +++ b/compiler/rustc_mir_transform/src/coverage/tests.rs @@ -30,6 +30,7 @@ use super::graph::{self, BasicCoverageBlock}; use itertools::Itertools; use rustc_data_structures::graph::{DirectedGraph, Successors}; use rustc_index::{Idx, IndexVec}; +use rustc_middle::bug; use rustc_middle::mir::*; use rustc_middle::ty; use rustc_span::{BytePos, Pos, Span, DUMMY_SP}; diff --git a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs index 3019b275fb260..a42d64f86be18 100644 --- a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs +++ b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs @@ -6,6 +6,7 @@ use rustc_const_eval::const_eval::{throw_machine_stop_str, DummyMachine}; use rustc_const_eval::interpret::{ImmTy, Immediate, InterpCx, OpTy, PlaceTy, Projectable}; use rustc_data_structures::fx::FxHashMap; use rustc_hir::def::DefKind; +use rustc_middle::bug; use rustc_middle::mir::interpret::{InterpResult, Scalar}; use rustc_middle::mir::visit::{MutVisitor, PlaceContext, Visitor}; use rustc_middle::mir::*; diff --git a/compiler/rustc_mir_transform/src/dead_store_elimination.rs b/compiler/rustc_mir_transform/src/dead_store_elimination.rs index e6317e5469ce8..08dba1de500cf 100644 --- a/compiler/rustc_mir_transform/src/dead_store_elimination.rs +++ b/compiler/rustc_mir_transform/src/dead_store_elimination.rs @@ -13,6 +13,7 @@ //! use crate::util::is_within_packed; +use rustc_middle::bug; use rustc_middle::mir::visit::Visitor; use rustc_middle::mir::*; use rustc_middle::ty::TyCtxt; diff --git a/compiler/rustc_mir_transform/src/dest_prop.rs b/compiler/rustc_mir_transform/src/dest_prop.rs index 10fea09531a65..1bc383fccc72b 100644 --- a/compiler/rustc_mir_transform/src/dest_prop.rs +++ b/compiler/rustc_mir_transform/src/dest_prop.rs @@ -135,6 +135,7 @@ use crate::MirPass; use rustc_data_structures::fx::{FxIndexMap, IndexEntry, IndexOccupiedEntry}; use rustc_index::bit_set::BitSet; use rustc_index::interval::SparseIntervalMatrix; +use rustc_middle::bug; use rustc_middle::mir::visit::{MutVisitor, PlaceContext, Visitor}; use rustc_middle::mir::HasLocalDecls; use rustc_middle::mir::{dump_mir, PassWhere}; diff --git a/compiler/rustc_mir_transform/src/elaborate_box_derefs.rs b/compiler/rustc_mir_transform/src/elaborate_box_derefs.rs index 318674f24e7ab..d955b96d06af0 100644 --- a/compiler/rustc_mir_transform/src/elaborate_box_derefs.rs +++ b/compiler/rustc_mir_transform/src/elaborate_box_derefs.rs @@ -6,6 +6,7 @@ use rustc_hir::def_id::DefId; use rustc_middle::mir::patch::MirPatch; use rustc_middle::mir::visit::MutVisitor; use rustc_middle::mir::*; +use rustc_middle::span_bug; use rustc_middle::ty::{Ty, TyCtxt}; use rustc_target::abi::FieldIdx; diff --git a/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs b/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs index 0970c4de19fde..5e3cd85367508 100644 --- a/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs +++ b/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs @@ -4,6 +4,7 @@ use rustc_middle::query::LocalCrate; use rustc_middle::query::Providers; use rustc_middle::ty::layout; use rustc_middle::ty::{self, TyCtxt}; +use rustc_middle::{bug, span_bug}; use rustc_session::lint::builtin::FFI_UNWIND_CALLS; use rustc_target::spec::abi::Abi; use rustc_target::spec::PanicStrategy; diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs index 342d1a1cd5bb0..123166a764d8d 100644 --- a/compiler/rustc_mir_transform/src/gvn.rs +++ b/compiler/rustc_mir_transform/src/gvn.rs @@ -91,6 +91,7 @@ use rustc_hir::def::DefKind; use rustc_index::bit_set::BitSet; use rustc_index::newtype_index; use rustc_index::IndexVec; +use rustc_middle::bug; use rustc_middle::mir::interpret::GlobalAlloc; use rustc_middle::mir::visit::*; use rustc_middle::mir::*; diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs index 7a3b08f82f619..401056cd49603 100644 --- a/compiler/rustc_mir_transform/src/inline.rs +++ b/compiler/rustc_mir_transform/src/inline.rs @@ -6,6 +6,7 @@ use rustc_hir::def::DefKind; use rustc_hir::def_id::DefId; use rustc_index::bit_set::BitSet; use rustc_index::Idx; +use rustc_middle::bug; use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs}; use rustc_middle::mir::visit::*; use rustc_middle::mir::*; diff --git a/compiler/rustc_mir_transform/src/instsimplify.rs b/compiler/rustc_mir_transform/src/instsimplify.rs index fd768cc96ae3a..f1adeab3f8849 100644 --- a/compiler/rustc_mir_transform/src/instsimplify.rs +++ b/compiler/rustc_mir_transform/src/instsimplify.rs @@ -2,6 +2,7 @@ use crate::simplify::simplify_duplicate_switch_targets; use rustc_ast::attr; +use rustc_middle::bug; use rustc_middle::mir::*; use rustc_middle::ty::layout; use rustc_middle::ty::layout::ValidityRequirement; diff --git a/compiler/rustc_mir_transform/src/jump_threading.rs b/compiler/rustc_mir_transform/src/jump_threading.rs index a458297210db8..ae807655b68d6 100644 --- a/compiler/rustc_mir_transform/src/jump_threading.rs +++ b/compiler/rustc_mir_transform/src/jump_threading.rs @@ -41,6 +41,7 @@ use rustc_const_eval::interpret::{ImmTy, Immediate, InterpCx, OpTy, Projectable} use rustc_data_structures::fx::FxHashSet; use rustc_index::bit_set::BitSet; use rustc_index::IndexVec; +use rustc_middle::bug; use rustc_middle::mir::interpret::Scalar; use rustc_middle::mir::visit::Visitor; use rustc_middle::mir::*; diff --git a/compiler/rustc_mir_transform/src/known_panics_lint.rs b/compiler/rustc_mir_transform/src/known_panics_lint.rs index 90c1c7ba63b45..d0a5a6cada8fa 100644 --- a/compiler/rustc_mir_transform/src/known_panics_lint.rs +++ b/compiler/rustc_mir_transform/src/known_panics_lint.rs @@ -14,6 +14,7 @@ use rustc_data_structures::fx::FxHashSet; use rustc_hir::def::DefKind; use rustc_hir::HirId; use rustc_index::{bit_set::BitSet, IndexVec}; +use rustc_middle::bug; use rustc_middle::mir::visit::{MutatingUseContext, NonMutatingUseContext, PlaceContext, Visitor}; use rustc_middle::mir::*; use rustc_middle::ty::layout::{LayoutError, LayoutOf, LayoutOfHelpers, TyAndLayout}; diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index e69c5da757ed4..9af48f0bad25c 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -16,8 +16,6 @@ #[macro_use] extern crate tracing; -#[macro_use] -extern crate rustc_middle; use hir::ConstContext; use required_consts::RequiredConstsVisitor; @@ -38,6 +36,7 @@ use rustc_middle::mir::{ use rustc_middle::query; use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt}; use rustc_middle::util::Providers; +use rustc_middle::{bug, span_bug}; use rustc_span::{source_map::Spanned, sym, DUMMY_SP}; use rustc_trait_selection::traits; diff --git a/compiler/rustc_mir_transform/src/lower_intrinsics.rs b/compiler/rustc_mir_transform/src/lower_intrinsics.rs index da63fcf23d9ee..43d8c45bb2dd9 100644 --- a/compiler/rustc_mir_transform/src/lower_intrinsics.rs +++ b/compiler/rustc_mir_transform/src/lower_intrinsics.rs @@ -2,6 +2,7 @@ use rustc_middle::mir::*; use rustc_middle::ty::{self, TyCtxt}; +use rustc_middle::{bug, span_bug}; use rustc_span::symbol::sym; pub struct LowerIntrinsics; diff --git a/compiler/rustc_mir_transform/src/nrvo.rs b/compiler/rustc_mir_transform/src/nrvo.rs index 232c290e0fb21..885dbd5f33934 100644 --- a/compiler/rustc_mir_transform/src/nrvo.rs +++ b/compiler/rustc_mir_transform/src/nrvo.rs @@ -2,6 +2,7 @@ use rustc_hir::Mutability; use rustc_index::bit_set::BitSet; +use rustc_middle::bug; use rustc_middle::mir::visit::{MutVisitor, NonUseContext, PlaceContext, Visitor}; use rustc_middle::mir::{self, BasicBlock, Local, Location}; use rustc_middle::ty::TyCtxt; diff --git a/compiler/rustc_mir_transform/src/promote_consts.rs b/compiler/rustc_mir_transform/src/promote_consts.rs index 689a547689a2d..b3116c002d3ce 100644 --- a/compiler/rustc_mir_transform/src/promote_consts.rs +++ b/compiler/rustc_mir_transform/src/promote_consts.rs @@ -20,6 +20,7 @@ use rustc_middle::mir::visit::{MutVisitor, MutatingUseContext, PlaceContext, Vis use rustc_middle::mir::*; use rustc_middle::ty::GenericArgs; use rustc_middle::ty::{self, List, Ty, TyCtxt, TypeVisitableExt}; +use rustc_middle::{bug, span_bug}; use rustc_span::Span; use rustc_index::{Idx, IndexSlice, IndexVec}; diff --git a/compiler/rustc_mir_transform/src/ref_prop.rs b/compiler/rustc_mir_transform/src/ref_prop.rs index 044ae32c1d40f..801ef14c9cd90 100644 --- a/compiler/rustc_mir_transform/src/ref_prop.rs +++ b/compiler/rustc_mir_transform/src/ref_prop.rs @@ -1,6 +1,7 @@ use rustc_data_structures::fx::FxHashSet; use rustc_index::bit_set::BitSet; use rustc_index::IndexVec; +use rustc_middle::bug; use rustc_middle::mir::visit::*; use rustc_middle::mir::*; use rustc_middle::ty::TyCtxt; diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs index 1c85a604053c7..cd8a43d6e6c26 100644 --- a/compiler/rustc_mir_transform/src/shim.rs +++ b/compiler/rustc_mir_transform/src/shim.rs @@ -5,6 +5,7 @@ use rustc_middle::mir::*; use rustc_middle::query::Providers; use rustc_middle::ty::GenericArgs; use rustc_middle::ty::{self, CoroutineArgs, EarlyBinder, Ty, TyCtxt}; +use rustc_middle::{bug, span_bug}; use rustc_target::abi::{FieldIdx, VariantIdx, FIRST_VARIANT}; use rustc_index::{Idx, IndexVec}; diff --git a/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs b/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs index 80eadb9abdcf4..0d023c626836b 100644 --- a/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs +++ b/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs @@ -14,6 +14,7 @@ use rustc_middle::mir::{ use rustc_middle::ty::adjustment::PointerCoercion; use rustc_middle::ty::util::Discr; use rustc_middle::ty::{self, Ty, TyCtxt}; +use rustc_middle::{bug, span_bug}; use rustc_span::source_map::respan; use rustc_span::{Span, Symbol}; use rustc_target::abi::{FieldIdx, VariantIdx}; diff --git a/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs b/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs index 1a8cfc411784f..03907babf2b0f 100644 --- a/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs +++ b/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs @@ -2,6 +2,7 @@ use std::iter; use super::MirPass; use rustc_middle::{ + bug, mir::{ interpret::Scalar, BasicBlock, BinOp, Body, Operand, Place, Rvalue, Statement, StatementKind, SwitchTargets, TerminatorKind, diff --git a/compiler/rustc_mir_transform/src/sroa.rs b/compiler/rustc_mir_transform/src/sroa.rs index 06d5e17fdd6c6..cdf3305b56096 100644 --- a/compiler/rustc_mir_transform/src/sroa.rs +++ b/compiler/rustc_mir_transform/src/sroa.rs @@ -1,6 +1,7 @@ use rustc_data_structures::flat_map_in_place::FlatMapInPlace; use rustc_index::bit_set::{BitSet, GrowableBitSet}; use rustc_index::IndexVec; +use rustc_middle::bug; use rustc_middle::mir::patch::MirPatch; use rustc_middle::mir::visit::*; use rustc_middle::mir::*; diff --git a/compiler/rustc_mir_transform/src/ssa.rs b/compiler/rustc_mir_transform/src/ssa.rs index 55fed7d9da28d..fb870425f6ef8 100644 --- a/compiler/rustc_mir_transform/src/ssa.rs +++ b/compiler/rustc_mir_transform/src/ssa.rs @@ -9,6 +9,7 @@ use rustc_data_structures::graph::dominators::Dominators; use rustc_index::bit_set::BitSet; use rustc_index::{IndexSlice, IndexVec}; +use rustc_middle::bug; use rustc_middle::middle::resolve_bound_vars::Set1; use rustc_middle::mir::visit::*; use rustc_middle::mir::*; diff --git a/compiler/rustc_mir_transform/src/unreachable_enum_branching.rs b/compiler/rustc_mir_transform/src/unreachable_enum_branching.rs index 66b6235eb9380..1404a45f4d2db 100644 --- a/compiler/rustc_mir_transform/src/unreachable_enum_branching.rs +++ b/compiler/rustc_mir_transform/src/unreachable_enum_branching.rs @@ -2,6 +2,7 @@ use crate::MirPass; use rustc_data_structures::fx::FxHashSet; +use rustc_middle::bug; use rustc_middle::mir::patch::MirPatch; use rustc_middle::mir::{ BasicBlock, BasicBlockData, BasicBlocks, Body, Local, Operand, Rvalue, StatementKind, diff --git a/compiler/rustc_mir_transform/src/unreachable_prop.rs b/compiler/rustc_mir_transform/src/unreachable_prop.rs index 8ad7bc394c5ae..a6c3c3b189ed0 100644 --- a/compiler/rustc_mir_transform/src/unreachable_prop.rs +++ b/compiler/rustc_mir_transform/src/unreachable_prop.rs @@ -3,6 +3,7 @@ //! post-order traversal of the blocks. use rustc_data_structures::fx::FxHashSet; +use rustc_middle::bug; use rustc_middle::mir::interpret::Scalar; use rustc_middle::mir::patch::MirPatch; use rustc_middle::mir::*; From 573aa9f677b8f6cd9efd0da41a9bed282e4bcba0 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 8 May 2024 20:25:42 +1000 Subject: [PATCH 143/179] Remove `extern crate rustc_middle` from `rustc_query_impl`. --- compiler/rustc_query_impl/src/lib.rs | 5 +---- compiler/rustc_query_impl/src/plumbing.rs | 5 +++-- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_query_impl/src/lib.rs b/compiler/rustc_query_impl/src/lib.rs index 914481d712e8e..85f55553af39f 100644 --- a/compiler/rustc_query_impl/src/lib.rs +++ b/compiler/rustc_query_impl/src/lib.rs @@ -8,9 +8,6 @@ #![allow(rustc::potential_query_instability, unused_parens)] #![allow(internal_features)] -#[macro_use] -extern crate rustc_middle; - use crate::plumbing::{__rust_begin_short_backtrace, encode_all_query_results, try_mark_green}; use crate::profiling_support::QueryKeyStringCache; use field_offset::offset_of; @@ -222,4 +219,4 @@ pub fn query_system<'tcx>( } } -rustc_query_append! { define_queries! } +rustc_middle::rustc_query_append! { define_queries! } diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs index a7696b1fbaff4..86531bd95900a 100644 --- a/compiler/rustc_query_impl/src/plumbing.rs +++ b/compiler/rustc_query_impl/src/plumbing.rs @@ -7,8 +7,8 @@ use rustc_data_structures::stable_hasher::{Hash64, HashStable, StableHasher}; use rustc_data_structures::sync::Lock; use rustc_data_structures::unord::UnordMap; use rustc_errors::DiagInner; - use rustc_index::Idx; +use rustc_middle::bug; use rustc_middle::dep_graph::dep_kinds; use rustc_middle::dep_graph::{ self, DepContext, DepKind, DepKindStruct, DepNode, DepNodeIndex, SerializedDepNodeIndex, @@ -781,6 +781,7 @@ macro_rules! define_queries { #[allow(nonstandard_style)] mod query_callbacks { use super::*; + use rustc_middle::bug; use rustc_query_system::dep_graph::FingerprintStyle; // We use this for most things when incr. comp. is turned off. @@ -849,7 +850,7 @@ macro_rules! define_queries { } pub fn query_callbacks<'tcx>(arena: &'tcx Arena<'tcx>) -> &'tcx [DepKindStruct<'tcx>] { - arena.alloc_from_iter(make_dep_kind_array!(query_callbacks)) + arena.alloc_from_iter(rustc_middle::make_dep_kind_array!(query_callbacks)) } } } From 4bf20b2b558289e9dcffd496890df116f98612c7 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 9 May 2024 08:06:59 +1000 Subject: [PATCH 144/179] Remove `extern crate rustc_middle` from `rustc_trait_selection`. --- compiler/rustc_trait_selection/src/lib.rs | 2 -- compiler/rustc_trait_selection/src/solve/assembly/mod.rs | 1 + .../src/solve/assembly/structural_traits.rs | 1 + compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs | 1 + compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs | 1 + compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs | 1 + compiler/rustc_trait_selection/src/solve/fulfill.rs | 1 + compiler/rustc_trait_selection/src/solve/inspect/build.rs | 1 + compiler/rustc_trait_selection/src/solve/mod.rs | 1 + compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs | 1 + compiler/rustc_trait_selection/src/solve/trait_goals.rs | 1 + compiler/rustc_trait_selection/src/traits/coherence.rs | 1 + compiler/rustc_trait_selection/src/traits/const_evaluatable.rs | 1 + .../src/traits/error_reporting/on_unimplemented.rs | 1 + .../src/traits/error_reporting/suggestions.rs | 1 + .../src/traits/error_reporting/type_err_ctxt_ext.rs | 1 + compiler/rustc_trait_selection/src/traits/fulfill.rs | 1 + compiler/rustc_trait_selection/src/traits/mod.rs | 1 + compiler/rustc_trait_selection/src/traits/outlives_bounds.rs | 1 + compiler/rustc_trait_selection/src/traits/project.rs | 1 + .../src/traits/query/evaluate_obligation.rs | 1 + .../src/traits/select/candidate_assembly.rs | 1 + .../rustc_trait_selection/src/traits/select/confirmation.rs | 1 + compiler/rustc_trait_selection/src/traits/select/mod.rs | 1 + compiler/rustc_trait_selection/src/traits/specialize/mod.rs | 1 + .../src/traits/specialize/specialization_graph.rs | 1 + compiler/rustc_trait_selection/src/traits/structural_match.rs | 1 + compiler/rustc_trait_selection/src/traits/util.rs | 1 + compiler/rustc_trait_selection/src/traits/vtable.rs | 1 + compiler/rustc_trait_selection/src/traits/wf.rs | 1 + 30 files changed, 29 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_trait_selection/src/lib.rs b/compiler/rustc_trait_selection/src/lib.rs index f1f03b810a961..521e4ef0c9edf 100644 --- a/compiler/rustc_trait_selection/src/lib.rs +++ b/compiler/rustc_trait_selection/src/lib.rs @@ -30,8 +30,6 @@ #[macro_use] extern crate tracing; -#[macro_use] -extern crate rustc_middle; pub mod errors; pub mod infer; diff --git a/compiler/rustc_trait_selection/src/solve/assembly/mod.rs b/compiler/rustc_trait_selection/src/solve/assembly/mod.rs index 938bd80b9eb0a..9a027d7f937ec 100644 --- a/compiler/rustc_trait_selection/src/solve/assembly/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/assembly/mod.rs @@ -4,6 +4,7 @@ use crate::solve::GoalSource; use crate::solve::{inspect, EvalCtxt, SolverMode}; use rustc_hir::def_id::DefId; use rustc_infer::traits::query::NoSolution; +use rustc_middle::bug; use rustc_middle::traits::solve::inspect::ProbeKind; use rustc_middle::traits::solve::{ CandidateSource, CanonicalResponse, Certainty, Goal, MaybeCause, QueryResult, diff --git a/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs b/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs index eeaef028cdb4d..f1115c3504eba 100644 --- a/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs +++ b/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs @@ -5,6 +5,7 @@ use rustc_hir::LangItem; use rustc_hir::{def_id::DefId, Movability, Mutability}; use rustc_infer::traits::query::NoSolution; use rustc_macros::{TypeFoldable, TypeVisitable}; +use rustc_middle::bug; use rustc_middle::traits::solve::Goal; use rustc_middle::ty::{ self, ToPredicate, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs index d5176dc321c08..2058650f288f9 100644 --- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs +++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs @@ -22,6 +22,7 @@ use rustc_infer::infer::resolve::EagerResolver; use rustc_infer::infer::RegionVariableOrigin; use rustc_infer::infer::{InferCtxt, InferOk}; use rustc_infer::traits::solve::NestedNormalizationGoals; +use rustc_middle::bug; use rustc_middle::infer::canonical::Canonical; use rustc_middle::traits::query::NoSolution; use rustc_middle::traits::solve::{ diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs index 8614c17cabf1d..144197b0bec61 100644 --- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs @@ -9,6 +9,7 @@ use rustc_infer::traits::query::NoSolution; use rustc_infer::traits::solve::{MaybeCause, NestedNormalizationGoals}; use rustc_infer::traits::ObligationCause; use rustc_macros::{extension, HashStable}; +use rustc_middle::bug; use rustc_middle::infer::canonical::CanonicalVarInfos; use rustc_middle::traits::solve::inspect; use rustc_middle::traits::solve::{ diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs index 7efc951135b79..6fda5f4af25e7 100644 --- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs +++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs @@ -8,6 +8,7 @@ use rustc_infer::traits::{ PolyTraitObligation, Selection, SelectionError, SelectionResult, }; use rustc_macros::extension; +use rustc_middle::{bug, span_bug}; use rustc_span::Span; use crate::solve::inspect::{self, ProofTreeInferCtxtExt}; diff --git a/compiler/rustc_trait_selection/src/solve/fulfill.rs b/compiler/rustc_trait_selection/src/solve/fulfill.rs index 586d2095d9c0e..3323f1bbf399b 100644 --- a/compiler/rustc_trait_selection/src/solve/fulfill.rs +++ b/compiler/rustc_trait_selection/src/solve/fulfill.rs @@ -9,6 +9,7 @@ use rustc_infer::traits::{ self, FulfillmentError, FulfillmentErrorCode, MismatchedProjectionTypes, Obligation, ObligationCause, ObligationCauseCode, PredicateObligation, SelectionError, TraitEngine, }; +use rustc_middle::bug; use rustc_middle::ty::error::{ExpectedFound, TypeError}; use rustc_middle::ty::{self, TyCtxt}; use rustc_span::symbol::sym; diff --git a/compiler/rustc_trait_selection/src/solve/inspect/build.rs b/compiler/rustc_trait_selection/src/solve/inspect/build.rs index 3c5505055a443..9dd681f09e76e 100644 --- a/compiler/rustc_trait_selection/src/solve/inspect/build.rs +++ b/compiler/rustc_trait_selection/src/solve/inspect/build.rs @@ -6,6 +6,7 @@ use std::mem; use rustc_infer::infer::InferCtxt; +use rustc_middle::bug; use rustc_middle::infer::canonical::CanonicalVarValues; use rustc_middle::traits::query::NoSolution; use rustc_middle::traits::solve::{ diff --git a/compiler/rustc_trait_selection/src/solve/mod.rs b/compiler/rustc_trait_selection/src/solve/mod.rs index 80ae4b6022dcf..6c912db975a06 100644 --- a/compiler/rustc_trait_selection/src/solve/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/mod.rs @@ -17,6 +17,7 @@ use rustc_hir::def_id::DefId; use rustc_infer::infer::canonical::{Canonical, CanonicalVarValues}; use rustc_infer::traits::query::NoSolution; use rustc_macros::extension; +use rustc_middle::bug; use rustc_middle::infer::canonical::CanonicalVarInfos; use rustc_middle::traits::solve::{ CanonicalResponse, Certainty, ExternalConstraintsData, Goal, GoalSource, QueryResult, Response, diff --git a/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs b/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs index 8d5c5d2a06380..906cf14975002 100644 --- a/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs @@ -17,6 +17,7 @@ use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams}; use rustc_middle::ty::NormalizesTo; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_middle::ty::{ToPredicate, TypeVisitableExt}; +use rustc_middle::{bug, span_bug}; use rustc_span::{sym, ErrorGuaranteed, DUMMY_SP}; mod anon_const; diff --git a/compiler/rustc_trait_selection/src/solve/trait_goals.rs b/compiler/rustc_trait_selection/src/solve/trait_goals.rs index 2f1b7d60df310..1cafa970b68ee 100644 --- a/compiler/rustc_trait_selection/src/solve/trait_goals.rs +++ b/compiler/rustc_trait_selection/src/solve/trait_goals.rs @@ -10,6 +10,7 @@ use rustc_hir::def_id::DefId; use rustc_hir::{LangItem, Movability}; use rustc_infer::traits::query::NoSolution; use rustc_infer::traits::solve::MaybeCause; +use rustc_middle::bug; use rustc_middle::traits::solve::inspect::ProbeKind; use rustc_middle::traits::solve::{CandidateSource, Certainty, Goal, QueryResult}; use rustc_middle::traits::{BuiltinImplSource, Reveal}; diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index 59725ce9de096..2cc972cb98eb9 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -20,6 +20,7 @@ use rustc_hir::def::DefKind; use rustc_hir::def_id::DefId; use rustc_infer::infer::{DefineOpaqueTypes, InferCtxt, TyCtxtInferExt}; use rustc_infer::traits::{util, FulfillmentErrorCode}; +use rustc_middle::bug; use rustc_middle::traits::query::NoSolution; use rustc_middle::traits::solve::{CandidateSource, Certainty, Goal}; use rustc_middle::traits::specialization_graph::OverlapMode; diff --git a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs index a8be5627fed81..8348482386f7b 100644 --- a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs +++ b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs @@ -11,6 +11,7 @@ use rustc_hir::def::DefKind; use rustc_infer::infer::InferCtxt; +use rustc_middle::bug; use rustc_middle::mir::interpret::ErrorHandled; use rustc_middle::traits::ObligationCause; use rustc_middle::ty::abstract_const::NotConstEvaluatable; diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs index 040ce450aaf93..7fc94b31b3b55 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs @@ -10,6 +10,7 @@ use rustc_errors::{codes::*, struct_span_code_err, ErrorGuaranteed}; use rustc_hir as hir; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_macros::{extension, LintDiagnostic}; +use rustc_middle::bug; use rustc_middle::ty::print::PrintTraitRefExt as _; use rustc_middle::ty::GenericArgsRef; use rustc_middle::ty::{self, GenericParamDefKind, TyCtxt}; diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index ea1752a6e982c..f1088626f5b33 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -34,6 +34,7 @@ use rustc_middle::ty::{ InferTy, IsSuggestable, ToPredicate, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt, TypeckResults, }; +use rustc_middle::{bug, span_bug}; use rustc_span::def_id::LocalDefId; use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::{BytePos, DesugaringKind, ExpnKind, MacroKind, Span, DUMMY_SP}; diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs index 08ffe37b8b4d0..4092022d53184 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs @@ -45,6 +45,7 @@ use rustc_middle::ty::{ self, SubtypePredicate, ToPolyTraitRef, ToPredicate, TraitRef, Ty, TyCtxt, TypeFoldable, TypeVisitable, TypeVisitableExt, }; +use rustc_middle::{bug, span_bug}; use rustc_session::config::DumpSolverProofTree; use rustc_session::Limit; use rustc_span::def_id::LOCAL_CRATE; diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index e3497c646dbde..bb4067804aa80 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -8,6 +8,7 @@ use rustc_data_structures::obligation_forest::{ObligationForest, ObligationProce use rustc_infer::infer::DefineOpaqueTypes; use rustc_infer::traits::ProjectionCacheKey; use rustc_infer::traits::{PolyTraitObligation, SelectionError, TraitEngine}; +use rustc_middle::bug; use rustc_middle::mir::interpret::ErrorHandled; use rustc_middle::ty::abstract_const::NotConstEvaluatable; use rustc_middle::ty::error::{ExpectedFound, TypeError}; diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index 56f8b4b9cdb82..4b42496c2e295 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -31,6 +31,7 @@ use crate::traits::error_reporting::TypeErrCtxtExt as _; use crate::traits::query::evaluate_obligation::InferCtxtExt as _; use rustc_errors::ErrorGuaranteed; use rustc_middle::query::Providers; +use rustc_middle::span_bug; use rustc_middle::ty::fold::TypeFoldable; use rustc_middle::ty::visit::{TypeVisitable, TypeVisitableExt}; use rustc_middle::ty::{self, ToPredicate, Ty, TyCtxt, TypeFolder, TypeSuperVisitable}; diff --git a/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs b/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs index 1dd2ada3356f7..1dc2ebfaa7a30 100644 --- a/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs +++ b/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs @@ -5,6 +5,7 @@ use rustc_infer::infer::resolve::OpportunisticRegionResolver; use rustc_infer::infer::InferOk; use rustc_macros::extension; use rustc_middle::infer::canonical::{OriginalQueryValues, QueryRegionConstraints}; +use rustc_middle::span_bug; use rustc_middle::ty::{self, ParamEnv, Ty, TypeFolder, TypeVisitableExt}; use rustc_span::def_id::LocalDefId; diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index f092f42dacf9a..d2ffd13cba4d4 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -17,6 +17,7 @@ use rustc_infer::traits::ObligationCauseCode; use rustc_middle::traits::BuiltinImplSource; use rustc_middle::traits::ImplSource; use rustc_middle::traits::ImplSourceUserDefinedData; +use rustc_middle::{bug, span_bug}; use crate::errors::InherentProjectionNormalizationOverflow; use crate::infer::{BoundRegionConversionTime, InferOk}; diff --git a/compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs b/compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs index 87d240cf8ac75..692feee739511 100644 --- a/compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs +++ b/compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs @@ -1,4 +1,5 @@ use rustc_macros::extension; +use rustc_middle::span_bug; use crate::infer::canonical::OriginalQueryValues; use crate::infer::InferCtxt; diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index 40d206b92b8df..a0260324da0a0 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -16,6 +16,7 @@ use rustc_infer::traits::ObligationCause; use rustc_infer::traits::{Obligation, PolyTraitObligation, SelectionError}; use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams}; use rustc_middle::ty::{self, ToPolyTraitRef, Ty, TypeVisitableExt}; +use rustc_middle::{bug, span_bug}; use crate::traits; use crate::traits::query::evaluate_obligation::InferCtxtExt; diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index 69d11b45e6045..24c6951a014f6 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -17,6 +17,7 @@ use rustc_middle::ty::{ self, GenericArgs, GenericArgsRef, GenericParamDefKind, ToPolyTraitRef, ToPredicate, TraitPredicate, Ty, TyCtxt, }; +use rustc_middle::{bug, span_bug}; use rustc_span::def_id::DefId; use crate::traits::normalize::{normalize_with_depth, normalize_with_depth_to}; diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 7aa2aabed7f72..3cf47e0f98e1f 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -36,6 +36,7 @@ use rustc_infer::infer::BoundRegionConversionTime; use rustc_infer::infer::BoundRegionConversionTime::HigherRankedType; use rustc_infer::infer::DefineOpaqueTypes; use rustc_infer::traits::TraitObligation; +use rustc_middle::bug; use rustc_middle::dep_graph::dep_kinds; use rustc_middle::dep_graph::DepNodeIndex; use rustc_middle::mir::interpret::ErrorHandled; diff --git a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs index fe3f66f3a3ff2..826bb706f48b1 100644 --- a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs @@ -23,6 +23,7 @@ use crate::traits::{ use rustc_data_structures::fx::FxIndexSet; use rustc_errors::{codes::*, DelayDm, Diag, EmissionGuarantee}; use rustc_hir::def_id::{DefId, LocalDefId}; +use rustc_middle::bug; use rustc_middle::ty::{self, ImplSubject, Ty, TyCtxt, TypeVisitableExt}; use rustc_middle::ty::{GenericArgs, GenericArgsRef}; use rustc_session::lint::builtin::COHERENCE_LEAK_CHECK; diff --git a/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs b/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs index b6c2fcb46eb8a..90f2c7ad213b9 100644 --- a/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs +++ b/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs @@ -4,6 +4,7 @@ use crate::traits; use rustc_errors::ErrorGuaranteed; use rustc_hir::def_id::DefId; use rustc_macros::extension; +use rustc_middle::bug; use rustc_middle::ty::fast_reject::{self, SimplifiedType, TreatParams}; use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt}; diff --git a/compiler/rustc_trait_selection/src/traits/structural_match.rs b/compiler/rustc_trait_selection/src/traits/structural_match.rs index 6778ac81aeaea..d4535db951e25 100644 --- a/compiler/rustc_trait_selection/src/traits/structural_match.rs +++ b/compiler/rustc_trait_selection/src/traits/structural_match.rs @@ -1,5 +1,6 @@ use rustc_data_structures::fx::FxHashSet; use rustc_hir as hir; +use rustc_middle::bug; use rustc_middle::ty::{self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor}; use std::ops::ControlFlow; diff --git a/compiler/rustc_trait_selection/src/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs index b2ba7854f1888..83edddb9a9622 100644 --- a/compiler/rustc_trait_selection/src/traits/util.rs +++ b/compiler/rustc_trait_selection/src/traits/util.rs @@ -6,6 +6,7 @@ use rustc_data_structures::fx::{FxHashSet, FxIndexMap}; use rustc_errors::Diag; use rustc_hir::def_id::DefId; use rustc_infer::infer::{InferCtxt, InferOk}; +use rustc_middle::bug; use rustc_middle::ty::GenericArgsRef; use rustc_middle::ty::{self, ImplSubject, ToPredicate, Ty, TyCtxt, TypeVisitableExt}; use rustc_middle::ty::{TypeFoldable, TypeFolder, TypeSuperFoldable}; diff --git a/compiler/rustc_trait_selection/src/traits/vtable.rs b/compiler/rustc_trait_selection/src/traits/vtable.rs index 3f1ba80acd3d9..8fd9889b4eab7 100644 --- a/compiler/rustc_trait_selection/src/traits/vtable.rs +++ b/compiler/rustc_trait_selection/src/traits/vtable.rs @@ -4,6 +4,7 @@ use rustc_hir::def_id::DefId; use rustc_hir::lang_items::LangItem; use rustc_infer::traits::util::PredicateSet; use rustc_infer::traits::ImplSource; +use rustc_middle::bug; use rustc_middle::query::Providers; use rustc_middle::traits::BuiltinImplSource; use rustc_middle::ty::visit::TypeVisitableExt; diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index 562a82cc73d65..31eae3926ee45 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -3,6 +3,7 @@ use crate::traits; use rustc_hir as hir; use rustc_hir::lang_items::LangItem; use rustc_infer::traits::ObligationCauseCode; +use rustc_middle::bug; use rustc_middle::ty::{ self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, }; From c34ebba1348749233fdcdcea8cccd567eca3504b Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 8 May 2024 20:35:52 +1000 Subject: [PATCH 145/179] Remove `extern crate rustc_middle` from `rustc_ty_utils`. --- compiler/rustc_ty_utils/src/abi.rs | 1 + compiler/rustc_ty_utils/src/assoc.rs | 1 + compiler/rustc_ty_utils/src/consts.rs | 1 + compiler/rustc_ty_utils/src/implied_bounds.rs | 1 + compiler/rustc_ty_utils/src/instance.rs | 1 + compiler/rustc_ty_utils/src/layout.rs | 1 + compiler/rustc_ty_utils/src/layout_sanity_check.rs | 1 + compiler/rustc_ty_utils/src/lib.rs | 2 -- compiler/rustc_ty_utils/src/needs_drop.rs | 1 + compiler/rustc_ty_utils/src/opaque_types.rs | 1 + compiler/rustc_ty_utils/src/representability.rs | 1 + compiler/rustc_ty_utils/src/sig_types.rs | 1 + compiler/rustc_ty_utils/src/ty.rs | 1 + 13 files changed, 12 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_ty_utils/src/abi.rs b/compiler/rustc_ty_utils/src/abi.rs index c6b8362850663..fd7e2fec38927 100644 --- a/compiler/rustc_ty_utils/src/abi.rs +++ b/compiler/rustc_ty_utils/src/abi.rs @@ -1,5 +1,6 @@ use rustc_hir as hir; use rustc_hir::lang_items::LangItem; +use rustc_middle::bug; use rustc_middle::query::Providers; use rustc_middle::ty::layout::{ fn_can_unwind, FnAbiError, HasParamEnv, HasTyCtxt, LayoutCx, LayoutOf, TyAndLayout, diff --git a/compiler/rustc_ty_utils/src/assoc.rs b/compiler/rustc_ty_utils/src/assoc.rs index d3fe8291e03c3..4395eb57cd6d2 100644 --- a/compiler/rustc_ty_utils/src/assoc.rs +++ b/compiler/rustc_ty_utils/src/assoc.rs @@ -5,6 +5,7 @@ use rustc_hir::def_id::{DefId, DefIdMap, LocalDefId}; use rustc_hir::intravisit::{self, Visitor}; use rustc_middle::query::Providers; use rustc_middle::ty::{self, ImplTraitInTraitData, TyCtxt}; +use rustc_middle::{bug, span_bug}; use rustc_span::symbol::kw; pub(crate) fn provide(providers: &mut Providers) { diff --git a/compiler/rustc_ty_utils/src/consts.rs b/compiler/rustc_ty_utils/src/consts.rs index acbcc3918b2fb..fec02f515caf3 100644 --- a/compiler/rustc_ty_utils/src/consts.rs +++ b/compiler/rustc_ty_utils/src/consts.rs @@ -1,6 +1,7 @@ use rustc_errors::ErrorGuaranteed; use rustc_hir::def::DefKind; use rustc_hir::def_id::LocalDefId; +use rustc_middle::bug; use rustc_middle::mir::interpret::{LitToConstError, LitToConstInput}; use rustc_middle::query::Providers; use rustc_middle::thir::visit; diff --git a/compiler/rustc_ty_utils/src/implied_bounds.rs b/compiler/rustc_ty_utils/src/implied_bounds.rs index 862fb2e166394..e87058f9ba489 100644 --- a/compiler/rustc_ty_utils/src/implied_bounds.rs +++ b/compiler/rustc_ty_utils/src/implied_bounds.rs @@ -2,6 +2,7 @@ use rustc_data_structures::fx::FxHashMap; use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_hir::def_id::LocalDefId; +use rustc_middle::bug; use rustc_middle::query::Providers; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_span::Span; diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs index d0aa4eb2e714a..41f482d8a7068 100644 --- a/compiler/rustc_ty_utils/src/instance.rs +++ b/compiler/rustc_ty_utils/src/instance.rs @@ -1,6 +1,7 @@ use rustc_errors::ErrorGuaranteed; use rustc_hir::def_id::DefId; use rustc_infer::infer::TyCtxtInferExt; +use rustc_middle::bug; use rustc_middle::query::Providers; use rustc_middle::traits::{BuiltinImplSource, CodegenObligationError}; use rustc_middle::ty::GenericArgsRef; diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs index f78a28d16fdf5..1ef22497a8fc5 100644 --- a/compiler/rustc_ty_utils/src/layout.rs +++ b/compiler/rustc_ty_utils/src/layout.rs @@ -2,6 +2,7 @@ use hir::def_id::DefId; use rustc_hir as hir; use rustc_index::bit_set::BitSet; use rustc_index::{IndexSlice, IndexVec}; +use rustc_middle::bug; use rustc_middle::mir::{CoroutineLayout, CoroutineSavedLocal}; use rustc_middle::query::Providers; use rustc_middle::ty::layout::{ diff --git a/compiler/rustc_ty_utils/src/layout_sanity_check.rs b/compiler/rustc_ty_utils/src/layout_sanity_check.rs index 6332c614a90bb..ab7d1be226b3c 100644 --- a/compiler/rustc_ty_utils/src/layout_sanity_check.rs +++ b/compiler/rustc_ty_utils/src/layout_sanity_check.rs @@ -1,3 +1,4 @@ +use rustc_middle::bug; use rustc_middle::ty::{ layout::{LayoutCx, TyAndLayout}, TyCtxt, diff --git a/compiler/rustc_ty_utils/src/lib.rs b/compiler/rustc_ty_utils/src/lib.rs index fd392d11e8317..e8c5c54d3a09c 100644 --- a/compiler/rustc_ty_utils/src/lib.rs +++ b/compiler/rustc_ty_utils/src/lib.rs @@ -16,8 +16,6 @@ #![feature(let_chains)] #![feature(never_type)] -#[macro_use] -extern crate rustc_middle; #[macro_use] extern crate tracing; diff --git a/compiler/rustc_ty_utils/src/needs_drop.rs b/compiler/rustc_ty_utils/src/needs_drop.rs index ee930a78e77c7..4e23fb3038365 100644 --- a/compiler/rustc_ty_utils/src/needs_drop.rs +++ b/compiler/rustc_ty_utils/src/needs_drop.rs @@ -2,6 +2,7 @@ use rustc_data_structures::fx::FxHashSet; use rustc_hir::def_id::DefId; +use rustc_middle::bug; use rustc_middle::query::Providers; use rustc_middle::ty::util::{needs_drop_components, AlwaysRequiresDrop}; use rustc_middle::ty::GenericArgsRef; diff --git a/compiler/rustc_ty_utils/src/opaque_types.rs b/compiler/rustc_ty_utils/src/opaque_types.rs index d7d31a88c9b51..be227ec8b9aa1 100644 --- a/compiler/rustc_ty_utils/src/opaque_types.rs +++ b/compiler/rustc_ty_utils/src/opaque_types.rs @@ -2,6 +2,7 @@ use rustc_data_structures::fx::FxHashSet; use rustc_hir::intravisit::Visitor; use rustc_hir::{def::DefKind, def_id::LocalDefId}; use rustc_hir::{intravisit, CRATE_HIR_ID}; +use rustc_middle::bug; use rustc_middle::query::Providers; use rustc_middle::ty::util::{CheckRegions, NotUniqueParam}; use rustc_middle::ty::{self, Ty, TyCtxt}; diff --git a/compiler/rustc_ty_utils/src/representability.rs b/compiler/rustc_ty_utils/src/representability.rs index 446f16b412546..0ffb7f624965e 100644 --- a/compiler/rustc_ty_utils/src/representability.rs +++ b/compiler/rustc_ty_utils/src/representability.rs @@ -1,5 +1,6 @@ use rustc_hir::def::DefKind; use rustc_index::bit_set::BitSet; +use rustc_middle::bug; use rustc_middle::query::Providers; use rustc_middle::ty::{self, Representability, Ty, TyCtxt}; use rustc_span::def_id::LocalDefId; diff --git a/compiler/rustc_ty_utils/src/sig_types.rs b/compiler/rustc_ty_utils/src/sig_types.rs index 19c092c5ddf3f..2d8c78267d9fc 100644 --- a/compiler/rustc_ty_utils/src/sig_types.rs +++ b/compiler/rustc_ty_utils/src/sig_types.rs @@ -4,6 +4,7 @@ use rustc_ast_ir::try_visit; use rustc_ast_ir::visit::VisitorResult; use rustc_hir::{def::DefKind, def_id::LocalDefId}; +use rustc_middle::span_bug; use rustc_middle::ty::{self, TyCtxt}; use rustc_span::Span; use rustc_type_ir::visit::TypeVisitable; diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index fa1085c7cd79a..d98b46dfb9323 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -3,6 +3,7 @@ use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_hir::LangItem; use rustc_index::bit_set::BitSet; +use rustc_middle::bug; use rustc_middle::query::Providers; use rustc_middle::ty::{self, EarlyBinder, Ty, TyCtxt, TypeVisitableExt, TypeVisitor}; use rustc_middle::ty::{ToPredicate, TypeSuperVisitable, TypeVisitable}; From 5e7a80b2d2462060e81295ea6a044f7012bba8cb Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 13 May 2024 08:57:42 +1000 Subject: [PATCH 146/179] Make handling of `Comments` more iterator-like. The current way of stepping through each comment in `Comments` is a bit weird. There is a `Vec` and a `current` index, which is fine. The `Comments::next` method clones the current comment but doesn't advance `current`; the advancing instead happens in `print_comment`, which is where each cloned comment is actually finally used (or not, in some cases, if the comment fails to satisfy a predicate). This commit makes things more iterator-like: - `Comments::next` now advances `current` instead of `print_comment`. - `Comments::peek` is added so you can inspect a comment and check a predicate without consuming it. - This requires splitting `PrintState::comments` into immutable and mutable versions. The commit also moves the ref inside the `Option` of the return type, to save callers from having to use `as_ref`/`as_mut`. - It also requires adding `PrintState::peek_comment` alongside the existing `PrintState::next_comment`. (The lifetimes in the signature of `peek_comment` ended up more complex than I expected.) We now have a neat separation between consuming (`next`) and non-consuming (`peek`) uses of each comment. As well as being clearer, this will facilitate the next commit that avoids unnecessary cloning. --- compiler/rustc_ast_pretty/src/pprust/state.rs | 56 +++++++++++-------- compiler/rustc_hir_pretty/src/lib.rs | 8 ++- 2 files changed, 40 insertions(+), 24 deletions(-) diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index 2c176828c841f..9eb552cdcdfae 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -186,17 +186,23 @@ impl<'a> Comments<'a> { Comments { sm, comments, current: 0 } } + fn peek(&self) -> Option<&Comment> { + self.comments.get(self.current) + } + // FIXME: This shouldn't probably clone lmao - fn next(&self) -> Option { - self.comments.get(self.current).cloned() + fn next(&mut self) -> Option { + let cmnt = self.comments.get(self.current).cloned(); + self.current += 1; + cmnt } fn trailing_comment( - &self, + &mut self, span: rustc_span::Span, next_pos: Option, ) -> Option { - if let Some(cmnt) = self.next() { + if let Some(cmnt) = self.peek() { if cmnt.style != CommentStyle::Trailing { return None; } @@ -204,7 +210,7 @@ impl<'a> Comments<'a> { let comment_line = self.sm.lookup_char_pos(cmnt.pos); let next = next_pos.unwrap_or_else(|| cmnt.pos + BytePos(1)); if span.hi() < cmnt.pos && cmnt.pos < next && span_line.line == comment_line.line { - return Some(cmnt); + return Some(self.next().unwrap()); } } @@ -400,7 +406,8 @@ impl std::ops::DerefMut for State<'_> { /// This trait is used for both AST and HIR pretty-printing. pub trait PrintState<'a>: std::ops::Deref + std::ops::DerefMut { - fn comments(&mut self) -> &mut Option>; + fn comments(&self) -> Option<&Comments<'a>>; + fn comments_mut(&mut self) -> Option<&mut Comments<'a>>; fn ann_post(&mut self, ident: Ident); fn print_generic_args(&mut self, args: &ast::GenericArgs, colons_before_params: bool); @@ -442,18 +449,18 @@ pub trait PrintState<'a>: std::ops::Deref + std::ops::Dere fn maybe_print_comment(&mut self, pos: BytePos) -> bool { let mut has_comment = false; - while let Some(cmnt) = self.next_comment() { - if cmnt.pos < pos { - has_comment = true; - self.print_comment(&cmnt); - } else { + while let Some(cmnt) = self.peek_comment() { + if cmnt.pos >= pos { break; } + has_comment = true; + let cmnt = self.next_comment().unwrap(); + self.print_comment(cmnt); } has_comment } - fn print_comment(&mut self, cmnt: &Comment) { + fn print_comment(&mut self, cmnt: Comment) { match cmnt.style { CommentStyle::Mixed => { if !self.is_beginning_of_line() { @@ -517,19 +524,20 @@ pub trait PrintState<'a>: std::ops::Deref + std::ops::Dere self.hardbreak(); } } - if let Some(cmnts) = self.comments() { - cmnts.current += 1; - } + } + + fn peek_comment<'b>(&'b self) -> Option<&'b Comment> where 'a: 'b { + self.comments().and_then(|c| c.peek()) } fn next_comment(&mut self) -> Option { - self.comments().as_mut().and_then(|c| c.next()) + self.comments_mut().and_then(|c| c.next()) } fn maybe_print_trailing_comment(&mut self, span: rustc_span::Span, next_pos: Option) { - if let Some(cmnts) = self.comments() { + if let Some(cmnts) = self.comments_mut() { if let Some(cmnt) = cmnts.trailing_comment(span, next_pos) { - self.print_comment(&cmnt); + self.print_comment(cmnt); } } } @@ -537,11 +545,11 @@ pub trait PrintState<'a>: std::ops::Deref + std::ops::Dere fn print_remaining_comments(&mut self) { // If there aren't any remaining comments, then we need to manually // make sure there is a line break at the end. - if self.next_comment().is_none() { + if self.peek_comment().is_none() { self.hardbreak(); } while let Some(cmnt) = self.next_comment() { - self.print_comment(&cmnt) + self.print_comment(cmnt) } } @@ -994,8 +1002,12 @@ pub trait PrintState<'a>: std::ops::Deref + std::ops::Dere } impl<'a> PrintState<'a> for State<'a> { - fn comments(&mut self) -> &mut Option> { - &mut self.comments + fn comments(&self) -> Option<&Comments<'a>> { + self.comments.as_ref() + } + + fn comments_mut(&mut self) -> Option<&mut Comments<'a>> { + self.comments.as_mut() } fn ann_post(&mut self, ident: Ident) { diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index 4f5fbd024a998..a47e6af0bf201 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -139,8 +139,12 @@ impl std::ops::DerefMut for State<'_> { } impl<'a> PrintState<'a> for State<'a> { - fn comments(&mut self) -> &mut Option> { - &mut self.comments + fn comments(&self) -> Option<&Comments<'a>> { + self.comments.as_ref() + } + + fn comments_mut(&mut self) -> Option<&mut Comments<'a>> { + self.comments.as_mut() } fn ann_post(&mut self, ident: Ident) { From 74e1b46ab23fe1f2deb414968340ca35e7882ae0 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 13 May 2024 10:06:27 +1000 Subject: [PATCH 147/179] Make `Comments::next` consume a comment. This avoids the need for a clone, fixing a FIXME comment. --- compiler/rustc_ast_pretty/src/pprust/state.rs | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index 9eb552cdcdfae..329c2167d5506 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -55,8 +55,8 @@ impl PpAnn for NoAnn {} pub struct Comments<'a> { sm: &'a SourceMap, - comments: Vec, - current: usize, + // Stored in reverse order so we can consume them by popping. + reversed_comments: Vec, } /// Returns `None` if the first `col` chars of `s` contain a non-whitespace char. @@ -182,19 +182,17 @@ fn gather_comments(sm: &SourceMap, path: FileName, src: String) -> Vec impl<'a> Comments<'a> { pub fn new(sm: &'a SourceMap, filename: FileName, input: String) -> Comments<'a> { - let comments = gather_comments(sm, filename, input); - Comments { sm, comments, current: 0 } + let mut comments = gather_comments(sm, filename, input); + comments.reverse(); + Comments { sm, reversed_comments: comments } } fn peek(&self) -> Option<&Comment> { - self.comments.get(self.current) + self.reversed_comments.last() } - // FIXME: This shouldn't probably clone lmao fn next(&mut self) -> Option { - let cmnt = self.comments.get(self.current).cloned(); - self.current += 1; - cmnt + self.reversed_comments.pop() } fn trailing_comment( From 9a63a42cb787476930f094fdbd9885251ae01de0 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 22 Apr 2024 16:29:27 +1000 Subject: [PATCH 148/179] Remove a `Span` from `TokenKind::Interpolated`. This span records the declaration of the metavariable in the LHS of the macro. It's used in a couple of error messages. Unfortunately, it gets in the way of the long-term goal of removing `TokenKind::Interpolated`. So this commit removes it, which degrades a couple of (obscure) error messages but makes things simpler and enables the next commit. --- compiler/rustc_ast/src/attr/mod.rs | 2 +- compiler/rustc_ast/src/mut_visit.rs | 2 -- compiler/rustc_ast/src/token.rs | 33 +++++++++++-------- compiler/rustc_ast/src/tokenstream.rs | 6 ++-- compiler/rustc_ast_pretty/src/pprust/state.rs | 2 +- compiler/rustc_expand/src/mbe/diagnostics.rs | 6 ---- compiler/rustc_expand/src/mbe/macro_parser.rs | 11 ++----- compiler/rustc_expand/src/proc_macro.rs | 2 +- .../rustc_expand/src/proc_macro_server.rs | 6 ++-- compiler/rustc_parse/src/parser/attr.rs | 2 +- .../rustc_parse/src/parser/diagnostics.rs | 23 +++++-------- compiler/rustc_parse/src/parser/expr.rs | 2 +- compiler/rustc_parse/src/parser/item.rs | 2 +- compiler/rustc_parse/src/parser/mod.rs | 28 +++++----------- .../rustc_parse/src/parser/nonterminal.rs | 18 +++++----- compiler/rustc_parse/src/parser/pat.rs | 2 +- compiler/rustc_parse/src/parser/path.rs | 2 +- tests/ui/macros/nonterminal-matching.stderr | 2 -- tests/ui/macros/trace_faulty_macros.stderr | 8 ++--- 19 files changed, 62 insertions(+), 97 deletions(-) diff --git a/compiler/rustc_ast/src/attr/mod.rs b/compiler/rustc_ast/src/attr/mod.rs index 0f12fd3197520..0684163617fe6 100644 --- a/compiler/rustc_ast/src/attr/mod.rs +++ b/compiler/rustc_ast/src/attr/mod.rs @@ -345,7 +345,7 @@ impl MetaItem { let span = span.with_hi(segments.last().unwrap().ident.span.hi()); Path { span, segments, tokens: None } } - Some(TokenTree::Token(Token { kind: token::Interpolated(nt), .. }, _)) => match &nt.0 { + Some(TokenTree::Token(Token { kind: token::Interpolated(nt), .. }, _)) => match &**nt { token::Nonterminal::NtMeta(item) => return item.meta(item.path.span), token::Nonterminal::NtPath(path) => (**path).clone(), _ => return None, diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index 379c2e273eb1c..07358047025ab 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -783,8 +783,6 @@ pub fn visit_token(t: &mut Token, vis: &mut T) { } token::Interpolated(nt) => { let nt = Lrc::make_mut(nt); - let (nt, sp) = (&mut nt.0, &mut nt.1); - vis.visit_span(sp); visit_nonterminal(nt, vis); } _ => {} diff --git a/compiler/rustc_ast/src/token.rs b/compiler/rustc_ast/src/token.rs index 72f89737f9952..590c3daf0c223 100644 --- a/compiler/rustc_ast/src/token.rs +++ b/compiler/rustc_ast/src/token.rs @@ -111,7 +111,7 @@ impl Lit { Ident(name, IdentIsRaw::No) if name.is_bool_lit() => Some(Lit::new(Bool, name, None)), Literal(token_lit) => Some(token_lit), Interpolated(ref nt) - if let NtExpr(expr) | NtLiteral(expr) = &nt.0 + if let NtExpr(expr) | NtLiteral(expr) = &**nt && let ast::ExprKind::Lit(token_lit) = expr.kind => { Some(token_lit) @@ -333,7 +333,11 @@ pub enum TokenKind { /// - It prevents `Token` from implementing `Copy`. /// It adds complexity and likely slows things down. Please don't add new /// occurrences of this token kind! - Interpolated(Lrc<(Nonterminal, Span)>), + /// + /// The span in the surrounding `Token` is that of the metavariable in the + /// macro's RHS. The span within the Nonterminal is that of the fragment + /// passed to the macro at the call site. + Interpolated(Lrc), /// A doc comment token. /// `Symbol` is the doc comment's data excluding its "quotes" (`///`, `/**`, etc) @@ -441,7 +445,7 @@ impl Token { /// if they keep spans or perform edition checks. pub fn uninterpolated_span(&self) -> Span { match &self.kind { - Interpolated(nt) => nt.0.use_span(), + Interpolated(nt) => nt.use_span(), _ => self.span, } } @@ -486,7 +490,7 @@ impl Token { PathSep | // global path Lifetime(..) | // labeled loop Pound => true, // expression attributes - Interpolated(ref nt) => matches!(&nt.0, NtLiteral(..) | + Interpolated(ref nt) => matches!(&**nt, NtLiteral(..) | NtExpr(..) | NtBlock(..) | NtPath(..)), @@ -510,7 +514,7 @@ impl Token { | DotDot | DotDotDot | DotDotEq // ranges | Lt | BinOp(Shl) // associated path | PathSep => true, // global path - Interpolated(ref nt) => matches!(&nt.0, NtLiteral(..) | + Interpolated(ref nt) => matches!(&**nt, NtLiteral(..) | NtPat(..) | NtBlock(..) | NtPath(..)), @@ -533,7 +537,7 @@ impl Token { Lifetime(..) | // lifetime bound in trait object Lt | BinOp(Shl) | // associated path PathSep => true, // global path - Interpolated(ref nt) => matches!(&nt.0, NtTy(..) | NtPath(..)), + Interpolated(ref nt) => matches!(&**nt, NtTy(..) | NtPath(..)), // For anonymous structs or unions, which only appear in specific positions // (type of struct fields or union fields), we don't consider them as regular types _ => false, @@ -544,7 +548,7 @@ impl Token { pub fn can_begin_const_arg(&self) -> bool { match self.kind { OpenDelim(Delimiter::Brace) => true, - Interpolated(ref nt) => matches!(&nt.0, NtExpr(..) | NtBlock(..) | NtLiteral(..)), + Interpolated(ref nt) => matches!(&**nt, NtExpr(..) | NtBlock(..) | NtLiteral(..)), _ => self.can_begin_literal_maybe_minus(), } } @@ -589,7 +593,7 @@ impl Token { match self.uninterpolate().kind { Literal(..) | BinOp(Minus) => true, Ident(name, IdentIsRaw::No) if name.is_bool_lit() => true, - Interpolated(ref nt) => match &nt.0 { + Interpolated(ref nt) => match &**nt { NtLiteral(_) => true, NtExpr(e) => match &e.kind { ast::ExprKind::Lit(_) => true, @@ -610,7 +614,7 @@ impl Token { /// otherwise returns the original token. pub fn uninterpolate(&self) -> Cow<'_, Token> { match &self.kind { - Interpolated(nt) => match &nt.0 { + Interpolated(nt) => match &**nt { NtIdent(ident, is_raw) => { Cow::Owned(Token::new(Ident(ident.name, *is_raw), ident.span)) } @@ -627,7 +631,7 @@ impl Token { // We avoid using `Token::uninterpolate` here because it's slow. match &self.kind { &Ident(name, is_raw) => Some((Ident::new(name, self.span), is_raw)), - Interpolated(nt) => match &nt.0 { + Interpolated(nt) => match &**nt { NtIdent(ident, is_raw) => Some((*ident, *is_raw)), _ => None, }, @@ -641,7 +645,7 @@ impl Token { // We avoid using `Token::uninterpolate` here because it's slow. match &self.kind { &Lifetime(name) => Some(Ident::new(name, self.span)), - Interpolated(nt) => match &nt.0 { + Interpolated(nt) => match &**nt { NtLifetime(ident) => Some(*ident), _ => None, }, @@ -668,7 +672,7 @@ impl Token { /// Returns `true` if the token is an interpolated path. fn is_whole_path(&self) -> bool { if let Interpolated(nt) = &self.kind - && let NtPath(..) = &nt.0 + && let NtPath(..) = &**nt { return true; } @@ -681,7 +685,7 @@ impl Token { /// (which happens while parsing the result of macro expansion)? pub fn is_whole_expr(&self) -> bool { if let Interpolated(nt) = &self.kind - && let NtExpr(_) | NtLiteral(_) | NtPath(_) | NtBlock(_) = &nt.0 + && let NtExpr(_) | NtLiteral(_) | NtPath(_) | NtBlock(_) = &**nt { return true; } @@ -692,7 +696,7 @@ impl Token { /// Is the token an interpolated block (`$b:block`)? pub fn is_whole_block(&self) -> bool { if let Interpolated(nt) = &self.kind - && let NtBlock(..) = &nt.0 + && let NtBlock(..) = &**nt { return true; } @@ -857,6 +861,7 @@ pub enum Nonterminal { NtPat(P), NtExpr(P), NtTy(P), + /// The span is for the identifier argument passed to the macro. NtIdent(Ident, IdentIsRaw), NtLifetime(Ident), NtLiteral(P), diff --git a/compiler/rustc_ast/src/tokenstream.rs b/compiler/rustc_ast/src/tokenstream.rs index 8e80161af1bf4..d532a884184ce 100644 --- a/compiler/rustc_ast/src/tokenstream.rs +++ b/compiler/rustc_ast/src/tokenstream.rs @@ -490,14 +490,14 @@ impl TokenStream { fn flatten_token(token: &Token, spacing: Spacing) -> TokenTree { match &token.kind { - token::Interpolated(nt) if let token::NtIdent(ident, is_raw) = nt.0 => { - TokenTree::Token(Token::new(token::Ident(ident.name, is_raw), ident.span), spacing) + token::Interpolated(nt) if let token::NtIdent(ident, is_raw) = &**nt => { + TokenTree::Token(Token::new(token::Ident(ident.name, *is_raw), ident.span), spacing) } token::Interpolated(nt) => TokenTree::Delimited( DelimSpan::from_single(token.span), DelimSpacing::new(Spacing::JointHidden, spacing), Delimiter::Invisible, - TokenStream::from_nonterminal_ast(&nt.0).flattened(), + TokenStream::from_nonterminal_ast(&nt).flattened(), ), _ => TokenTree::Token(token.clone(), spacing), } diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index 2c176828c841f..f438cee4cd252 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -926,7 +926,7 @@ pub trait PrintState<'a>: std::ops::Deref + std::ops::Dere } token::Eof => "".into(), - token::Interpolated(ref nt) => self.nonterminal_to_string(&nt.0).into(), + token::Interpolated(ref nt) => self.nonterminal_to_string(&nt).into(), } } diff --git a/compiler/rustc_expand/src/mbe/diagnostics.rs b/compiler/rustc_expand/src/mbe/diagnostics.rs index 464361cb4020b..3fee39dd085cc 100644 --- a/compiler/rustc_expand/src/mbe/diagnostics.rs +++ b/compiler/rustc_expand/src/mbe/diagnostics.rs @@ -73,12 +73,6 @@ pub(super) fn failed_to_match_macro<'cx>( && (matches!(expected_token.kind, TokenKind::Interpolated(_)) || matches!(token.kind, TokenKind::Interpolated(_))) { - if let TokenKind::Interpolated(node) = &expected_token.kind { - err.span_label(node.1, ""); - } - if let TokenKind::Interpolated(node) = &token.kind { - err.span_label(node.1, ""); - } err.note("captured metavariables except for `:tt`, `:ident` and `:lifetime` cannot be compared to other tokens"); err.note("see for more information"); diff --git a/compiler/rustc_expand/src/mbe/macro_parser.rs b/compiler/rustc_expand/src/mbe/macro_parser.rs index ffb50f4c92e14..27cf6fee702a7 100644 --- a/compiler/rustc_expand/src/mbe/macro_parser.rs +++ b/compiler/rustc_expand/src/mbe/macro_parser.rs @@ -75,10 +75,9 @@ pub(crate) use ParseResult::*; use crate::mbe::{macro_rules::Tracker, KleeneOp, TokenTree}; -use rustc_ast::token::{self, DocComment, Nonterminal, NonterminalKind, Token}; +use rustc_ast::token::{self, DocComment, NonterminalKind, Token}; use rustc_ast_pretty::pprust; use rustc_data_structures::fx::FxHashMap; -use rustc_data_structures::sync::Lrc; use rustc_errors::ErrorGuaranteed; use rustc_lint_defs::pluralize; use rustc_parse::parser::{ParseNtResult, Parser}; @@ -392,7 +391,7 @@ pub(super) fn count_metavar_decls(matcher: &[TokenTree]) -> usize { #[derive(Debug, Clone)] pub(crate) enum NamedMatch { MatchedSeq(Vec), - MatchedSingle(ParseNtResult>), + MatchedSingle(ParseNtResult), } /// Performs a token equality check, ignoring syntax context (that is, an unhygienic comparison) @@ -686,11 +685,7 @@ impl TtParser { } Ok(nt) => nt, }; - mp.push_match( - next_metavar, - seq_depth, - MatchedSingle(nt.map_nt(|nt| (Lrc::new((nt, span))))), - ); + mp.push_match(next_metavar, seq_depth, MatchedSingle(nt)); mp.idx += 1; } else { unreachable!() diff --git a/compiler/rustc_expand/src/proc_macro.rs b/compiler/rustc_expand/src/proc_macro.rs index 4b5c148cb555d..530059e53c210 100644 --- a/compiler/rustc_expand/src/proc_macro.rs +++ b/compiler/rustc_expand/src/proc_macro.rs @@ -127,7 +127,7 @@ impl MultiItemModifier for DeriveProcMacro { Annotatable::Stmt(stmt) => token::NtStmt(stmt), _ => unreachable!(), }; - TokenStream::token_alone(token::Interpolated(Lrc::new((nt, span))), DUMMY_SP) + TokenStream::token_alone(token::Interpolated(Lrc::new(nt)), DUMMY_SP) } else { item.to_tokens() }; diff --git a/compiler/rustc_expand/src/proc_macro_server.rs b/compiler/rustc_expand/src/proc_macro_server.rs index 5a66b0fbdef10..8cf9658016182 100644 --- a/compiler/rustc_expand/src/proc_macro_server.rs +++ b/compiler/rustc_expand/src/proc_macro_server.rs @@ -259,7 +259,7 @@ impl FromInternal<(TokenStream, &mut Rustc<'_, '_>)> for Vec { + Interpolated(ref nt) if let NtIdent(ident, is_raw) = &**nt => { trees.push(TokenTree::Ident(Ident { sym: ident.name, is_raw: matches!(is_raw, IdentIsRaw::Yes), @@ -268,14 +268,14 @@ impl FromInternal<(TokenStream, &mut Rustc<'_, '_>)> for Vec { - let stream = TokenStream::from_nonterminal_ast(&nt.0); + let stream = TokenStream::from_nonterminal_ast(&nt); // A hack used to pass AST fragments to attribute and derive // macros as a single nonterminal token instead of a token // stream. Such token needs to be "unwrapped" and not // represented as a delimited group. // FIXME: It needs to be removed, but there are some // compatibility issues (see #73345). - if crate::base::nt_pretty_printing_compatibility_hack(&nt.0, rustc.ecx.sess) { + if crate::base::nt_pretty_printing_compatibility_hack(&nt, rustc.ecx.sess) { trees.extend(Self::from_internal((stream, rustc))); } else { trees.push(TokenTree::Group(Group { diff --git a/compiler/rustc_parse/src/parser/attr.rs b/compiler/rustc_parse/src/parser/attr.rs index d5d8060d909a1..a57eb70c7053a 100644 --- a/compiler/rustc_parse/src/parser/attr.rs +++ b/compiler/rustc_parse/src/parser/attr.rs @@ -363,7 +363,7 @@ impl<'a> Parser<'a> { // We can't use `maybe_whole` here because it would bump in the `None` // case, which we don't want. if let token::Interpolated(nt) = &self.token.kind - && let token::NtMeta(attr_item) = &nt.0 + && let token::NtMeta(attr_item) = &**nt { match attr_item.meta(attr_item.path.span) { Some(meta) => { diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index 50698dbf9c176..63762f64be993 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -2372,9 +2372,9 @@ impl<'a> Parser<'a> { // in a subsequent macro invocation (#71039). let mut tok = self.token.clone(); let mut labels = vec![]; - while let TokenKind::Interpolated(node) = &tok.kind { - let tokens = node.0.tokens(); - labels.push(node.clone()); + while let TokenKind::Interpolated(nt) = &tok.kind { + let tokens = nt.tokens(); + labels.push(nt.clone()); if let Some(tokens) = tokens && let tokens = tokens.to_attr_token_stream() && let tokens = tokens.0.deref() @@ -2387,27 +2387,20 @@ impl<'a> Parser<'a> { } let mut iter = labels.into_iter().peekable(); let mut show_link = false; - while let Some(node) = iter.next() { - let descr = node.0.descr(); + while let Some(nt) = iter.next() { + let descr = nt.descr(); if let Some(next) = iter.peek() { - let next_descr = next.0.descr(); + let next_descr = next.descr(); if next_descr != descr { - err.span_label(next.1, format!("this macro fragment matcher is {next_descr}")); - err.span_label(node.1, format!("this macro fragment matcher is {descr}")); + err.span_label(next.use_span(), format!("this is expected to be {next_descr}")); err.span_label( - next.0.use_span(), - format!("this is expected to be {next_descr}"), - ); - err.span_label( - node.0.use_span(), + nt.use_span(), format!( "this is interpreted as {}, but it is expected to be {}", next_descr, descr, ), ); show_link = true; - } else { - err.span_label(node.1, ""); } } } diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 441aa5b0806da..8e3cd0f8ea9d5 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -45,7 +45,7 @@ use thin_vec::{thin_vec, ThinVec}; macro_rules! maybe_whole_expr { ($p:expr) => { if let token::Interpolated(nt) = &$p.token.kind { - match &nt.0 { + match &**nt { token::NtExpr(e) | token::NtLiteral(e) => { let e = e.clone(); $p.bump(); diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index df6996dbc458b..29957bd2f71ea 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -2841,7 +2841,7 @@ impl<'a> Parser<'a> { fn is_named_param(&self) -> bool { let offset = match &self.token.kind { - token::Interpolated(nt) => match &nt.0 { + token::Interpolated(nt) => match &**nt { token::NtPat(..) => return self.look_ahead(1, |t| t == &token::Colon), _ => 0, }, diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index bfb6c4a38858e..cc40c8a7126ed 100644 --- a/compiler/rustc_parse/src/parser/mod.rs +++ b/compiler/rustc_parse/src/parser/mod.rs @@ -11,7 +11,6 @@ mod stmt; mod ty; use crate::lexer::UnmatchedDelim; -use ast::token::IdentIsRaw; pub use attr_wrapper::AttrWrapper; pub use diagnostics::AttemptLocalParseRecovery; pub(crate) use expr::ForbiddenLetReason; @@ -21,7 +20,7 @@ pub use path::PathStyle; use core::fmt; use rustc_ast::ptr::P; -use rustc_ast::token::{self, Delimiter, Token, TokenKind}; +use rustc_ast::token::{self, Delimiter, IdentIsRaw, Nonterminal, Token, TokenKind}; use rustc_ast::tokenstream::{AttributesData, DelimSpacing, DelimSpan, Spacing}; use rustc_ast::tokenstream::{TokenStream, TokenTree, TokenTreeCursor}; use rustc_ast::util::case::Case; @@ -32,6 +31,7 @@ use rustc_ast::{ }; use rustc_ast_pretty::pprust; use rustc_data_structures::fx::FxHashMap; +use rustc_data_structures::sync::Lrc; use rustc_errors::{Applicability, Diag, FatalError, MultiSpan, PResult}; use rustc_session::parse::ParseSess; use rustc_span::symbol::{kw, sym, Ident, Symbol}; @@ -107,7 +107,7 @@ pub enum TrailingToken { macro_rules! maybe_whole { ($p:expr, $constructor:ident, |$x:ident| $e:expr) => { if let token::Interpolated(nt) = &$p.token.kind - && let token::$constructor(x) = &nt.0 + && let token::$constructor(x) = &**nt { #[allow(unused_mut)] let mut $x = x.clone(); @@ -125,7 +125,7 @@ macro_rules! maybe_recover_from_interpolated_ty_qpath { && $self.may_recover() && $self.look_ahead(1, |t| t == &token::PathSep) && let token::Interpolated(nt) = &$self.token.kind - && let token::NtTy(ty) = &nt.0 + && let token::NtTy(ty) = &**nt { let ty = ty.clone(); $self.bump(); @@ -407,7 +407,7 @@ pub(super) fn token_descr(token: &Token) -> String { (Some(TokenDescription::Keyword), _) => Some("keyword"), (Some(TokenDescription::ReservedKeyword), _) => Some("reserved keyword"), (Some(TokenDescription::DocComment), _) => Some("doc comment"), - (None, TokenKind::Interpolated(node)) => Some(node.0.descr()), + (None, TokenKind::Interpolated(node)) => Some(node.descr()), (None, _) => None, }; @@ -708,7 +708,7 @@ impl<'a> Parser<'a> { fn check_inline_const(&self, dist: usize) -> bool { self.is_keyword_ahead(dist, &[kw::Const]) && self.look_ahead(dist + 1, |t| match &t.kind { - token::Interpolated(nt) => matches!(&nt.0, token::NtBlock(..)), + token::Interpolated(nt) => matches!(&**nt, token::NtBlock(..)), token::OpenDelim(Delimiter::Brace) => true, _ => false, }) @@ -1631,19 +1631,7 @@ pub enum FlatToken { // Metavar captures of various kinds. #[derive(Clone, Debug)] -pub enum ParseNtResult { +pub enum ParseNtResult { Tt(TokenTree), - Nt(NtType), -} - -impl ParseNtResult { - pub fn map_nt(self, mut f: F) -> ParseNtResult - where - F: FnMut(T) -> U, - { - match self { - ParseNtResult::Tt(tt) => ParseNtResult::Tt(tt), - ParseNtResult::Nt(nt) => ParseNtResult::Nt(f(nt)), - } - } + Nt(Lrc), } diff --git a/compiler/rustc_parse/src/parser/nonterminal.rs b/compiler/rustc_parse/src/parser/nonterminal.rs index 73b17353ac90c..3a560382d327c 100644 --- a/compiler/rustc_parse/src/parser/nonterminal.rs +++ b/compiler/rustc_parse/src/parser/nonterminal.rs @@ -1,7 +1,8 @@ use rustc_ast::ptr::P; -use rustc_ast::token::{self, Delimiter, Nonterminal, Nonterminal::*, NonterminalKind, Token}; +use rustc_ast::token::{self, Delimiter, Nonterminal::*, NonterminalKind, Token}; use rustc_ast::HasTokens; use rustc_ast_pretty::pprust; +use rustc_data_structures::sync::Lrc; use rustc_errors::PResult; use rustc_span::symbol::{kw, Ident}; @@ -54,7 +55,7 @@ impl<'a> Parser<'a> { }, NonterminalKind::Block => match &token.kind { token::OpenDelim(Delimiter::Brace) => true, - token::Interpolated(nt) => match &nt.0 { + token::Interpolated(nt) => match &**nt { NtBlock(_) | NtLifetime(_) | NtStmt(_) | NtExpr(_) | NtLiteral(_) => true, NtItem(_) | NtPat(_) | NtTy(_) | NtIdent(..) | NtMeta(_) | NtPath(_) | NtVis(_) => false, @@ -63,7 +64,7 @@ impl<'a> Parser<'a> { }, NonterminalKind::Path | NonterminalKind::Meta => match &token.kind { token::PathSep | token::Ident(..) => true, - token::Interpolated(nt) => may_be_ident(&nt.0), + token::Interpolated(nt) => may_be_ident(nt), _ => false, }, NonterminalKind::PatParam { .. } | NonterminalKind::PatWithOr => match &token.kind { @@ -81,13 +82,13 @@ impl<'a> Parser<'a> { token::BinOp(token::Shl) => true, // path (double UFCS) // leading vert `|` or-pattern token::BinOp(token::Or) => matches!(kind, NonterminalKind::PatWithOr), - token::Interpolated(nt) => may_be_ident(&nt.0), + token::Interpolated(nt) => may_be_ident(nt), _ => false, }, NonterminalKind::Lifetime => match &token.kind { token::Lifetime(_) => true, token::Interpolated(nt) => { - matches!(&nt.0, NtLifetime(_)) + matches!(&**nt, NtLifetime(_)) } _ => false, }, @@ -100,10 +101,7 @@ impl<'a> Parser<'a> { /// Parse a non-terminal (e.g. MBE `:pat` or `:ident`). Inlined because there is only one call /// site. #[inline] - pub fn parse_nonterminal( - &mut self, - kind: NonterminalKind, - ) -> PResult<'a, ParseNtResult> { + pub fn parse_nonterminal(&mut self, kind: NonterminalKind) -> PResult<'a, ParseNtResult> { // A `macro_rules!` invocation may pass a captured item/expr to a proc-macro, // which requires having captured tokens available. Since we cannot determine // in advance whether or not a proc-macro will be (transitively) invoked, @@ -196,7 +194,7 @@ impl<'a> Parser<'a> { ); } - Ok(ParseNtResult::Nt(nt)) + Ok(ParseNtResult::Nt(Lrc::new(nt))) } } diff --git a/compiler/rustc_parse/src/parser/pat.rs b/compiler/rustc_parse/src/parser/pat.rs index 78d3d019bf4d2..8af415f7c9dd3 100644 --- a/compiler/rustc_parse/src/parser/pat.rs +++ b/compiler/rustc_parse/src/parser/pat.rs @@ -757,7 +757,7 @@ impl<'a> Parser<'a> { // Make sure we don't allow e.g. `let mut $p;` where `$p:pat`. if let token::Interpolated(nt) = &self.token.kind { - if let token::NtPat(..) = &nt.0 { + if let token::NtPat(..) = &**nt { self.expected_ident_found_err().emit(); } } diff --git a/compiler/rustc_parse/src/parser/path.rs b/compiler/rustc_parse/src/parser/path.rs index 3636a3579781b..c37d3f0441d0b 100644 --- a/compiler/rustc_parse/src/parser/path.rs +++ b/compiler/rustc_parse/src/parser/path.rs @@ -193,7 +193,7 @@ impl<'a> Parser<'a> { maybe_whole!(self, NtPath, |path| reject_generics_if_mod_style(self, path.into_inner())); if let token::Interpolated(nt) = &self.token.kind { - if let token::NtTy(ty) = &nt.0 { + if let token::NtTy(ty) = &**nt { if let ast::TyKind::Path(None, path) = &ty.kind { let path = path.clone(); self.bump(); diff --git a/tests/ui/macros/nonterminal-matching.stderr b/tests/ui/macros/nonterminal-matching.stderr index 499f9a7637d22..d19141145fa19 100644 --- a/tests/ui/macros/nonterminal-matching.stderr +++ b/tests/ui/macros/nonterminal-matching.stderr @@ -1,8 +1,6 @@ error: no rules expected the token `enum E {}` --> $DIR/nonterminal-matching.rs:19:10 | -LL | macro complex_nonterminal($nt_item: item) { - | -------------- LL | macro n(a $nt_item b) { | --------------------- when calling this macro ... diff --git a/tests/ui/macros/trace_faulty_macros.stderr b/tests/ui/macros/trace_faulty_macros.stderr index 69607600b55c8..665dcc7d0913c 100644 --- a/tests/ui/macros/trace_faulty_macros.stderr +++ b/tests/ui/macros/trace_faulty_macros.stderr @@ -73,14 +73,10 @@ error: expected expression, found pattern `1 + 1` --> $DIR/trace_faulty_macros.rs:49:37 | LL | (let $p:pat = $e:expr) => {test!(($p,$e))}; - | ------- -- this is interpreted as expression, but it is expected to be pattern - | | - | this macro fragment matcher is expression + | -- this is interpreted as expression, but it is expected to be pattern ... LL | (($p:pat, $e:pat)) => {let $p = $e;}; - | ------ ^^ expected expression - | | - | this macro fragment matcher is pattern + | ^^ expected expression ... LL | test!(let x = 1+1); | ------------------ From b15d09a6ddd8a069d3aaa2bd5326cd3dad53b81e Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 13 May 2024 08:06:37 +0200 Subject: [PATCH 149/179] interpret: move error macros into error.rs --- .../rustc_middle/src/mir/interpret/error.rs | 121 +++++++++++++++- .../rustc_middle/src/mir/interpret/mod.rs | 137 +----------------- 2 files changed, 126 insertions(+), 132 deletions(-) diff --git a/compiler/rustc_middle/src/mir/interpret/error.rs b/compiler/rustc_middle/src/mir/interpret/error.rs index 383241465c3d1..6e152cbcb6571 100644 --- a/compiler/rustc_middle/src/mir/interpret/error.rs +++ b/compiler/rustc_middle/src/mir/interpret/error.rs @@ -188,8 +188,9 @@ impl<'tcx> From> for InterpErrorInfo<'tcx> { } /// Error information for when the program we executed turned out not to actually be a valid -/// program. This cannot happen in stand-alone Miri, but it can happen during CTFE/ConstProp -/// where we work on generic code or execution does not have all information available. +/// program. This cannot happen in stand-alone Miri (except for layout errors that are only detect +/// during monomorphization), but it can happen during CTFE/ConstProp where we work on generic code +/// or execution does not have all information available. #[derive(Debug)] pub enum InvalidProgramInfo<'tcx> { /// Resolution can fail if we are in a too generic context. @@ -507,7 +508,7 @@ pub enum ValidationErrorKind<'tcx> { /// Miri engine, e.g., CTFE does not support dereferencing pointers at integral addresses. #[derive(Debug)] pub enum UnsupportedOpInfo { - /// Free-form case. Only for errors that are never caught! + /// Free-form case. Only for errors that are never caught! Used by Miri. // FIXME still use translatable diagnostics Unsupported(String), /// Unsized local variables. @@ -592,3 +593,117 @@ impl InterpError<'_> { ) } } + +// Macros for constructing / throwing `InterpError` +#[macro_export] +macro_rules! err_unsup { + ($($tt:tt)*) => { + $crate::mir::interpret::InterpError::Unsupported( + $crate::mir::interpret::UnsupportedOpInfo::$($tt)* + ) + }; +} + +#[macro_export] +macro_rules! err_unsup_format { + ($($tt:tt)*) => { $crate::err_unsup!(Unsupported(format!($($tt)*))) }; +} + +#[macro_export] +macro_rules! err_inval { + ($($tt:tt)*) => { + $crate::mir::interpret::InterpError::InvalidProgram( + $crate::mir::interpret::InvalidProgramInfo::$($tt)* + ) + }; +} + +#[macro_export] +macro_rules! err_ub { + ($($tt:tt)*) => { + $crate::mir::interpret::InterpError::UndefinedBehavior( + $crate::mir::interpret::UndefinedBehaviorInfo::$($tt)* + ) + }; +} + +#[macro_export] +macro_rules! err_ub_format { + ($($tt:tt)*) => { $crate::err_ub!(Ub(format!($($tt)*))) }; +} + +#[macro_export] +macro_rules! err_ub_custom { + ($msg:expr $(, $($name:ident = $value:expr),* $(,)?)?) => {{ + $( + let ($($name,)*) = ($($value,)*); + )? + $crate::err_ub!(Custom( + $crate::error::CustomSubdiagnostic { + msg: || $msg, + add_args: Box::new(move |mut set_arg| { + $($( + set_arg(stringify!($name).into(), rustc_errors::IntoDiagArg::into_diag_arg($name)); + )*)? + }) + } + )) + }}; +} + +#[macro_export] +macro_rules! err_exhaust { + ($($tt:tt)*) => { + $crate::mir::interpret::InterpError::ResourceExhaustion( + $crate::mir::interpret::ResourceExhaustionInfo::$($tt)* + ) + }; +} + +#[macro_export] +macro_rules! err_machine_stop { + ($($tt:tt)*) => { + $crate::mir::interpret::InterpError::MachineStop(Box::new($($tt)*)) + }; +} + +// In the `throw_*` macros, avoid `return` to make them work with `try {}`. +#[macro_export] +macro_rules! throw_unsup { + ($($tt:tt)*) => { do yeet $crate::err_unsup!($($tt)*) }; +} + +#[macro_export] +macro_rules! throw_unsup_format { + ($($tt:tt)*) => { do yeet $crate::err_unsup_format!($($tt)*) }; +} + +#[macro_export] +macro_rules! throw_inval { + ($($tt:tt)*) => { do yeet $crate::err_inval!($($tt)*) }; +} + +#[macro_export] +macro_rules! throw_ub { + ($($tt:tt)*) => { do yeet $crate::err_ub!($($tt)*) }; +} + +#[macro_export] +macro_rules! throw_ub_format { + ($($tt:tt)*) => { do yeet $crate::err_ub_format!($($tt)*) }; +} + +#[macro_export] +macro_rules! throw_ub_custom { + ($($tt:tt)*) => { do yeet $crate::err_ub_custom!($($tt)*) }; +} + +#[macro_export] +macro_rules! throw_exhaust { + ($($tt:tt)*) => { do yeet $crate::err_exhaust!($($tt)*) }; +} + +#[macro_export] +macro_rules! throw_machine_stop { + ($($tt:tt)*) => { do yeet $crate::err_machine_stop!($($tt)*) }; +} diff --git a/compiler/rustc_middle/src/mir/interpret/mod.rs b/compiler/rustc_middle/src/mir/interpret/mod.rs index 20afe52c1f31c..739b1410e6db4 100644 --- a/compiler/rustc_middle/src/mir/interpret/mod.rs +++ b/compiler/rustc_middle/src/mir/interpret/mod.rs @@ -1,136 +1,9 @@ //! An interpreter for MIR used in CTFE and by miri. -#[macro_export] -macro_rules! err_unsup { - ($($tt:tt)*) => { - $crate::mir::interpret::InterpError::Unsupported( - $crate::mir::interpret::UnsupportedOpInfo::$($tt)* - ) - }; -} -pub use err_unsup; - -#[macro_export] -macro_rules! err_unsup_format { - ($($tt:tt)*) => { $crate::err_unsup!(Unsupported(format!($($tt)*))) }; -} -pub use err_unsup_format; - -#[macro_export] -macro_rules! err_inval { - ($($tt:tt)*) => { - $crate::mir::interpret::InterpError::InvalidProgram( - $crate::mir::interpret::InvalidProgramInfo::$($tt)* - ) - }; -} -pub use err_inval; - -#[macro_export] -macro_rules! err_ub { - ($($tt:tt)*) => { - $crate::mir::interpret::InterpError::UndefinedBehavior( - $crate::mir::interpret::UndefinedBehaviorInfo::$($tt)* - ) - }; -} -pub use err_ub; - -#[macro_export] -macro_rules! err_ub_format { - ($($tt:tt)*) => { err_ub!(Ub(format!($($tt)*))) }; -} -pub use err_ub_format; - -#[macro_export] -macro_rules! err_exhaust { - ($($tt:tt)*) => { - $crate::mir::interpret::InterpError::ResourceExhaustion( - $crate::mir::interpret::ResourceExhaustionInfo::$($tt)* - ) - }; -} -pub use err_exhaust; - -#[macro_export] -macro_rules! err_machine_stop { - ($($tt:tt)*) => { - $crate::mir::interpret::InterpError::MachineStop(Box::new($($tt)*)) - }; -} -pub use err_machine_stop; - -// In the `throw_*` macros, avoid `return` to make them work with `try {}`. -#[macro_export] -macro_rules! throw_unsup { - ($($tt:tt)*) => { do yeet $crate::err_unsup!($($tt)*) }; -} -pub use throw_unsup; - -#[macro_export] -macro_rules! throw_unsup_format { - ($($tt:tt)*) => { $crate::throw_unsup!(Unsupported(format!($($tt)*))) }; -} -pub use throw_unsup_format; - -#[macro_export] -macro_rules! throw_inval { - ($($tt:tt)*) => { do yeet $crate::err_inval!($($tt)*) }; -} -pub use throw_inval; - -#[macro_export] -macro_rules! throw_ub { - ($($tt:tt)*) => { do yeet $crate::err_ub!($($tt)*) }; -} -pub use throw_ub; - -#[macro_export] -macro_rules! throw_ub_format { - ($($tt:tt)*) => { $crate::throw_ub!(Ub(format!($($tt)*))) }; -} -pub use throw_ub_format; - -#[macro_export] -macro_rules! throw_exhaust { - ($($tt:tt)*) => { do yeet $crate::err_exhaust!($($tt)*) }; -} -pub use throw_exhaust; - -#[macro_export] -macro_rules! throw_machine_stop { - ($($tt:tt)*) => { do yeet $crate::err_machine_stop!($($tt)*) }; -} -pub use throw_machine_stop; - -#[macro_export] -macro_rules! err_ub_custom { - ($msg:expr $(, $($name:ident = $value:expr),* $(,)?)?) => {{ - $( - let ($($name,)*) = ($($value,)*); - )? - $crate::err_ub!(Custom( - $crate::error::CustomSubdiagnostic { - msg: || $msg, - add_args: Box::new(move |mut set_arg| { - $($( - set_arg(stringify!($name).into(), rustc_errors::IntoDiagArg::into_diag_arg($name)); - )*)? - }) - } - )) - }}; -} -pub use err_ub_custom; - -#[macro_export] -macro_rules! throw_ub_custom { - ($($tt:tt)*) => { do yeet $crate::err_ub_custom!($($tt)*) }; -} -pub use throw_ub_custom; +#[macro_use] +mod error; mod allocation; -mod error; mod pointer; mod queries; mod value; @@ -166,6 +39,12 @@ pub use self::error::{ ScalarSizeMismatch, UndefinedBehaviorInfo, UnsupportedOpInfo, ValidationErrorInfo, ValidationErrorKind, }; +// Also make the error macros available from this module. +pub use { + err_exhaust, err_inval, err_machine_stop, err_ub, err_ub_custom, err_ub_format, err_unsup, + err_unsup_format, throw_exhaust, throw_inval, throw_machine_stop, throw_ub, throw_ub_custom, + throw_ub_format, throw_unsup, throw_unsup_format, +}; pub use self::value::Scalar; From b98b8d76b1228999dd97058ea4e4a4719fe2f287 Mon Sep 17 00:00:00 2001 From: Tobias Bucher Date: Mon, 13 May 2024 09:18:23 +0200 Subject: [PATCH 150/179] Don't call `env::set_var` in `rustc_driver::install_ice_hook` Modifying an environment variable would make the function unsafe to call. --- compiler/rustc_driver_impl/src/lib.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index b2d38a00f0b5f..ba6b9ef078467 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -11,6 +11,7 @@ #![allow(internal_features)] #![feature(decl_macro)] #![feature(let_chains)] +#![feature(panic_backtrace_config)] #![feature(panic_update_hook)] #![feature(result_flattening)] @@ -1317,8 +1318,8 @@ pub fn install_ice_hook( // by the user. Compiler developers and other rustc users can // opt in to less-verbose backtraces by manually setting "RUST_BACKTRACE" // (e.g. `RUST_BACKTRACE=1`) - if std::env::var_os("RUST_BACKTRACE").is_none() { - std::env::set_var("RUST_BACKTRACE", "full"); + if env::var_os("RUST_BACKTRACE").is_none() { + panic::set_backtrace_style(panic::BacktraceStyle::Full); } let using_internal_features = Arc::new(std::sync::atomic::AtomicBool::default()); From b3a78c1d094eb978ec876643c3c4d0e5349b1073 Mon Sep 17 00:00:00 2001 From: Alice Ryhl Date: Mon, 13 May 2024 13:34:33 +0200 Subject: [PATCH 151/179] Add test for dynamic dispatch + Pin::new soundness --- tests/ui/coercion/pin-dyn-dispatch-sound.rs | 19 +++++++++++++++++++ .../ui/coercion/pin-dyn-dispatch-sound.stderr | 9 +++++++++ 2 files changed, 28 insertions(+) create mode 100644 tests/ui/coercion/pin-dyn-dispatch-sound.rs create mode 100644 tests/ui/coercion/pin-dyn-dispatch-sound.stderr diff --git a/tests/ui/coercion/pin-dyn-dispatch-sound.rs b/tests/ui/coercion/pin-dyn-dispatch-sound.rs new file mode 100644 index 0000000000000..b9d43ebac8bf4 --- /dev/null +++ b/tests/ui/coercion/pin-dyn-dispatch-sound.rs @@ -0,0 +1,19 @@ +use std::marker::PhantomPinned; +use std::pin::Pin; + +trait MyUnpinTrait { + fn into_pinned_type(self: Pin<&mut Self>) -> Pin<&mut PhantomPinned>; +} +impl MyUnpinTrait for PhantomPinned { + fn into_pinned_type(self: Pin<&mut Self>) -> Pin<&mut PhantomPinned> { + self + } +} +impl Unpin for dyn MyUnpinTrait {} //~ ERROR E0321 + +// It would be unsound for this function to compile. +fn pin_it(not_yet_pinned: &mut PhantomPinned) -> Pin<&mut PhantomPinned> { + Pin::new(not_yet_pinned as &mut dyn MyUnpinTrait).into_pinned_type() +} + +fn main() {} diff --git a/tests/ui/coercion/pin-dyn-dispatch-sound.stderr b/tests/ui/coercion/pin-dyn-dispatch-sound.stderr new file mode 100644 index 0000000000000..45860bfcfc760 --- /dev/null +++ b/tests/ui/coercion/pin-dyn-dispatch-sound.stderr @@ -0,0 +1,9 @@ +error[E0321]: cross-crate traits with a default impl, like `Unpin`, can only be implemented for a struct/enum type, not `(dyn MyUnpinTrait + 'static)` + --> $DIR/pin-dyn-dispatch-sound.rs:12:1 + | +LL | impl Unpin for dyn MyUnpinTrait {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't implement cross-crate trait with a default impl for non-struct/enum type + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0321`. From eea00ca354855e546a1f3626c215571a5afa9e6c Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 13 May 2024 15:04:10 +0200 Subject: [PATCH 152/179] Add `target` method to `Rustdoc` type --- src/tools/run-make-support/src/rustdoc.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/tools/run-make-support/src/rustdoc.rs b/src/tools/run-make-support/src/rustdoc.rs index 75ca1fc29747f..fa8521ed9194b 100644 --- a/src/tools/run-make-support/src/rustdoc.rs +++ b/src/tools/run-make-support/src/rustdoc.rs @@ -123,6 +123,12 @@ impl Rustdoc { self } + /// Specify the target triple, or a path to a custom target json spec file. + pub fn target(&mut self, target: &str) -> &mut Self { + self.cmd.arg(format!("--target={target}")); + self + } + /// Specify the crate type. pub fn crate_type(&mut self, crate_type: &str) -> &mut Self { self.cmd.arg("--crate-type"); From 4057a7b1e3fd1a1371b5dda1fa4323c6d3426b39 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 13 May 2024 15:12:42 +0200 Subject: [PATCH 153/179] Add `library_search_path` to `Rustdoc` --- src/tools/run-make-support/src/rustdoc.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/tools/run-make-support/src/rustdoc.rs b/src/tools/run-make-support/src/rustdoc.rs index fa8521ed9194b..c4f4e9f9bd23b 100644 --- a/src/tools/run-make-support/src/rustdoc.rs +++ b/src/tools/run-make-support/src/rustdoc.rs @@ -143,6 +143,14 @@ impl Rustdoc { self } + /// Add a directory to the library search path. It corresponds to the `-L` + /// rustdoc option. + pub fn library_search_path>(&mut self, path: P) -> &mut Self { + self.cmd.arg("-L"); + self.cmd.arg(path.as_ref()); + self + } + #[track_caller] pub fn run_fail_assert_exit_code(&mut self, code: i32) -> Output { let caller_location = std::panic::Location::caller(); From b515de83af4fd73255de0a1ebb48db5849f8e01f Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 13 May 2024 15:04:36 +0200 Subject: [PATCH 154/179] Migrate `run-make/rustdoc-target-spec-json-path` to rmake --- src/tools/tidy/src/allowed_run_make_makefiles.txt | 1 - .../rustdoc-target-spec-json-path/Makefile | 9 --------- .../rustdoc-target-spec-json-path/rmake.rs | 14 ++++++++++++++ 3 files changed, 14 insertions(+), 10 deletions(-) delete mode 100644 tests/run-make/rustdoc-target-spec-json-path/Makefile create mode 100644 tests/run-make/rustdoc-target-spec-json-path/rmake.rs diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index d742368292035..5f385280ac5ac 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -251,7 +251,6 @@ run-make/rustdoc-scrape-examples-multiple/Makefile run-make/rustdoc-scrape-examples-remap/Makefile run-make/rustdoc-scrape-examples-test/Makefile run-make/rustdoc-scrape-examples-whitespace/Makefile -run-make/rustdoc-target-spec-json-path/Makefile run-make/rustdoc-themes/Makefile run-make/rustdoc-verify-output-files/Makefile run-make/rustdoc-with-out-dir-option/Makefile diff --git a/tests/run-make/rustdoc-target-spec-json-path/Makefile b/tests/run-make/rustdoc-target-spec-json-path/Makefile deleted file mode 100644 index 6d0bc4186f229..0000000000000 --- a/tests/run-make/rustdoc-target-spec-json-path/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -include ../tools.mk - -# Test that rustdoc will properly canonicalize the target spec json path just like rustc - -OUTPUT_DIR := "$(TMPDIR)/rustdoc-target-spec-json-path" - -all: - $(RUSTC) --crate-type lib dummy_core.rs --target target.json - $(RUSTDOC) -o $(OUTPUT_DIR) -L $(TMPDIR) my_crate.rs --target target.json diff --git a/tests/run-make/rustdoc-target-spec-json-path/rmake.rs b/tests/run-make/rustdoc-target-spec-json-path/rmake.rs new file mode 100644 index 0000000000000..66530a4f08ee9 --- /dev/null +++ b/tests/run-make/rustdoc-target-spec-json-path/rmake.rs @@ -0,0 +1,14 @@ +// Test that rustdoc will properly canonicalize the target spec json path just like rustc. + +use run_make_support::{rustc, rustdoc, tmp_dir}; + +fn main() { + let out_dir = tmp_dir().join("rustdoc-target-spec-json-path"); + rustc().crate_type("lib").input("dummy_core.rs").target("target.json").run(); + rustdoc() + .input("my_crate.rs") + .output(out_dir) + .library_search_path(tmp_dir()) + .target("target.json") + .run(); +} From 3270432f4b0583104c8b9b6f695bf97d6bbf3ac2 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Mon, 13 May 2024 13:22:02 +0000 Subject: [PATCH 155/179] Rustup to rustc 1.80.0-nightly (ef0027897 2024-05-12) --- rust-toolchain | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-toolchain b/rust-toolchain index 18f88fab9c8da..a2ba79cbe9038 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2024-05-11" +channel = "nightly-2024-05-13" components = ["rust-src", "rustc-dev", "llvm-tools"] From 3742a4bd902f5d6efd2b401a6dab5e4087070d5d Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Tue, 2 Jan 2024 04:59:24 -0800 Subject: [PATCH 156/179] style-guide: Format single associated type `where` clauses on the same line In particular, lifetime-generic associated types often have a `where Self: 'a` bound, which we can format on the same line. --- src/doc/style-guide/src/editions.md | 1 + src/doc/style-guide/src/items.md | 13 ++++++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/doc/style-guide/src/editions.md b/src/doc/style-guide/src/editions.md index b9a89c20cee40..9d593f8081025 100644 --- a/src/doc/style-guide/src/editions.md +++ b/src/doc/style-guide/src/editions.md @@ -43,6 +43,7 @@ include: - Miscellaneous `rustfmt` bugfixes. - Use version-sort (sort `x8`, `x16`, `x32`, `x64`, `x128` in that order). - Change "ASCIIbetical" sort to Unicode-aware "non-lowercase before lowercase". +- Format single associated type `where` clauses on the same line if they fit. ## Rust 2015/2018/2021 style edition diff --git a/src/doc/style-guide/src/items.md b/src/doc/style-guide/src/items.md index 0066a4bacb956..06bac12987191 100644 --- a/src/doc/style-guide/src/items.md +++ b/src/doc/style-guide/src/items.md @@ -421,9 +421,20 @@ Format associated types like type aliases. Where an associated type has a bound, put a space after the colon but not before: ```rust -pub type Foo: Bar; +type Foo: Bar; ``` +If an associated type has no `=`, and has a `where` clause with only one entry, +format the entire type declaration including the `where` clause on the same +line if it fits: + +```rust +type Item<'a> where Self: 'a; +``` + +If the associated type has a `=`, or if the `where` clause contains multiple +entries, format it across multiple lines as with a type alias. + ## extern items When writing extern items (such as `extern "C" fn`), always specify the ABI. From 2f20bb4a976e7dbd11c5329b48a2d402ff81fca9 Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Wed, 10 Jan 2024 19:11:17 -0800 Subject: [PATCH 157/179] style-guide: Give a second example for associated type formatting Show an example that has bounds. --- src/doc/style-guide/src/items.md | 1 + 1 file changed, 1 insertion(+) diff --git a/src/doc/style-guide/src/items.md b/src/doc/style-guide/src/items.md index 06bac12987191..718180191895a 100644 --- a/src/doc/style-guide/src/items.md +++ b/src/doc/style-guide/src/items.md @@ -430,6 +430,7 @@ line if it fits: ```rust type Item<'a> where Self: 'a; +type Item<'a>: PartialEq + Send where Self: 'a; ``` If the associated type has a `=`, or if the `where` clause contains multiple From 2af29af710aa4613e4ff670e5902d7ea6725988f Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Wed, 10 Jan 2024 19:13:15 -0800 Subject: [PATCH 158/179] style-guide: Not all where clauses can be written as inline bounds --- src/doc/style-guide/src/items.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/style-guide/src/items.md b/src/doc/style-guide/src/items.md index 718180191895a..095e5512ea923 100644 --- a/src/doc/style-guide/src/items.md +++ b/src/doc/style-guide/src/items.md @@ -347,7 +347,7 @@ where ``` If a `where` clause is very short, prefer using an inline bound on the type -parameter. +parameter if possible. If a component of a `where` clause does not fit and contains `+`, break it before each `+` and block-indent the continuation lines. Put each bound on its From 9ff777bf50cb26107496c1bfdd178c56c5a57cca Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Wed, 10 Jan 2024 19:21:27 -0800 Subject: [PATCH 159/179] style-guide: Also format where clauses on one line for short function decls --- src/doc/style-guide/src/items.md | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/src/doc/style-guide/src/items.md b/src/doc/style-guide/src/items.md index 095e5512ea923..9b8cdaed88bee 100644 --- a/src/doc/style-guide/src/items.md +++ b/src/doc/style-guide/src/items.md @@ -295,8 +295,18 @@ Prefer to use single-letter names for generic parameters. These rules apply for `where` clauses on any item. -If immediately following a closing bracket of any kind, write the keyword -`where` on the same line, with a space before it. +If a where clause is short, and appears on a short one-line function +declaration with no body or a short associated type with no `=`, format it on +the same line as the declaration: + +```rust +fn new(&self) -> Self where Self: Sized; + +type Item<'a>: SomeTrait where Self: 'a; +``` + +Otherwise, if immediately following a closing bracket of any kind, write the +keyword `where` on the same line, with a space before it. Otherwise, put `where` on a new line at the same indentation level. Put each component of a `where` clause on its own line, block-indented. Use a trailing @@ -424,9 +434,9 @@ bound, put a space after the colon but not before: type Foo: Bar; ``` -If an associated type has no `=`, and has a `where` clause with only one entry, -format the entire type declaration including the `where` clause on the same -line if it fits: +If an associated type is short, has no `=`, and has a `where` clause with only +one entry, format the entire type declaration including the `where` clause on +the same line if it fits: ```rust type Item<'a> where Self: 'a; From 163b1a66152faffb5543f5a7ed5d80251f4d466c Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Wed, 24 Jan 2024 12:48:11 -0800 Subject: [PATCH 160/179] Reword formatting for where clauses Suggested-by: Caleb Cartwright --- src/doc/style-guide/src/items.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/style-guide/src/items.md b/src/doc/style-guide/src/items.md index 9b8cdaed88bee..c0628691b7734 100644 --- a/src/doc/style-guide/src/items.md +++ b/src/doc/style-guide/src/items.md @@ -296,7 +296,7 @@ Prefer to use single-letter names for generic parameters. These rules apply for `where` clauses on any item. If a where clause is short, and appears on a short one-line function -declaration with no body or a short associated type with no `=`, format it on +declaration with no body or on a short type with no `=`, format it on the same line as the declaration: ```rust From 3bcdf3058ef3eaef5042661cf8301acfbcddce65 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 13 May 2024 10:00:38 -0400 Subject: [PATCH 161/179] split out AliasTy -> AliasTerm --- .../src/diagnostics/region_name.rs | 3 +- .../src/check/compare_impl_item.rs | 2 +- compiler/rustc_hir_analysis/src/check/mod.rs | 7 +- .../src/collect/item_bounds.rs | 2 +- .../src/collect/predicates_of.rs | 4 +- .../src/constrained_generic_params.rs | 4 +- .../src/hir_ty_lowering/bounds.rs | 16 +- .../src/hir_ty_lowering/errors.rs | 12 +- .../src/hir_ty_lowering/object_safety.rs | 6 +- .../src/impl_wf_check/min_specialization.rs | 16 +- .../rustc_hir_analysis/src/variance/mod.rs | 2 +- compiler/rustc_hir_typeck/src/callee.rs | 2 +- compiler/rustc_hir_typeck/src/closure.rs | 10 +- .../src/fn_ctxt/adjust_fulfillment_errors.rs | 2 +- .../src/fn_ctxt/inspect_obligations.rs | 2 +- .../rustc_hir_typeck/src/method/suggest.rs | 18 +- compiler/rustc_infer/src/infer/at.rs | 14 ++ .../src/infer/error_reporting/mod.rs | 2 +- compiler/rustc_infer/src/infer/mod.rs | 2 +- .../rustc_infer/src/infer/opaque_types/mod.rs | 2 +- compiler/rustc_infer/src/infer/projection.rs | 4 +- .../src/infer/relate/generalize.rs | 2 +- compiler/rustc_infer/src/traits/mod.rs | 2 +- compiler/rustc_infer/src/traits/project.rs | 18 +- .../src/opaque_hidden_inferred_bound.rs | 11 +- compiler/rustc_middle/src/ty/context.rs | 1 + compiler/rustc_middle/src/ty/flags.rs | 10 +- compiler/rustc_middle/src/ty/mod.rs | 16 +- compiler/rustc_middle/src/ty/predicate.rs | 6 +- compiler/rustc_middle/src/ty/print/pretty.rs | 38 +-- compiler/rustc_middle/src/ty/relate.rs | 28 +++ .../rustc_middle/src/ty/structural_impls.rs | 2 +- compiler/rustc_middle/src/ty/sty.rs | 231 +++++++++++++++--- compiler/rustc_middle/src/ty/util.rs | 2 +- .../src/shim/async_destructor_ctor.rs | 3 +- compiler/rustc_privacy/src/lib.rs | 11 +- .../rustc_smir/src/rustc_smir/convert/ty.rs | 14 +- .../src/solve/alias_relate.rs | 6 +- .../src/solve/assembly/structural_traits.rs | 8 +- .../src/solve/eval_ctxt/mod.rs | 10 +- .../src/solve/normalize.rs | 11 +- .../src/solve/normalizes_to/inherent.rs | 2 +- .../src/solve/normalizes_to/mod.rs | 35 +-- .../src/solve/project_goals.rs | 14 +- .../src/traits/auto_trait.rs | 12 +- .../src/traits/coherence.rs | 4 +- .../src/traits/error_reporting/suggestions.rs | 24 +- .../error_reporting/type_err_ctxt_ext.rs | 46 ++-- .../src/traits/fulfill.rs | 4 +- .../rustc_trait_selection/src/traits/mod.rs | 2 +- .../src/traits/normalize.rs | 10 +- .../src/traits/object_safety.rs | 2 +- .../src/traits/project.rs | 151 +++++++----- .../src/traits/query/normalize.rs | 2 +- .../src/traits/select/candidate_assembly.rs | 2 +- .../src/traits/select/mod.rs | 10 +- .../rustc_trait_selection/src/traits/wf.rs | 41 +++- .../src/normalize_projection_ty.rs | 10 +- compiler/rustc_ty_utils/src/ty.rs | 2 +- compiler/rustc_type_ir/src/inherent.rs | 3 +- compiler/rustc_type_ir/src/interner.rs | 3 +- compiler/rustc_type_ir/src/lib.rs | 2 +- compiler/rustc_type_ir/src/predicate.rs | 56 ++++- compiler/rustc_type_ir/src/ty_kind.rs | 14 +- compiler/stable_mir/src/ty.rs | 8 +- src/librustdoc/clean/mod.rs | 33 ++- .../src/methods/unnecessary_to_owned.rs | 2 +- .../src/needless_borrows_for_generic_args.rs | 13 +- .../src/unit_return_expecting_ord.rs | 2 +- src/tools/clippy/clippy_utils/src/ty.rs | 4 +- 70 files changed, 688 insertions(+), 387 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/region_name.rs b/compiler/rustc_borrowck/src/diagnostics/region_name.rs index 28c5c505f7916..46011c1f43ec9 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_name.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_name.rs @@ -1010,7 +1010,8 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { clauses.iter().any(|pred| { match pred.kind().skip_binder() { ty::ClauseKind::Trait(data) if data.self_ty() == ty => {} - ty::ClauseKind::Projection(data) if data.projection_ty.self_ty() == ty => {} + ty::ClauseKind::Projection(data) + if data.projection_term.self_ty() == ty => {} _ => return false, } tcx.any_free_region_meets(pred, |r| *r == ty::ReEarlyParam(region)) diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index db223f9d80f39..0a6aa751ed7d1 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -2205,7 +2205,7 @@ fn param_env_with_gat_bounds<'tcx>( _ => predicates.push( ty::Binder::bind_with_vars( ty::ProjectionPredicate { - projection_ty: ty::AliasTy::new(tcx, trait_ty.def_id, rebased_args), + projection_term: ty::AliasTerm::new(tcx, trait_ty.def_id, rebased_args), term: normalize_impl_ty.into(), }, bound_vars, diff --git a/compiler/rustc_hir_analysis/src/check/mod.rs b/compiler/rustc_hir_analysis/src/check/mod.rs index eb0ffc19d4540..c7462a6ee49d4 100644 --- a/compiler/rustc_hir_analysis/src/check/mod.rs +++ b/compiler/rustc_hir_analysis/src/check/mod.rs @@ -343,9 +343,10 @@ fn bounds_from_generic_predicates<'tcx>( let mut projections_str = vec![]; for projection in &projections { let p = projection.skip_binder(); - let alias_ty = p.projection_ty; - if bound == tcx.parent(alias_ty.def_id) && alias_ty.self_ty() == ty { - let name = tcx.item_name(alias_ty.def_id); + if bound == tcx.parent(p.projection_term.def_id) + && p.projection_term.self_ty() == ty + { + let name = tcx.item_name(p.projection_term.def_id); projections_str.push(format!("{} = {}", name, p.term)); } } diff --git a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs index 02291cc603e13..67f578373e0b1 100644 --- a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs +++ b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs @@ -39,7 +39,7 @@ fn associated_type_bounds<'tcx>( let bounds_from_parent = trait_predicates.predicates.iter().copied().filter(|(pred, _)| { match pred.kind().skip_binder() { ty::ClauseKind::Trait(tr) => tr.self_ty() == item_ty, - ty::ClauseKind::Projection(proj) => proj.projection_ty.self_ty() == item_ty, + ty::ClauseKind::Projection(proj) => proj.projection_term.self_ty() == item_ty, ty::ClauseKind::TypeOutlives(outlives) => outlives.0 == item_ty, _ => false, } diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs index 7e82571d172f1..8948e60b6dc24 100644 --- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs @@ -445,7 +445,9 @@ pub(super) fn explicit_predicates_of<'tcx>( .copied() .filter(|(pred, _)| match pred.kind().skip_binder() { ty::ClauseKind::Trait(tr) => !is_assoc_item_ty(tr.self_ty()), - ty::ClauseKind::Projection(proj) => !is_assoc_item_ty(proj.projection_ty.self_ty()), + ty::ClauseKind::Projection(proj) => { + !is_assoc_item_ty(proj.projection_term.self_ty()) + } ty::ClauseKind::TypeOutlives(outlives) => !is_assoc_item_ty(outlives.0), _ => true, }) diff --git a/compiler/rustc_hir_analysis/src/constrained_generic_params.rs b/compiler/rustc_hir_analysis/src/constrained_generic_params.rs index 3b8bb0731fbd8..ccf0c7bf2c17d 100644 --- a/compiler/rustc_hir_analysis/src/constrained_generic_params.rs +++ b/compiler/rustc_hir_analysis/src/constrained_generic_params.rs @@ -197,7 +197,7 @@ pub fn setup_constraining_predicates<'tcx>( // Special case: watch out for some kind of sneaky attempt // to project out an associated type defined by this very // trait. - let unbound_trait_ref = projection.projection_ty.trait_ref(tcx); + let unbound_trait_ref = projection.projection_term.trait_ref(tcx); if Some(unbound_trait_ref) == impl_trait_ref { continue; } @@ -207,7 +207,7 @@ pub fn setup_constraining_predicates<'tcx>( // `<::Baz as Iterator>::Output = ::Output` // Then the projection only applies if `T` is known, but it still // does not determine `U`. - let inputs = parameters_for(tcx, projection.projection_ty, true); + let inputs = parameters_for(tcx, projection.projection_term, true); let relies_only_on_inputs = inputs.iter().all(|p| input_parameters.contains(p)); if !relies_only_on_inputs { continue; diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs index de12475678ca3..41e3abd7451f1 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs @@ -326,7 +326,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { }) .or_insert(binding.span); - let projection_ty = if let ty::AssocKind::Fn = assoc_kind { + let projection_term = if let ty::AssocKind::Fn = assoc_kind { let mut emitted_bad_param_err = None; // If we have an method return type bound, then we need to instantiate // the method's early bound params with suitable late-bound params. @@ -380,7 +380,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let output = if let ty::Alias(ty::Projection, alias_ty) = *output.skip_binder().kind() && tcx.is_impl_trait_in_trait(alias_ty.def_id) { - alias_ty + alias_ty.into() } else { return Err(tcx.dcx().emit_err(crate::errors::ReturnTypeNotationOnNonRpitit { span: binding.span, @@ -424,7 +424,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { // Note that we're indeed also using `AliasTy` (alias *type*) for associated // *constants* to represent *const projections*. Alias *term* would be a more // appropriate name but alas. - ty::AliasTy::new(tcx, assoc_item.def_id, alias_args) + ty::AliasTerm::new(tcx, assoc_item.def_id, alias_args) }); // Provide the resolved type of the associated constant to `type_of(AnonConst)`. @@ -461,7 +461,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { // for<'a> ::Item = &'a str // <-- 'a is bad // for<'a> >::Output = &'a str // <-- 'a is ok let late_bound_in_projection_ty = - tcx.collect_constrained_late_bound_regions(projection_ty); + tcx.collect_constrained_late_bound_regions(projection_term); let late_bound_in_term = tcx.collect_referenced_late_bound_regions(trait_ref.rebind(term)); debug!(?late_bound_in_projection_ty); @@ -490,8 +490,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { bounds.push_projection_bound( tcx, - projection_ty - .map_bound(|projection_ty| ty::ProjectionPredicate { projection_ty, term }), + projection_term.map_bound(|projection_term| ty::ProjectionPredicate { + projection_term, + term, + }), binding.span, ); } @@ -501,6 +503,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { // NOTE: If `only_self_bounds` is true, do NOT expand this associated type bound into // a trait predicate, since we only want to add predicates for the `Self` type. if !only_self_bounds.0 { + let projection_ty = projection_term + .map_bound(|projection_term| projection_term.expect_ty(self.tcx())); // Calling `skip_binder` is okay, because `lower_bounds` expects the `param_ty` // parameter to have a skipped binder. let param_ty = Ty::new_alias(tcx, ty::Projection, projection_ty.skip_binder()); diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs index 38dfa8d57d34b..8f68a670d01d3 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs @@ -627,23 +627,23 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { ty::PredicateKind::Clause(ty::ClauseKind::Projection(pred)) => { let pred = bound_predicate.rebind(pred); // `::Item = String`. - let projection_ty = pred.skip_binder().projection_ty; + let projection_term = pred.skip_binder().projection_term; let args_with_infer_self = tcx.mk_args_from_iter( std::iter::once(Ty::new_var(tcx, ty::TyVid::ZERO).into()) - .chain(projection_ty.args.iter().skip(1)), + .chain(projection_term.args.iter().skip(1)), ); let quiet_projection_ty = - ty::AliasTy::new(tcx, projection_ty.def_id, args_with_infer_self); + ty::AliasTerm::new(tcx, projection_term.def_id, args_with_infer_self); let term = pred.skip_binder().term; - let obligation = format!("{projection_ty} = {term}"); + let obligation = format!("{projection_term} = {term}"); let quiet = format!("{quiet_projection_ty} = {term}"); - bound_span_label(projection_ty.self_ty(), &obligation, &quiet); - Some((obligation, projection_ty.self_ty())) + bound_span_label(projection_term.self_ty(), &obligation, &quiet); + Some((obligation, projection_term.self_ty())) } ty::PredicateKind::Clause(ty::ClauseKind::Trait(poly_trait_ref)) => { let p = poly_trait_ref.trait_ref; diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/object_safety.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/object_safety.rs index 37d4d4ec35581..a64a7a2e5bd45 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/object_safety.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/object_safety.rs @@ -280,11 +280,11 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let existential_projections = projection_bounds.iter().map(|(bound, _)| { bound.map_bound(|mut b| { - assert_eq!(b.projection_ty.self_ty(), dummy_self); + assert_eq!(b.projection_term.self_ty(), dummy_self); // Like for trait refs, verify that `dummy_self` did not leak inside default type // parameters. - let references_self = b.projection_ty.args.iter().skip(1).any(|arg| { + let references_self = b.projection_term.args.iter().skip(1).any(|arg| { if arg.walk().any(|arg| arg == dummy_self.into()) { return true; } @@ -294,7 +294,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let guar = tcx .dcx() .span_delayed_bug(span, "trait object projection bounds reference `Self`"); - b.projection_ty = replace_dummy_self_with_error(tcx, b.projection_ty, guar); + b.projection_term = replace_dummy_self_with_error(tcx, b.projection_term, guar); } ty::ExistentialProjection::erase_self_ty(tcx, b) diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs index 6dd59a62a7a46..61357d6504c90 100644 --- a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs +++ b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs @@ -258,23 +258,23 @@ fn unconstrained_parent_impl_args<'tcx>( // unconstrained parameters. for (clause, _) in impl_generic_predicates.predicates.iter() { if let ty::ClauseKind::Projection(proj) = clause.kind().skip_binder() { - let projection_ty = proj.projection_ty; - let projected_ty = proj.term; + let projection_term = proj.projection_term; + let projected_term = proj.term; - let unbound_trait_ref = projection_ty.trait_ref(tcx); + let unbound_trait_ref = projection_term.trait_ref(tcx); if Some(unbound_trait_ref) == impl_trait_ref { continue; } - unconstrained_parameters.extend(cgp::parameters_for(tcx, projection_ty, true)); + unconstrained_parameters.extend(cgp::parameters_for(tcx, projection_term, true)); - for param in cgp::parameters_for(tcx, projected_ty, false) { + for param in cgp::parameters_for(tcx, projected_term, false) { if !unconstrained_parameters.contains(¶m) { constrained_params.insert(param.0); } } - unconstrained_parameters.extend(cgp::parameters_for(tcx, projected_ty, true)); + unconstrained_parameters.extend(cgp::parameters_for(tcx, projected_term, true)); } } @@ -495,11 +495,11 @@ fn check_specialization_on<'tcx>( .emit()) } } - ty::ClauseKind::Projection(ty::ProjectionPredicate { projection_ty, term }) => Err(tcx + ty::ClauseKind::Projection(ty::ProjectionPredicate { projection_term, term }) => Err(tcx .dcx() .struct_span_err( span, - format!("cannot specialize on associated type `{projection_ty} == {term}`",), + format!("cannot specialize on associated type `{projection_term} == {term}`",), ) .emit()), ty::ClauseKind::ConstArgHasType(..) => { diff --git a/compiler/rustc_hir_analysis/src/variance/mod.rs b/compiler/rustc_hir_analysis/src/variance/mod.rs index 27fdea01c2b27..cfc7ecf85802d 100644 --- a/compiler/rustc_hir_analysis/src/variance/mod.rs +++ b/compiler/rustc_hir_analysis/src/variance/mod.rs @@ -166,7 +166,7 @@ fn variance_of_opaque(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[ty::Varianc } } ty::ClauseKind::Projection(ty::ProjectionPredicate { - projection_ty: ty::AliasTy { args, .. }, + projection_term: ty::AliasTerm { args, .. }, term, }) => { for arg in &args[1..] { diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs index defb557867b79..fe2a335c016c0 100644 --- a/compiler/rustc_hir_typeck/src/callee.rs +++ b/compiler/rustc_hir_typeck/src/callee.rs @@ -574,7 +574,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.misc(span), self.param_env, ty::ProjectionPredicate { - projection_ty: ty::AliasTy::new( + projection_term: ty::AliasTerm::new( self.tcx, fn_once_output_def_id, [arg_ty.into(), fn_sig.inputs()[0].into(), const_param], diff --git a/compiler/rustc_hir_typeck/src/closure.rs b/compiler/rustc_hir_typeck/src/closure.rs index f52f95db6d342..4a308d85c8dd8 100644 --- a/compiler/rustc_hir_typeck/src/closure.rs +++ b/compiler/rustc_hir_typeck/src/closure.rs @@ -414,7 +414,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // many viable options, so pick the most restrictive. let trait_def_id = match bound_predicate.skip_binder() { ty::PredicateKind::Clause(ty::ClauseKind::Projection(data)) => { - Some(data.projection_ty.trait_def_id(self.tcx)) + Some(data.projection_term.trait_def_id(self.tcx)) } ty::PredicateKind::Clause(ty::ClauseKind::Trait(data)) => Some(data.def_id()), _ => None, @@ -475,7 +475,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { _ => return None, } - let arg_param_ty = projection.skip_binder().projection_ty.args.type_at(1); + let arg_param_ty = projection.skip_binder().projection_term.args.type_at(1); let arg_param_ty = self.resolve_vars_if_possible(arg_param_ty); debug!(?arg_param_ty); @@ -930,7 +930,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }; // Check that this is a projection from the `Future` trait. - let trait_def_id = predicate.projection_ty.trait_def_id(self.tcx); + let trait_def_id = predicate.projection_term.trait_def_id(self.tcx); let future_trait = self.tcx.require_lang_item(LangItem::Future, Some(cause_span)); if trait_def_id != future_trait { debug!("deduce_future_output_from_projection: not a future"); @@ -940,11 +940,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // The `Future` trait has only one associated item, `Output`, // so check that this is what we see. let output_assoc_item = self.tcx.associated_item_def_ids(future_trait)[0]; - if output_assoc_item != predicate.projection_ty.def_id { + if output_assoc_item != predicate.projection_term.def_id { span_bug!( cause_span, "projecting associated item `{:?}` from future, which is not Output `{:?}`", - predicate.projection_ty.def_id, + predicate.projection_term.def_id, output_assoc_item, ); } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs index c3525f175da8e..4edc11d7ab15b 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs @@ -37,7 +37,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ty::ClauseKind::Trait(pred) => { (pred.trait_ref.args.to_vec(), Some(pred.self_ty().into())) } - ty::ClauseKind::Projection(pred) => (pred.projection_ty.args.to_vec(), None), + ty::ClauseKind::Projection(pred) => (pred.projection_term.args.to_vec(), None), ty::ClauseKind::ConstArgHasType(arg, ty) => (vec![ty.into(), arg.into()], None), ty::ClauseKind::ConstEvaluatable(e) => (vec![e.into()], None), _ => return false, diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/inspect_obligations.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/inspect_obligations.rs index 2ef254f644f73..ac1e26df87076 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/inspect_obligations.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/inspect_obligations.rs @@ -38,7 +38,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.type_matches_expected_vid(expected_vid, data.self_ty()) } ty::PredicateKind::Clause(ty::ClauseKind::Projection(data)) => { - self.type_matches_expected_vid(expected_vid, data.projection_ty.self_ty()) + self.type_matches_expected_vid(expected_vid, data.projection_term.self_ty()) } ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(..)) | ty::PredicateKind::Subtype(..) diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 0483bd0357675..6d931d15008a6 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -172,7 +172,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } } - ty::Slice(..) | ty::Adt(..) | ty::Alias(ty::AliasKind::Opaque, _) => { + ty::Slice(..) | ty::Adt(..) | ty::Alias(ty::Opaque, _) => { for unsatisfied in unsatisfied_predicates.iter() { if is_iterator_predicate(unsatisfied.0, self.tcx) { return true; @@ -787,26 +787,26 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ty::PredicateKind::Clause(ty::ClauseKind::Projection(pred)) => { let pred = bound_predicate.rebind(pred); // `::Item = String`. - let projection_ty = pred.skip_binder().projection_ty; + let projection_term = pred.skip_binder().projection_term; let args_with_infer_self = tcx.mk_args_from_iter( iter::once(Ty::new_var(tcx, ty::TyVid::ZERO).into()) - .chain(projection_ty.args.iter().skip(1)), + .chain(projection_term.args.iter().skip(1)), ); - let quiet_projection_ty = - ty::AliasTy::new(tcx, projection_ty.def_id, args_with_infer_self); + let quiet_projection_term = + ty::AliasTerm::new(tcx, projection_term.def_id, args_with_infer_self); let term = pred.skip_binder().term; - let obligation = format!("{projection_ty} = {term}"); + let obligation = format!("{projection_term} = {term}"); let quiet = with_forced_trimmed_paths!(format!( "{} = {}", - quiet_projection_ty, term + quiet_projection_term, term )); - bound_span_label(projection_ty.self_ty(), &obligation, &quiet); - Some((obligation, projection_ty.self_ty())) + bound_span_label(projection_term.self_ty(), &obligation, &quiet); + Some((obligation, projection_term.self_ty())) } ty::PredicateKind::Clause(ty::ClauseKind::Trait(poly_trait_ref)) => { let p = poly_trait_ref.trait_ref; diff --git a/compiler/rustc_infer/src/infer/at.rs b/compiler/rustc_infer/src/infer/at.rs index 0f21d3966c40b..830d472e1b837 100644 --- a/compiler/rustc_infer/src/infer/at.rs +++ b/compiler/rustc_infer/src/infer/at.rs @@ -430,6 +430,20 @@ impl<'tcx> ToTrace<'tcx> for ty::TraitRef<'tcx> { } impl<'tcx> ToTrace<'tcx> for ty::AliasTy<'tcx> { + fn to_trace( + cause: &ObligationCause<'tcx>, + a_is_expected: bool, + a: Self, + b: Self, + ) -> TypeTrace<'tcx> { + TypeTrace { + cause: cause.clone(), + values: Aliases(ExpectedFound::new(a_is_expected, a.into(), b.into())), + } + } +} + +impl<'tcx> ToTrace<'tcx> for ty::AliasTerm<'tcx> { fn to_trace( cause: &ObligationCause<'tcx>, a_is_expected: bool, diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 3488517a4ef9b..f17bc2f0ae159 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -410,7 +410,7 @@ impl<'tcx> InferCtxt<'tcx> { .kind() .map_bound(|kind| match kind { ty::ClauseKind::Projection(projection_predicate) - if projection_predicate.projection_ty.def_id == item_def_id => + if projection_predicate.projection_term.def_id == item_def_id => { projection_predicate.term.ty() } diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index ce82296a8aadd..0a7f2369a8332 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -403,7 +403,7 @@ impl<'tcx> ty::InferCtxtLike for InferCtxt<'tcx> { pub enum ValuePairs<'tcx> { Regions(ExpectedFound>), Terms(ExpectedFound>), - Aliases(ExpectedFound>), + Aliases(ExpectedFound>), TraitRefs(ExpectedFound>), PolySigs(ExpectedFound>), ExistentialTraitRef(ExpectedFound>), diff --git a/compiler/rustc_infer/src/infer/opaque_types/mod.rs b/compiler/rustc_infer/src/infer/opaque_types/mod.rs index 703bd5ae90b7d..8eb3185673b4a 100644 --- a/compiler/rustc_infer/src/infer/opaque_types/mod.rs +++ b/compiler/rustc_infer/src/infer/opaque_types/mod.rs @@ -588,7 +588,7 @@ impl<'tcx> InferCtxt<'tcx> { && !tcx.is_impl_trait_in_trait(projection_ty.def_id) && !self.next_trait_solver() => { - self.infer_projection( + self.projection_ty_to_infer( param_env, projection_ty, cause.clone(), diff --git a/compiler/rustc_infer/src/infer/projection.rs b/compiler/rustc_infer/src/infer/projection.rs index 041838ffc1693..1678634798064 100644 --- a/compiler/rustc_infer/src/infer/projection.rs +++ b/compiler/rustc_infer/src/infer/projection.rs @@ -12,7 +12,7 @@ impl<'tcx> InferCtxt<'tcx> { /// of the given projection. This allows us to proceed with projections /// while they cannot be resolved yet due to missing information or /// simply due to the lack of access to the trait resolution machinery. - pub fn infer_projection( + pub fn projection_ty_to_infer( &self, param_env: ty::ParamEnv<'tcx>, projection_ty: ty::AliasTy<'tcx>, @@ -24,7 +24,7 @@ impl<'tcx> InferCtxt<'tcx> { let def_id = projection_ty.def_id; let ty_var = self.next_ty_var(self.tcx.def_span(def_id)); let projection = ty::Binder::dummy(ty::PredicateKind::Clause(ty::ClauseKind::Projection( - ty::ProjectionPredicate { projection_ty, term: ty_var.into() }, + ty::ProjectionPredicate { projection_term: projection_ty.into(), term: ty_var.into() }, ))); let obligation = Obligation::with_depth(self.tcx, cause, recursion_depth, param_env, projection); diff --git a/compiler/rustc_infer/src/infer/relate/generalize.rs b/compiler/rustc_infer/src/infer/relate/generalize.rs index 5880ca788bce9..e7ed2fe9b4942 100644 --- a/compiler/rustc_infer/src/infer/relate/generalize.rs +++ b/compiler/rustc_infer/src/infer/relate/generalize.rs @@ -101,7 +101,7 @@ impl<'tcx> InferCtxt<'tcx> { // instead create a new inference variable `?normalized_source`, emitting // `Projection(normalized_source, ?ty_normalized)` and `?normalized_source <: generalized_ty`. relation.register_predicates([ty::ProjectionPredicate { - projection_ty: data, + projection_term: data.into(), term: generalized_ty.into(), }]); } diff --git a/compiler/rustc_infer/src/traits/mod.rs b/compiler/rustc_infer/src/traits/mod.rs index 85510cf2dcceb..f77a92bf9bc3a 100644 --- a/compiler/rustc_infer/src/traits/mod.rs +++ b/compiler/rustc_infer/src/traits/mod.rs @@ -27,7 +27,7 @@ pub use self::engine::{TraitEngine, TraitEngineExt}; pub use self::project::MismatchedProjectionTypes; pub(crate) use self::project::UndoLog; pub use self::project::{ - Normalized, NormalizedTy, ProjectionCache, ProjectionCacheEntry, ProjectionCacheKey, + Normalized, NormalizedTerm, ProjectionCache, ProjectionCacheEntry, ProjectionCacheKey, ProjectionCacheStorage, Reveal, }; pub use rustc_middle::traits::*; diff --git a/compiler/rustc_infer/src/traits/project.rs b/compiler/rustc_infer/src/traits/project.rs index c6ffba59638e3..c1cfa5ca6b7c8 100644 --- a/compiler/rustc_infer/src/traits/project.rs +++ b/compiler/rustc_infer/src/traits/project.rs @@ -8,7 +8,7 @@ use rustc_data_structures::{ snapshot_map::{self, SnapshotMapRef, SnapshotMapStorage}, undo_log::Rollback, }; -use rustc_middle::ty::{self, Ty}; +use rustc_middle::ty; pub use rustc_middle::traits::{EvaluationResult, Reveal}; @@ -26,7 +26,7 @@ pub struct Normalized<'tcx, T> { pub obligations: Vec>, } -pub type NormalizedTy<'tcx> = Normalized<'tcx, Ty<'tcx>>; +pub type NormalizedTerm<'tcx> = Normalized<'tcx, ty::Term<'tcx>>; impl<'tcx, T> Normalized<'tcx, T> { pub fn with(self, value: U) -> Normalized<'tcx, U> { @@ -77,13 +77,13 @@ pub struct ProjectionCacheStorage<'tcx> { #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)] pub struct ProjectionCacheKey<'tcx> { - ty: ty::AliasTy<'tcx>, + term: ty::AliasTerm<'tcx>, param_env: ty::ParamEnv<'tcx>, } impl<'tcx> ProjectionCacheKey<'tcx> { - pub fn new(ty: ty::AliasTy<'tcx>, param_env: ty::ParamEnv<'tcx>) -> Self { - Self { ty, param_env } + pub fn new(term: ty::AliasTerm<'tcx>, param_env: ty::ParamEnv<'tcx>) -> Self { + Self { term, param_env } } } @@ -94,7 +94,7 @@ pub enum ProjectionCacheEntry<'tcx> { Recur, Error, NormalizedTy { - ty: Normalized<'tcx, ty::Term<'tcx>>, + ty: NormalizedTerm<'tcx>, /// If we were able to successfully evaluate the /// corresponding cache entry key during predicate /// evaluation, then this field stores the final @@ -175,11 +175,7 @@ impl<'tcx> ProjectionCache<'_, 'tcx> { } /// Indicates that `key` was normalized to `value`. - pub fn insert_term( - &mut self, - key: ProjectionCacheKey<'tcx>, - value: Normalized<'tcx, ty::Term<'tcx>>, - ) { + pub fn insert_term(&mut self, key: ProjectionCacheKey<'tcx>, value: NormalizedTerm<'tcx>) { debug!( "ProjectionCacheEntry::insert_ty: adding cache entry: key={:?}, value={:?}", key, value diff --git a/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs b/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs index 1d2e12ec575b3..eda40e4a011a6 100644 --- a/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs +++ b/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs @@ -107,8 +107,11 @@ impl<'tcx> LateLintPass<'tcx> for OpaqueHiddenInferredBound { return; } - let proj_ty = - Ty::new_projection(cx.tcx, proj.projection_ty.def_id, proj.projection_ty.args); + let proj_ty = Ty::new_projection( + cx.tcx, + proj.projection_term.def_id, + proj.projection_term.args, + ); // For every instance of the projection type in the bounds, // replace them with the term we're assigning to the associated // type in our opaque type. @@ -123,8 +126,8 @@ impl<'tcx> LateLintPass<'tcx> for OpaqueHiddenInferredBound { // with `impl Send: OtherTrait`. for (assoc_pred, assoc_pred_span) in cx .tcx - .explicit_item_bounds(proj.projection_ty.def_id) - .iter_instantiated_copied(cx.tcx, proj.projection_ty.args) + .explicit_item_bounds(proj.projection_term.def_id) + .iter_instantiated_copied(cx.tcx, proj.projection_term.args) { let assoc_pred = assoc_pred.fold_with(proj_replacer); let Ok(assoc_pred) = traits::fully_normalize( diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index f9d1a77c3d960..e831db1a41bf8 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -132,6 +132,7 @@ impl<'tcx> Interner for TyCtxt<'tcx> { type RegionOutlivesPredicate = ty::RegionOutlivesPredicate<'tcx>; type TypeOutlivesPredicate = ty::TypeOutlivesPredicate<'tcx>; type ProjectionPredicate = ty::ProjectionPredicate<'tcx>; + type AliasTerm = ty::AliasTerm<'tcx>; type NormalizesTo = ty::NormalizesTo<'tcx>; type SubtypePredicate = ty::SubtypePredicate<'tcx>; type CoercePredicate = ty::CoercePredicate<'tcx>; diff --git a/compiler/rustc_middle/src/ty/flags.rs b/compiler/rustc_middle/src/ty/flags.rs index 0dc835671d56b..4de7d532c967c 100644 --- a/compiler/rustc_middle/src/ty/flags.rs +++ b/compiler/rustc_middle/src/ty/flags.rs @@ -294,10 +294,10 @@ impl FlagComputation { self.add_ty(b); } ty::PredicateKind::Clause(ty::ClauseKind::Projection(ty::ProjectionPredicate { - projection_ty, + projection_term, term, })) => { - self.add_alias_ty(projection_ty); + self.add_alias_term(projection_term); self.add_term(term); } ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(arg)) => { @@ -313,7 +313,7 @@ impl FlagComputation { } ty::PredicateKind::Ambiguous => {} ty::PredicateKind::NormalizesTo(ty::NormalizesTo { alias, term }) => { - self.add_alias_ty(alias); + self.add_alias_term(alias); self.add_term(term); } ty::PredicateKind::AliasRelate(t1, t2, _) => { @@ -410,6 +410,10 @@ impl FlagComputation { self.add_args(alias_ty.args); } + fn add_alias_term(&mut self, alias_term: ty::AliasTerm<'_>) { + self.add_args(alias_term.args); + } + fn add_args(&mut self, args: &[GenericArg<'_>]) { for kind in args { match kind.unpack() { diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 4d3b92bf2affd..02f6f4da4f169 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -110,11 +110,11 @@ pub use self::region::{ }; pub use self::rvalue_scopes::RvalueScopes; pub use self::sty::{ - AliasTy, Article, Binder, BoundTy, BoundTyKind, BoundVariableKind, CanonicalPolyFnSig, - ClosureArgs, ClosureArgsParts, CoroutineArgs, CoroutineArgsParts, CoroutineClosureArgs, - CoroutineClosureArgsParts, CoroutineClosureSignature, FnSig, GenSig, InlineConstArgs, - InlineConstArgsParts, ParamConst, ParamTy, PolyFnSig, TyKind, TypeAndMut, UpvarArgs, - VarianceDiagInfo, + AliasTerm, AliasTy, Article, Binder, BoundTy, BoundTyKind, BoundVariableKind, + CanonicalPolyFnSig, ClosureArgs, ClosureArgsParts, CoroutineArgs, CoroutineArgsParts, + CoroutineClosureArgs, CoroutineClosureArgsParts, CoroutineClosureSignature, FnSig, GenSig, + InlineConstArgs, InlineConstArgsParts, ParamConst, ParamTy, PolyFnSig, TyKind, TypeAndMut, + UpvarArgs, VarianceDiagInfo, }; pub use self::trait_def::TraitDef; pub use self::typeck_results::{ @@ -630,14 +630,14 @@ impl<'tcx> Term<'tcx> { } /// This function returns the inner `AliasTy` for a `ty::Alias` or `ConstKind::Unevaluated`. - pub fn to_alias_ty(&self, tcx: TyCtxt<'tcx>) -> Option> { + pub fn to_alias_term(self) -> Option> { match self.unpack() { TermKind::Ty(ty) => match *ty.kind() { - ty::Alias(_kind, alias_ty) => Some(alias_ty), + ty::Alias(_kind, alias_ty) => Some(alias_ty.into()), _ => None, }, TermKind::Const(ct) => match ct.kind() { - ConstKind::Unevaluated(uv) => Some(AliasTy::new(tcx, uv.def, uv.args)), + ConstKind::Unevaluated(uv) => Some(uv.into()), _ => None, }, } diff --git a/compiler/rustc_middle/src/ty/predicate.rs b/compiler/rustc_middle/src/ty/predicate.rs index c1de23b249864..e78856517b217 100644 --- a/compiler/rustc_middle/src/ty/predicate.rs +++ b/compiler/rustc_middle/src/ty/predicate.rs @@ -503,7 +503,7 @@ impl<'tcx> PolyProjectionPredicate<'tcx> { /// Returns the `DefId` of the trait of the associated item being projected. #[inline] pub fn trait_def_id(&self, tcx: TyCtxt<'tcx>) -> DefId { - self.skip_binder().projection_ty.trait_def_id(tcx) + self.skip_binder().projection_term.trait_def_id(tcx) } /// Get the [PolyTraitRef] required for this projection to be well formed. @@ -516,7 +516,7 @@ impl<'tcx> PolyProjectionPredicate<'tcx> { // This is because here `self` has a `Binder` and so does our // return value, so we are preserving the number of binding // levels. - self.map_bound(|predicate| predicate.projection_ty.trait_ref(tcx)) + self.map_bound(|predicate| predicate.projection_term.trait_ref(tcx)) } pub fn term(&self) -> Binder<'tcx, Term<'tcx>> { @@ -529,7 +529,7 @@ impl<'tcx> PolyProjectionPredicate<'tcx> { /// associated type, which is in `tcx.associated_item(projection_def_id()).container`. pub fn projection_def_id(&self) -> DefId { // Ok to skip binder since trait `DefId` does not care about regions. - self.skip_binder().projection_ty.def_id + self.skip_binder().projection_term.def_id } } diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index be9525a083ce5..edd5bef33d5ec 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -1277,7 +1277,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { fn pretty_print_inherent_projection( &mut self, - alias_ty: ty::AliasTy<'tcx>, + alias_ty: ty::AliasTerm<'tcx>, ) -> Result<(), PrintError> { let def_key = self.tcx().def_key(alias_ty.def_id); self.path_generic_args( @@ -3111,7 +3111,7 @@ define_print! { } ty::ProjectionPredicate<'tcx> { - p!(print(self.projection_ty), " == "); + p!(print(self.projection_term), " == "); cx.reset_type_limit(); p!(print(self.term)) } @@ -3206,20 +3206,28 @@ define_print_and_forward_display! { } ty::AliasTy<'tcx> { - if let DefKind::Impl { of_trait: false } = cx.tcx().def_kind(cx.tcx().parent(self.def_id)) { - p!(pretty_print_inherent_projection(*self)) - } else { - // If we're printing verbosely, or don't want to invoke queries - // (`is_impl_trait_in_trait`), then fall back to printing the def path. - // This is likely what you want if you're debugging the compiler anyways. - if !(cx.should_print_verbose() || with_reduced_queries()) - && cx.tcx().is_impl_trait_in_trait(self.def_id) - { - return cx.pretty_print_opaque_impl_type(self.def_id, self.args); - } else { - p!(print_def_path(self.def_id, self.args)); + let alias_term: ty::AliasTerm<'tcx> = (*self).into(); + p!(print(alias_term)) + } + + ty::AliasTerm<'tcx> { + match self.kind(cx.tcx()) { + ty::AliasTermKind::InherentTy => p!(pretty_print_inherent_projection(*self)), + ty::AliasTermKind::ProjectionTy + | ty::AliasTermKind::WeakTy + | ty::AliasTermKind::OpaqueTy + | ty::AliasTermKind::UnevaluatedConst => { + // If we're printing verbosely, or don't want to invoke queries + // (`is_impl_trait_in_trait`), then fall back to printing the def path. + // This is likely what you want if you're debugging the compiler anyways. + if !(cx.should_print_verbose() || with_reduced_queries()) + && cx.tcx().is_impl_trait_in_trait(self.def_id) + { + return cx.pretty_print_opaque_impl_type(self.def_id, self.args); + } else { + p!(print_def_path(self.def_id, self.args)); + } } - } } diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs index 417edda10caeb..32d420f96a210 100644 --- a/compiler/rustc_middle/src/ty/relate.rs +++ b/compiler/rustc_middle/src/ty/relate.rs @@ -246,6 +246,34 @@ impl<'tcx> Relate<'tcx> for ty::AliasTy<'tcx> { } } +impl<'tcx> Relate<'tcx> for ty::AliasTerm<'tcx> { + fn relate>( + relation: &mut R, + a: ty::AliasTerm<'tcx>, + b: ty::AliasTerm<'tcx>, + ) -> RelateResult<'tcx, ty::AliasTerm<'tcx>> { + if a.def_id != b.def_id { + Err(TypeError::ProjectionMismatched(expected_found(a.def_id, b.def_id))) + } else { + let args = match relation.tcx().def_kind(a.def_id) { + DefKind::OpaqueTy => relate_args_with_variances( + relation, + a.def_id, + relation.tcx().variances_of(a.def_id), + a.args, + b.args, + false, // do not fetch `type_of(a_def_id)`, as it will cause a cycle + )?, + DefKind::AssocTy | DefKind::AssocConst | DefKind::TyAlias => { + relate_args_invariantly(relation, a.args, b.args)? + } + def => bug!("unknown alias DefKind: {def:?}"), + }; + Ok(ty::AliasTerm::new(relation.tcx(), a.def_id, args)) + } + } +} + impl<'tcx> Relate<'tcx> for ty::ExistentialProjection<'tcx> { fn relate>( relation: &mut R, diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index dc071b295aad3..6abd685343b3a 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -410,7 +410,7 @@ TrivialTypeTraversalImpls! { crate::ty::BoundRegionKind, crate::ty::AssocItem, crate::ty::AssocKind, - crate::ty::AliasKind, + crate::ty::AliasTyKind, crate::ty::Placeholder, crate::ty::Placeholder, crate::ty::Placeholder, diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 1fc8eefd65fb1..7aca09c5cfbcb 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -22,7 +22,7 @@ use rustc_span::symbol::{sym, Symbol}; use rustc_span::{Span, DUMMY_SP}; use rustc_target::abi::{FieldIdx, VariantIdx, FIRST_VARIANT}; use rustc_target::spec::abi::{self, Abi}; -use std::assert_matches::debug_assert_matches; +use std::assert_matches::{assert_matches, debug_assert_matches}; use std::borrow::Cow; use std::iter; use std::ops::{ControlFlow, Deref, Range}; @@ -1105,14 +1105,14 @@ where } } -/// Represents the projection of an associated type. +/// Represents the unprojected term of a projection goal. /// /// * For a projection, this would be `>::N<...>`. /// * For an inherent projection, this would be `Ty::N<...>`. /// * For an opaque type, there is no explicit syntax. #[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable)] #[derive(HashStable, TypeFoldable, TypeVisitable, Lift)] -pub struct AliasTy<'tcx> { +pub struct AliasTerm<'tcx> { /// The parameters of the associated or opaque item. /// /// For a projection, these are the generic parameters for the trait and the @@ -1139,16 +1139,35 @@ pub struct AliasTy<'tcx> { /// This field exists to prevent the creation of `AliasTy` without using /// [AliasTy::new]. - _use_alias_ty_new_instead: (), + _use_alias_term_new_instead: (), } -impl<'tcx> rustc_type_ir::inherent::AliasTy> for AliasTy<'tcx> { +// FIXME: Remove these when we uplift `AliasTerm` +use crate::ty::{DebugWithInfcx, InferCtxtLike, WithInfcx}; +impl<'tcx> std::fmt::Debug for AliasTerm<'tcx> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + WithInfcx::with_no_infcx(self).fmt(f) + } +} +impl<'tcx> DebugWithInfcx> for AliasTerm<'tcx> { + fn fmt>>( + this: WithInfcx<'_, Infcx, &Self>, + f: &mut std::fmt::Formatter<'_>, + ) -> std::fmt::Result { + f.debug_struct("AliasTerm") + .field("args", &this.map(|data| data.args)) + .field("def_id", &this.data.def_id) + .finish() + } +} + +impl<'tcx> rustc_type_ir::inherent::AliasTerm> for AliasTerm<'tcx> { fn new( interner: TyCtxt<'tcx>, trait_def_id: DefId, args: impl IntoIterator>>, ) -> Self { - AliasTy::new(interner, trait_def_id, args) + AliasTerm::new(interner, trait_def_id, args) } fn def_id(self) -> DefId { @@ -1172,6 +1191,178 @@ impl<'tcx> rustc_type_ir::inherent::AliasTy> for AliasTy<'tcx> { } } +impl<'tcx> AliasTerm<'tcx> { + pub fn new( + tcx: TyCtxt<'tcx>, + def_id: DefId, + args: impl IntoIterator>>, + ) -> AliasTerm<'tcx> { + let args = tcx.check_and_mk_args(def_id, args); + AliasTerm { def_id, args, _use_alias_term_new_instead: () } + } + + pub fn expect_ty(self, tcx: TyCtxt<'tcx>) -> AliasTy<'tcx> { + assert_matches!( + self.kind(tcx), + ty::AliasTermKind::ProjectionTy + | ty::AliasTermKind::OpaqueTy + | ty::AliasTermKind::WeakTy + | ty::AliasTermKind::InherentTy + ); + ty::AliasTy { def_id: self.def_id, args: self.args, _use_alias_ty_new_instead: () } + } + + pub fn kind(self, tcx: TyCtxt<'tcx>) -> ty::AliasTermKind { + match tcx.def_kind(self.def_id) { + DefKind::AssocTy => { + if let DefKind::Impl { of_trait: false } = tcx.def_kind(tcx.parent(self.def_id)) { + ty::AliasTermKind::InherentTy + } else { + ty::AliasTermKind::ProjectionTy + } + } + DefKind::OpaqueTy => ty::AliasTermKind::OpaqueTy, + DefKind::TyAlias => ty::AliasTermKind::WeakTy, + DefKind::AssocConst | DefKind::AnonConst => ty::AliasTermKind::UnevaluatedConst, + kind => bug!("unexpected DefKind in AliasTy: {kind:?}"), + } + } +} + +/// The following methods work only with (trait) associated type projections. +impl<'tcx> AliasTerm<'tcx> { + pub fn self_ty(self) -> Ty<'tcx> { + self.args.type_at(0) + } + + pub fn with_self_ty(self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> Self { + AliasTerm::new( + tcx, + self.def_id, + [self_ty.into()].into_iter().chain(self.args.iter().skip(1)), + ) + } + + pub fn trait_def_id(self, tcx: TyCtxt<'tcx>) -> DefId { + match tcx.def_kind(self.def_id) { + DefKind::AssocTy | DefKind::AssocConst => tcx.parent(self.def_id), + kind => bug!("expected a projection AliasTy; found {kind:?}"), + } + } + + /// Extracts the underlying trait reference from this projection. + /// For example, if this is a projection of `::Item`, + /// then this function would return a `T: Iterator` trait reference. + /// + /// NOTE: This will drop the args for generic associated types + /// consider calling [Self::trait_ref_and_own_args] to get those + /// as well. + pub fn trait_ref(self, tcx: TyCtxt<'tcx>) -> ty::TraitRef<'tcx> { + let def_id = self.trait_def_id(tcx); + ty::TraitRef::new(tcx, def_id, self.args.truncate_to(tcx, tcx.generics_of(def_id))) + } + + /// Extracts the underlying trait reference and own args from this projection. + /// For example, if this is a projection of `::Item<'a>`, + /// then this function would return a `T: StreamingIterator` trait reference and `['a]` as the own args + pub fn trait_ref_and_own_args( + self, + tcx: TyCtxt<'tcx>, + ) -> (ty::TraitRef<'tcx>, &'tcx [ty::GenericArg<'tcx>]) { + debug_assert!(matches!(tcx.def_kind(self.def_id), DefKind::AssocTy | DefKind::AssocConst)); + let trait_def_id = self.trait_def_id(tcx); + let trait_generics = tcx.generics_of(trait_def_id); + ( + ty::TraitRef::new(tcx, trait_def_id, self.args.truncate_to(tcx, trait_generics)), + &self.args[trait_generics.count()..], + ) + } + + pub fn to_term(self, tcx: TyCtxt<'tcx>) -> ty::Term<'tcx> { + match self.kind(tcx) { + ty::AliasTermKind::ProjectionTy => Ty::new_alias( + tcx, + ty::Projection, + AliasTy { def_id: self.def_id, args: self.args, _use_alias_ty_new_instead: () }, + ) + .into(), + ty::AliasTermKind::InherentTy => Ty::new_alias( + tcx, + ty::Inherent, + AliasTy { def_id: self.def_id, args: self.args, _use_alias_ty_new_instead: () }, + ) + .into(), + ty::AliasTermKind::OpaqueTy => Ty::new_alias( + tcx, + ty::Opaque, + AliasTy { def_id: self.def_id, args: self.args, _use_alias_ty_new_instead: () }, + ) + .into(), + ty::AliasTermKind::WeakTy => Ty::new_alias( + tcx, + ty::Weak, + AliasTy { def_id: self.def_id, args: self.args, _use_alias_ty_new_instead: () }, + ) + .into(), + ty::AliasTermKind::UnevaluatedConst => ty::Const::new_unevaluated( + tcx, + ty::UnevaluatedConst::new(self.def_id, self.args), + tcx.type_of(self.def_id).instantiate(tcx, self.args), + ) + .into(), + } + } +} + +impl<'tcx> From> for AliasTerm<'tcx> { + fn from(ty: AliasTy<'tcx>) -> Self { + AliasTerm { args: ty.args, def_id: ty.def_id, _use_alias_term_new_instead: () } + } +} + +impl<'tcx> From> for AliasTerm<'tcx> { + fn from(ct: ty::UnevaluatedConst<'tcx>) -> Self { + AliasTerm { args: ct.args, def_id: ct.def, _use_alias_term_new_instead: () } + } +} + +/// Represents the projection of an associated, opaque, or lazy-type-alias type. +/// +/// * For a projection, this would be `>::N<...>`. +/// * For an inherent projection, this would be `Ty::N<...>`. +/// * For an opaque type, there is no explicit syntax. +#[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable)] +#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)] +pub struct AliasTy<'tcx> { + /// The parameters of the associated or opaque type. + /// + /// For a projection, these are the generic parameters for the trait and the + /// GAT parameters, if there are any. + /// + /// For an inherent projection, they consist of the self type and the GAT parameters, + /// if there are any. + /// + /// For RPIT the generic parameters are for the generics of the function, + /// while for TAIT it is used for the generic parameters of the alias. + pub args: GenericArgsRef<'tcx>, + + /// The `DefId` of the `TraitItem` or `ImplItem` for the associated type `N` depending on whether + /// this is a projection or an inherent projection or the `DefId` of the `OpaqueType` item if + /// this is an opaque. + /// + /// During codegen, `tcx.type_of(def_id)` can be used to get the type of the + /// underlying type if the type is an opaque. + /// + /// Note that if this is an associated type, this is not the `DefId` of the + /// `TraitRef` containing this associated type, which is in `tcx.associated_item(def_id).container`, + /// aka. `tcx.parent(def_id)`. + pub def_id: DefId, + + /// This field exists to prevent the creation of `AliasTy` without using + /// [AliasTy::new]. + _use_alias_ty_new_instead: (), +} + impl<'tcx> AliasTy<'tcx> { pub fn new( tcx: TyCtxt<'tcx>, @@ -1182,7 +1373,7 @@ impl<'tcx> AliasTy<'tcx> { ty::AliasTy { def_id, args, _use_alias_ty_new_instead: () } } - pub fn kind(self, tcx: TyCtxt<'tcx>) -> ty::AliasKind { + pub fn kind(self, tcx: TyCtxt<'tcx>) -> ty::AliasTyKind { match tcx.def_kind(self.def_id) { DefKind::AssocTy if let DefKind::Impl { of_trait: false } = @@ -1199,24 +1390,7 @@ impl<'tcx> AliasTy<'tcx> { /// Whether this alias type is an opaque. pub fn is_opaque(self, tcx: TyCtxt<'tcx>) -> bool { - matches!(self.opt_kind(tcx), Some(ty::Opaque)) - } - - /// FIXME: rename `AliasTy` to `AliasTerm` and always handle - /// constants. This function can then be removed. - pub fn opt_kind(self, tcx: TyCtxt<'tcx>) -> Option { - match tcx.def_kind(self.def_id) { - DefKind::AssocTy - if let DefKind::Impl { of_trait: false } = - tcx.def_kind(tcx.parent(self.def_id)) => - { - Some(ty::Inherent) - } - DefKind::AssocTy => Some(ty::Projection), - DefKind::OpaqueTy => Some(ty::Opaque), - DefKind::TyAlias => Some(ty::Weak), - _ => None, - } + matches!(self.kind(tcx), ty::Opaque) } pub fn to_ty(self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> { @@ -1224,7 +1398,7 @@ impl<'tcx> AliasTy<'tcx> { } } -/// The following methods work only with associated type projections. +/// The following methods work only with (trait) associated type projections. impl<'tcx> AliasTy<'tcx> { pub fn self_ty(self) -> Ty<'tcx> { self.args.type_at(0) @@ -1233,10 +1407,7 @@ impl<'tcx> AliasTy<'tcx> { pub fn with_self_ty(self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> Self { AliasTy::new(tcx, self.def_id, [self_ty.into()].into_iter().chain(self.args.iter().skip(1))) } -} -/// The following methods work only with trait associated type projections. -impl<'tcx> AliasTy<'tcx> { pub fn trait_def_id(self, tcx: TyCtxt<'tcx>) -> DefId { match tcx.def_kind(self.def_id) { DefKind::AssocTy | DefKind::AssocConst => tcx.parent(self.def_id), @@ -1541,7 +1712,7 @@ impl<'tcx> Ty<'tcx> { #[inline] pub fn new_alias( tcx: TyCtxt<'tcx>, - kind: ty::AliasKind, + kind: ty::AliasTyKind, alias_ty: ty::AliasTy<'tcx>, ) -> Ty<'tcx> { debug_assert_matches!( diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index 6ad4f492f742f..04ce3de887441 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -1086,7 +1086,7 @@ impl<'tcx> TypeFolder> for OpaqueTypeExpander<'tcx> { { p.kind() .rebind(ty::ProjectionPredicate { - projection_ty: projection_pred.projection_ty.fold_with(self), + projection_term: projection_pred.projection_term.fold_with(self), // Don't fold the term on the RHS of the projection predicate. // This is because for default trait methods with RPITITs, we // install a `NormalizesTo(Projection(RPITIT) -> Opaque(RPITIT))` diff --git a/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs b/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs index 80eadb9abdcf4..ee820226ff326 100644 --- a/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs +++ b/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs @@ -534,8 +534,7 @@ impl<'tcx> AsyncDestructorCtorShimBuilder<'tcx> { } // If projection of Discriminant then compare with `Ty::discriminant_ty` - if let ty::Alias(ty::AliasKind::Projection, ty::AliasTy { args, def_id, .. }) = - expected_ty.kind() + if let ty::Alias(ty::Projection, ty::AliasTy { args, def_id, .. }) = expected_ty.kind() && Some(*def_id) == self.tcx.lang_items().discriminant_type() && args.first().unwrap().as_type().unwrap().discriminant_ty(self.tcx) == operand_ty { diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index c8143015583ef..f631ae76de50b 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -117,7 +117,7 @@ where if V::SHALLOW { V::Result::output() } else { args.visit_with(self) } } - fn visit_projection_ty(&mut self, projection: ty::AliasTy<'tcx>) -> V::Result { + fn visit_projection_term(&mut self, projection: ty::AliasTerm<'tcx>) -> V::Result { let tcx = self.def_id_visitor.tcx(); let (trait_ref, assoc_args) = projection.trait_ref_and_own_args(tcx); try_visit!(self.visit_trait(trait_ref)); @@ -135,9 +135,12 @@ where ty::ClauseKind::Trait(ty::TraitPredicate { trait_ref, polarity: _ }) => { self.visit_trait(trait_ref) } - ty::ClauseKind::Projection(ty::ProjectionPredicate { projection_ty, term }) => { + ty::ClauseKind::Projection(ty::ProjectionPredicate { + projection_term: projection_ty, + term, + }) => { try_visit!(term.visit_with(self)); - self.visit_projection_ty(projection_ty) + self.visit_projection_term(projection_ty) } ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(ty, _region)) => ty.visit_with(self), ty::ClauseKind::RegionOutlives(..) => V::Result::output(), @@ -226,7 +229,7 @@ where return if V::SHALLOW { V::Result::output() } else if kind == ty::Projection { - self.visit_projection_ty(data) + self.visit_projection_term(data.into()) } else { V::Result::from_branch( data.args.iter().try_for_each(|arg| arg.visit_with(self).branch()), diff --git a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs index c442d33cf8660..ec44b4c16fec9 100644 --- a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs +++ b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs @@ -9,7 +9,7 @@ use stable_mir::ty::{ use crate::rustc_smir::{alloc, Stable, Tables}; -impl<'tcx> Stable<'tcx> for ty::AliasKind { +impl<'tcx> Stable<'tcx> for ty::AliasTyKind { type T = stable_mir::ty::AliasKind; fn stable(&self, _: &mut Tables<'_>) -> Self::T { match self { @@ -29,6 +29,14 @@ impl<'tcx> Stable<'tcx> for ty::AliasTy<'tcx> { } } +impl<'tcx> Stable<'tcx> for ty::AliasTerm<'tcx> { + type T = stable_mir::ty::AliasTerm; + fn stable(&self, tables: &mut Tables<'_>) -> Self::T { + let ty::AliasTerm { args, def_id, .. } = self; + stable_mir::ty::AliasTerm { def_id: tables.alias_def(*def_id), args: args.stable(tables) } + } +} + impl<'tcx> Stable<'tcx> for ty::DynKind { type T = stable_mir::ty::DynKind; @@ -715,9 +723,9 @@ impl<'tcx> Stable<'tcx> for ty::ProjectionPredicate<'tcx> { type T = stable_mir::ty::ProjectionPredicate; fn stable(&self, tables: &mut Tables<'_>) -> Self::T { - let ty::ProjectionPredicate { projection_ty, term } = self; + let ty::ProjectionPredicate { projection_term: projection_ty, term } = self; stable_mir::ty::ProjectionPredicate { - projection_ty: projection_ty.stable(tables), + projection_term: projection_ty.stable(tables), term: term.unpack().stable(tables), } } diff --git a/compiler/rustc_trait_selection/src/solve/alias_relate.rs b/compiler/rustc_trait_selection/src/solve/alias_relate.rs index e079809aecc99..65cc0a4585732 100644 --- a/compiler/rustc_trait_selection/src/solve/alias_relate.rs +++ b/compiler/rustc_trait_selection/src/solve/alias_relate.rs @@ -29,7 +29,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { let Goal { param_env, predicate: (lhs, rhs, direction) } = goal; // Structurally normalize the lhs. - let lhs = if let Some(alias) = lhs.to_alias_ty(self.tcx()) { + let lhs = if let Some(alias) = lhs.to_alias_term() { let term = self.next_term_infer_of_kind(lhs); self.add_normalizes_to_goal(goal.with(tcx, ty::NormalizesTo { alias, term })); term @@ -38,7 +38,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { }; // Structurally normalize the rhs. - let rhs = if let Some(alias) = rhs.to_alias_ty(self.tcx()) { + let rhs = if let Some(alias) = rhs.to_alias_term() { let term = self.next_term_infer_of_kind(rhs); self.add_normalizes_to_goal(goal.with(tcx, ty::NormalizesTo { alias, term })); term @@ -56,7 +56,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { ty::AliasRelationDirection::Equate => ty::Variance::Invariant, ty::AliasRelationDirection::Subtype => ty::Variance::Covariant, }; - match (lhs.to_alias_ty(tcx), rhs.to_alias_ty(tcx)) { + match (lhs.to_alias_term(), rhs.to_alias_term()) { (None, None) => { self.relate(param_env, lhs, variance, rhs)?; self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) diff --git a/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs b/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs index eeaef028cdb4d..1474f8a679b69 100644 --- a/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs +++ b/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs @@ -698,7 +698,7 @@ pub(in crate::solve) fn predicates_for_object_candidate<'tcx>( old_ty, None, "{} has two generic parameters: {} and {}", - proj.projection_ty, + proj.projection_term, proj.term, old_ty.unwrap() ); @@ -739,7 +739,11 @@ impl<'tcx> TypeFolder> for ReplaceProjectionWith<'_, 'tcx> { // FIXME: Technically this equate could be fallible... self.nested.extend( self.ecx - .eq_and_get_goals(self.param_env, alias_ty, proj.projection_ty) + .eq_and_get_goals( + self.param_env, + alias_ty, + proj.projection_term.expect_ty(self.ecx.tcx()), + ) .expect("expected to be able to unify goal projection with dyn's projection"), ); proj.term.ty().unwrap() diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs index 8614c17cabf1d..06c30bb82cfc3 100644 --- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs @@ -747,7 +747,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { pub(super) fn relate_rigid_alias_non_alias( &mut self, param_env: ty::ParamEnv<'tcx>, - alias: ty::AliasTy<'tcx>, + alias: ty::AliasTerm<'tcx>, variance: ty::Variance, term: ty::Term<'tcx>, ) -> Result<(), NoSolution> { @@ -764,13 +764,13 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { // Alternatively we could modify `Equate` for this case by adding another // variant to `StructurallyRelateAliases`. let identity_args = self.fresh_args_for_item(alias.def_id); - let rigid_ctor = ty::AliasTy::new(tcx, alias.def_id, identity_args); - let ctor_ty = rigid_ctor.to_ty(tcx); + let rigid_ctor = ty::AliasTerm::new(tcx, alias.def_id, identity_args); + let ctor_term = rigid_ctor.to_term(tcx); let InferOk { value: (), obligations } = self .infcx .at(&ObligationCause::dummy(), param_env) - .trace(term, ctor_ty.into()) - .eq_structurally_relating_aliases(term, ctor_ty.into())?; + .trace(term, ctor_term) + .eq_structurally_relating_aliases(term, ctor_term)?; debug_assert!(obligations.is_empty()); self.relate(param_env, alias, variance, rigid_ctor) } else { diff --git a/compiler/rustc_trait_selection/src/solve/normalize.rs b/compiler/rustc_trait_selection/src/solve/normalize.rs index 1ac1827bf1c33..5d5161e092e31 100644 --- a/compiler/rustc_trait_selection/src/solve/normalize.rs +++ b/compiler/rustc_trait_selection/src/solve/normalize.rs @@ -7,7 +7,7 @@ use rustc_infer::infer::InferCtxt; use rustc_infer::traits::TraitEngineExt; use rustc_infer::traits::{FulfillmentError, Obligation, TraitEngine}; use rustc_middle::traits::ObligationCause; -use rustc_middle::ty::{self, AliasTy, Ty, TyCtxt, UniverseIndex}; +use rustc_middle::ty::{self, Ty, TyCtxt, UniverseIndex}; use rustc_middle::ty::{FallibleTypeFolder, TypeFolder, TypeSuperFoldable}; use rustc_middle::ty::{TypeFoldable, TypeVisitableExt}; @@ -63,7 +63,7 @@ impl<'tcx> NormalizationFolder<'_, 'tcx> { }; self.at.infcx.err_ctxt().report_overflow_error( - OverflowCause::DeeplyNormalize(data), + OverflowCause::DeeplyNormalize(data.into()), self.at.cause.span, true, |_| {}, @@ -108,7 +108,7 @@ impl<'tcx> NormalizationFolder<'_, 'tcx> { let recursion_limit = tcx.recursion_limit(); if !recursion_limit.value_within_limit(self.depth) { self.at.infcx.err_ctxt().report_overflow_error( - OverflowCause::DeeplyNormalize(ty::AliasTy::new(tcx, uv.def, uv.args)), + OverflowCause::DeeplyNormalize(uv.into()), self.at.cause.span, true, |_| {}, @@ -122,10 +122,7 @@ impl<'tcx> NormalizationFolder<'_, 'tcx> { tcx, self.at.cause.clone(), self.at.param_env, - ty::NormalizesTo { - alias: AliasTy::new(tcx, uv.def, uv.args), - term: new_infer_ct.into(), - }, + ty::NormalizesTo { alias: uv.into(), term: new_infer_ct.into() }, ); let result = if infcx.predicate_may_hold(&obligation) { diff --git a/compiler/rustc_trait_selection/src/solve/normalizes_to/inherent.rs b/compiler/rustc_trait_selection/src/solve/normalizes_to/inherent.rs index 439f9eec831f2..353bdb9caff8f 100644 --- a/compiler/rustc_trait_selection/src/solve/normalizes_to/inherent.rs +++ b/compiler/rustc_trait_selection/src/solve/normalizes_to/inherent.rs @@ -15,7 +15,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { goal: Goal<'tcx, ty::NormalizesTo<'tcx>>, ) -> QueryResult<'tcx> { let tcx = self.tcx(); - let inherent = goal.predicate.alias; + let inherent = goal.predicate.alias.expect_ty(tcx); let impl_def_id = tcx.parent(inherent.def_id); let impl_args = self.fresh_args_for_item(impl_def_id); diff --git a/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs b/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs index 8d5c5d2a06380..9dd76e5523561 100644 --- a/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs @@ -40,19 +40,8 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { Ok(res) => Ok(res), Err(NoSolution) => { let Goal { param_env, predicate: NormalizesTo { alias, term } } = goal; - if alias.opt_kind(self.tcx()).is_some() { - self.relate_rigid_alias_non_alias( - param_env, - alias, - ty::Variance::Invariant, - term, - )?; - self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) - } else { - // FIXME(generic_const_exprs): we currently do not support rigid - // unevaluated constants. - Err(NoSolution) - } + self.relate_rigid_alias_non_alias(param_env, alias, ty::Variance::Invariant, term)?; + self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) } } } @@ -132,7 +121,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> { ecx.eq( goal.param_env, goal.predicate.alias, - assumption_projection_pred.projection_ty, + assumption_projection_pred.projection_term, )?; ecx.instantiate_normalizes_to_term(goal, assumption_projection_pred.term); @@ -373,7 +362,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> { let pred = tupled_inputs_and_output .map_bound(|(inputs, output)| ty::ProjectionPredicate { - projection_ty: ty::AliasTy::new( + projection_term: ty::AliasTerm::new( tcx, goal.predicate.def_id(), [goal.predicate.self_ty(), inputs], @@ -425,9 +414,9 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> { output_coroutine_ty, coroutine_return_ty, }| { - let (projection_ty, term) = match tcx.item_name(goal.predicate.def_id()) { + let (projection_term, term) = match tcx.item_name(goal.predicate.def_id()) { sym::CallOnceFuture => ( - ty::AliasTy::new( + ty::AliasTerm::new( tcx, goal.predicate.def_id(), [goal.predicate.self_ty(), tupled_inputs_ty], @@ -435,7 +424,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> { output_coroutine_ty.into(), ), sym::CallRefFuture => ( - ty::AliasTy::new( + ty::AliasTerm::new( tcx, goal.predicate.def_id(), [ @@ -447,7 +436,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> { output_coroutine_ty.into(), ), sym::Output => ( - ty::AliasTy::new( + ty::AliasTerm::new( tcx, goal.predicate.def_id(), [ @@ -459,7 +448,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> { ), name => bug!("no such associated type: {name}"), }; - ty::ProjectionPredicate { projection_ty, term } + ty::ProjectionPredicate { projection_term, term } }, ) .to_predicate(tcx); @@ -636,7 +625,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> { CandidateSource::BuiltinImpl(BuiltinImplSource::Misc), goal, ty::ProjectionPredicate { - projection_ty: ty::AliasTy::new(ecx.tcx(), goal.predicate.def_id(), [self_ty]), + projection_term: ty::AliasTerm::new(ecx.tcx(), goal.predicate.def_id(), [self_ty]), term, } .to_predicate(tcx), @@ -668,7 +657,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> { CandidateSource::BuiltinImpl(BuiltinImplSource::Misc), goal, ty::ProjectionPredicate { - projection_ty: ty::AliasTy::new(ecx.tcx(), goal.predicate.def_id(), [self_ty]), + projection_term: ty::AliasTerm::new(ecx.tcx(), goal.predicate.def_id(), [self_ty]), term, } .to_predicate(tcx), @@ -752,7 +741,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> { CandidateSource::BuiltinImpl(BuiltinImplSource::Misc), goal, ty::ProjectionPredicate { - projection_ty: ty::AliasTy::new( + projection_term: ty::AliasTerm::new( ecx.tcx(), goal.predicate.def_id(), [self_ty, coroutine.resume_ty()], diff --git a/compiler/rustc_trait_selection/src/solve/project_goals.rs b/compiler/rustc_trait_selection/src/solve/project_goals.rs index 74b3db71e78f2..0f1be1072a8f1 100644 --- a/compiler/rustc_trait_selection/src/solve/project_goals.rs +++ b/compiler/rustc_trait_selection/src/solve/project_goals.rs @@ -11,19 +11,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { goal: Goal<'tcx, ProjectionPredicate<'tcx>>, ) -> QueryResult<'tcx> { let tcx = self.tcx(); - let projection_term = match goal.predicate.term.unpack() { - ty::TermKind::Ty(_) => goal.predicate.projection_ty.to_ty(tcx).into(), - ty::TermKind::Const(_) => ty::Const::new_unevaluated( - tcx, - ty::UnevaluatedConst::new( - goal.predicate.projection_ty.def_id, - goal.predicate.projection_ty.args, - ), - tcx.type_of(goal.predicate.projection_ty.def_id) - .instantiate(tcx, goal.predicate.projection_ty.args), - ) - .into(), - }; + let projection_term = goal.predicate.projection_term.to_term(tcx); let goal = goal.with( tcx, ty::PredicateKind::AliasRelate( diff --git a/compiler/rustc_trait_selection/src/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs index 053de2c673b8a..60562acfe93f9 100644 --- a/compiler/rustc_trait_selection/src/traits/auto_trait.rs +++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs @@ -540,11 +540,11 @@ impl<'tcx> AutoTraitFinder<'tcx> { finished_map } - fn is_param_no_infer(&self, args: GenericArgsRef<'_>) -> bool { + fn is_param_no_infer(&self, args: GenericArgsRef<'tcx>) -> bool { self.is_of_param(args.type_at(0)) && !args.types().any(|t| t.has_infer_types()) } - pub fn is_of_param(&self, ty: Ty<'_>) -> bool { + pub fn is_of_param(&self, ty: Ty<'tcx>) -> bool { match ty.kind() { ty::Param(_) => true, ty::Alias(ty::Projection, p) => self.is_of_param(p.self_ty()), @@ -552,9 +552,9 @@ impl<'tcx> AutoTraitFinder<'tcx> { } } - fn is_self_referential_projection(&self, p: ty::PolyProjectionPredicate<'_>) -> bool { + fn is_self_referential_projection(&self, p: ty::PolyProjectionPredicate<'tcx>) -> bool { if let Some(ty) = p.term().skip_binder().ty() { - matches!(ty.kind(), ty::Alias(ty::Projection, proj) if proj == &p.skip_binder().projection_ty) + matches!(ty.kind(), ty::Alias(ty::Projection, proj) if proj == &p.skip_binder().projection_term.expect_ty(self.tcx)) } else { false } @@ -612,7 +612,7 @@ impl<'tcx> AutoTraitFinder<'tcx> { // an inference variable. // Additionally, we check if we've seen this predicate before, // to avoid rendering duplicate bounds to the user. - if self.is_param_no_infer(p.skip_binder().projection_ty.args) + if self.is_param_no_infer(p.skip_binder().projection_term.args) && !p.term().skip_binder().has_infer_types() && is_new_pred { @@ -684,7 +684,7 @@ impl<'tcx> AutoTraitFinder<'tcx> { // and turn them into an explicit negative impl for our type. debug!("Projecting and unifying projection predicate {:?}", predicate); - match project::poly_project_and_unify_type(selcx, &obligation.with(self.tcx, p)) + match project::poly_project_and_unify_term(selcx, &obligation.with(self.tcx, p)) { ProjectAndUnifyResult::MismatchedProjectionTypes(e) => { debug!( diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index 59725ce9de096..9069456b6e7d4 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -1095,11 +1095,11 @@ impl<'a, 'tcx> ProofTreeVisitor<'tcx> for AmbiguityCausesVisitor<'a, 'tcx> { Some(ty::PredicateKind::Clause(ty::ClauseKind::Trait(tr))) => tr.trait_ref, Some(ty::PredicateKind::Clause(ty::ClauseKind::Projection(proj))) if matches!( - infcx.tcx.def_kind(proj.projection_ty.def_id), + infcx.tcx.def_kind(proj.projection_term.def_id), DefKind::AssocTy | DefKind::AssocConst ) => { - proj.projection_ty.trait_ref(infcx.tcx) + proj.projection_term.trait_ref(infcx.tcx) } _ => return, }; diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index ea1752a6e982c..efa7c3959c3b3 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -1104,9 +1104,9 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { .iter() .find_map(|pred| { if let ty::ClauseKind::Projection(proj) = pred.kind().skip_binder() - && Some(proj.projection_ty.def_id) == self.tcx.lang_items().fn_once_output() + && Some(proj.projection_term.def_id) == self.tcx.lang_items().fn_once_output() // args tuple will always be args[1] - && let ty::Tuple(args) = proj.projection_ty.args.type_at(1).kind() + && let ty::Tuple(args) = proj.projection_term.args.type_at(1).kind() { Some(( DefIdOrName::DefId(def_id), @@ -1148,10 +1148,10 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { }; param_env.caller_bounds().iter().find_map(|pred| { if let ty::ClauseKind::Projection(proj) = pred.kind().skip_binder() - && Some(proj.projection_ty.def_id) == self.tcx.lang_items().fn_once_output() - && proj.projection_ty.self_ty() == found + && Some(proj.projection_term.def_id) == self.tcx.lang_items().fn_once_output() + && proj.projection_term.self_ty() == found // args tuple will always be args[1] - && let ty::Tuple(args) = proj.projection_ty.args.type_at(1).kind() + && let ty::Tuple(args) = proj.projection_term.args.type_at(1).kind() { Some(( name, @@ -3845,11 +3845,11 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { && let Some(found) = failed_pred.skip_binder().term.ty() { type_diffs = vec![Sorts(ty::error::ExpectedFound { - expected: Ty::new_alias( - self.tcx, - ty::Projection, - where_pred.skip_binder().projection_ty, - ), + expected: where_pred + .skip_binder() + .projection_term + .expect_ty(self.tcx) + .to_ty(self.tcx), found, })]; } @@ -4274,7 +4274,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { // This corresponds to `::Item = _`. let projection = ty::Binder::dummy(ty::PredicateKind::Clause( ty::ClauseKind::Projection(ty::ProjectionPredicate { - projection_ty: ty::AliasTy::new(self.tcx, proj.def_id, args), + projection_term: ty::AliasTerm::new(self.tcx, proj.def_id, args), term: ty.into(), }), )); @@ -4971,7 +4971,7 @@ fn point_at_assoc_type_restriction( let ty::ClauseKind::Projection(proj) = clause else { return; }; - let name = tcx.item_name(proj.projection_ty.def_id); + let name = tcx.item_name(proj.projection_term.def_id); let mut predicates = generics.predicates.iter().peekable(); let mut prev: Option<&hir::WhereBoundPredicate<'_>> = None; while let Some(pred) = predicates.next() { diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs index 08ffe37b8b4d0..8f6e997e3b778 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs @@ -62,7 +62,7 @@ use super::{ pub use rustc_infer::traits::error_reporting::*; pub enum OverflowCause<'tcx> { - DeeplyNormalize(ty::AliasTy<'tcx>), + DeeplyNormalize(ty::AliasTerm<'tcx>), TraitSolver(ty::Predicate<'tcx>), } @@ -246,10 +246,10 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { } let mut err = match cause { - OverflowCause::DeeplyNormalize(alias_ty) => { - let alias_ty = self.resolve_vars_if_possible(alias_ty); - let kind = alias_ty.opt_kind(self.tcx).map_or("alias", |k| k.descr()); - let alias_str = with_short_path(self.tcx, alias_ty); + OverflowCause::DeeplyNormalize(alias_term) => { + let alias_term = self.resolve_vars_if_possible(alias_term); + let kind = alias_term.kind(self.tcx).descr(); + let alias_str = with_short_path(self.tcx, alias_term); struct_span_code_err!( self.dcx(), span, @@ -1468,7 +1468,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { ); let param_env = ty::ParamEnv::empty(); - self.can_eq(param_env, goal.projection_ty, assumption.projection_ty) + self.can_eq(param_env, goal.projection_term, assumption.projection_term) && self.can_eq(param_env, goal.term, assumption.term) } @@ -1583,23 +1583,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { infer::BoundRegionConversionTime::HigherRankedType, bound_predicate.rebind(data), ); - let unnormalized_term = match data.term.unpack() { - ty::TermKind::Ty(_) => Ty::new_projection( - self.tcx, - data.projection_ty.def_id, - data.projection_ty.args, - ) - .into(), - ty::TermKind::Const(ct) => ty::Const::new_unevaluated( - self.tcx, - ty::UnevaluatedConst { - def: data.projection_ty.def_id, - args: data.projection_ty.args, - }, - ct.ty(), - ) - .into(), - }; + let unnormalized_term = data.projection_term.to_term(self.tcx); // FIXME(-Znext-solver): For diagnostic purposes, it would be nice // to deeply normalize this type. let normalized_term = @@ -1664,13 +1648,13 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { return None; }; - let trait_assoc_item = self.tcx.opt_associated_item(proj.projection_ty.def_id)?; + let trait_assoc_item = self.tcx.opt_associated_item(proj.projection_term.def_id)?; let trait_assoc_ident = trait_assoc_item.ident(self.tcx); let mut associated_items = vec![]; self.tcx.for_each_relevant_impl( - self.tcx.trait_of_item(proj.projection_ty.def_id)?, - proj.projection_ty.self_ty(), + self.tcx.trait_of_item(proj.projection_term.def_id)?, + proj.projection_term.self_ty(), |impl_def_id| { associated_items.extend( self.tcx @@ -1739,11 +1723,11 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { normalized_ty: ty::Term<'tcx>, expected_ty: ty::Term<'tcx>, ) -> Option { - let trait_def_id = pred.projection_ty.trait_def_id(self.tcx); - let self_ty = pred.projection_ty.self_ty(); + let trait_def_id = pred.projection_term.trait_def_id(self.tcx); + let self_ty = pred.projection_term.self_ty(); with_forced_trimmed_paths! { - if Some(pred.projection_ty.def_id) == self.tcx.lang_items().fn_once_output() { + if Some(pred.projection_term.def_id) == self.tcx.lang_items().fn_once_output() { let fn_kind = self_ty.prefix_string(self.tcx); let item = match self_ty.kind() { ty::FnDef(def, _) => self.tcx.item_name(*def).to_string(), @@ -2622,14 +2606,14 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { } if let Err(guar) = - self.tcx.ensure().coherent_trait(self.tcx.parent(data.projection_ty.def_id)) + self.tcx.ensure().coherent_trait(self.tcx.parent(data.projection_term.def_id)) { // Avoid bogus "type annotations needed `Foo: Bar`" errors on `impl Bar for Foo` in case // other `Foo` impls are incoherent. return guar; } let arg = data - .projection_ty + .projection_term .args .iter() .chain(Some(data.term.into_arg())) diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index e3497c646dbde..dc32db0903428 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -770,13 +770,13 @@ impl<'a, 'tcx> FulfillProcessor<'a, 'tcx> { } } - match project::poly_project_and_unify_type(&mut self.selcx, &project_obligation) { + match project::poly_project_and_unify_term(&mut self.selcx, &project_obligation) { ProjectAndUnifyResult::Holds(os) => ProcessResult::Changed(mk_pending(os)), ProjectAndUnifyResult::FailedNormalization => { stalled_on.clear(); stalled_on.extend(args_infer_vars( &self.selcx, - project_obligation.predicate.map_bound(|pred| pred.projection_ty.args), + project_obligation.predicate.map_bound(|pred| pred.projection_term.args), )); ProcessResult::Unchanged } diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index 56f8b4b9cdb82..2325e45467e2e 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -51,7 +51,7 @@ pub use self::object_safety::hir_ty_lowering_object_safety_violations; pub use self::object_safety::is_vtable_safe_method; pub use self::object_safety::object_safety_violations_for_assoc_item; pub use self::object_safety::ObjectSafetyViolation; -pub use self::project::{normalize_inherent_projection, normalize_projection_type}; +pub use self::project::{normalize_inherent_projection, normalize_projection_ty}; pub use self::select::{EvaluationCache, SelectionCache, SelectionContext}; pub use self::select::{EvaluationResult, IntercrateAmbiguityCause, OverflowError}; pub use self::specialize::specialization_graph::FutureCompatOverlapError; diff --git a/compiler/rustc_trait_selection/src/traits/normalize.rs b/compiler/rustc_trait_selection/src/traits/normalize.rs index 43f4fa8e81ca1..d10aee2d4e29e 100644 --- a/compiler/rustc_trait_selection/src/traits/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/normalize.rs @@ -213,7 +213,7 @@ impl<'a, 'b, 'tcx> TypeFolder> for AssocTypeNormalizer<'a, 'b, 'tcx let recursion_limit = self.interner().recursion_limit(); if !recursion_limit.value_within_limit(self.depth) { self.selcx.infcx.err_ctxt().report_overflow_error( - OverflowCause::DeeplyNormalize(data), + OverflowCause::DeeplyNormalize(data.into()), self.cause.span, true, |_| {}, @@ -238,7 +238,7 @@ impl<'a, 'b, 'tcx> TypeFolder> for AssocTypeNormalizer<'a, 'b, 'tcx // register an obligation to *later* project, since we know // there won't be bound vars there. let data = data.fold_with(self); - let normalized_ty = project::normalize_projection_type( + let normalized_ty = project::normalize_projection_ty( self.selcx, self.param_env, data, @@ -273,10 +273,10 @@ impl<'a, 'b, 'tcx> TypeFolder> for AssocTypeNormalizer<'a, 'b, 'tcx let (data, mapped_regions, mapped_types, mapped_consts) = BoundVarReplacer::replace_bound_vars(infcx, &mut self.universes, data); let data = data.fold_with(self); - let normalized_ty = project::opt_normalize_projection_type( + let normalized_ty = project::opt_normalize_projection_term( self.selcx, self.param_env, - data, + data.into(), self.cause.clone(), self.depth, self.obligations, @@ -309,7 +309,7 @@ impl<'a, 'b, 'tcx> TypeFolder> for AssocTypeNormalizer<'a, 'b, 'tcx let recursion_limit = self.interner().recursion_limit(); if !recursion_limit.value_within_limit(self.depth) { self.selcx.infcx.err_ctxt().report_overflow_error( - OverflowCause::DeeplyNormalize(data), + OverflowCause::DeeplyNormalize(data.into()), self.cause.span, false, |diag| { diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs index 75e43bc8f5d9e..41080b3d9d357 100644 --- a/compiler/rustc_trait_selection/src/traits/object_safety.rs +++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs @@ -305,7 +305,7 @@ fn predicate_references_self<'tcx>( // // This is ALT2 in issue #56288, see that for discussion of the // possible alternatives. - data.projection_ty.args[1..].iter().any(has_self_ty).then_some(sp) + data.projection_term.args[1..].iter().any(has_self_ty).then_some(sp) } ty::ClauseKind::ConstArgHasType(_ct, ty) => has_self_ty(&ty.into()).then_some(sp), diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index f092f42dacf9a..20b5a81bb0ee3 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -12,7 +12,7 @@ use super::PredicateObligation; use super::Selection; use super::SelectionContext; use super::SelectionError; -use super::{Normalized, NormalizedTy, ProjectionCacheEntry, ProjectionCacheKey}; +use super::{Normalized, NormalizedTerm, ProjectionCacheEntry, ProjectionCacheKey}; use rustc_infer::traits::ObligationCauseCode; use rustc_middle::traits::BuiltinImplSource; use rustc_middle::traits::ImplSource; @@ -43,7 +43,7 @@ pub type PolyProjectionObligation<'tcx> = Obligation<'tcx, ty::PolyProjectionPre pub type ProjectionObligation<'tcx> = Obligation<'tcx, ty::ProjectionPredicate<'tcx>>; -pub type ProjectionTyObligation<'tcx> = Obligation<'tcx, ty::AliasTy<'tcx>>; +pub type ProjectionTermObligation<'tcx> = Obligation<'tcx, ty::AliasTerm<'tcx>>; pub(super) struct InProgress; @@ -181,7 +181,7 @@ pub(super) enum ProjectAndUnifyResult<'tcx> { /// If successful, this may result in additional obligations. Also returns /// the projection cache key used to track these additional obligations. #[instrument(level = "debug", skip(selcx))] -pub(super) fn poly_project_and_unify_type<'cx, 'tcx>( +pub(super) fn poly_project_and_unify_term<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, obligation: &PolyProjectionObligation<'tcx>, ) -> ProjectAndUnifyResult<'tcx> { @@ -192,7 +192,7 @@ pub(super) fn poly_project_and_unify_type<'cx, 'tcx>( let new_universe = infcx.universe(); let placeholder_obligation = obligation.with(infcx.tcx, placeholder_predicate); - match project_and_unify_type(selcx, &placeholder_obligation) { + match project_and_unify_term(selcx, &placeholder_obligation) { ProjectAndUnifyResult::MismatchedProjectionTypes(e) => Err(e), ProjectAndUnifyResult::Holds(obligations) if old_universe != new_universe @@ -234,17 +234,17 @@ pub(super) fn poly_project_and_unify_type<'cx, 'tcx>( /// /// See [poly_project_and_unify_type] for an explanation of the return value. #[instrument(level = "debug", skip(selcx))] -fn project_and_unify_type<'cx, 'tcx>( +fn project_and_unify_term<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, obligation: &ProjectionObligation<'tcx>, ) -> ProjectAndUnifyResult<'tcx> { let mut obligations = vec![]; let infcx = selcx.infcx; - let normalized = match opt_normalize_projection_type( + let normalized = match opt_normalize_projection_term( selcx, obligation.param_env, - obligation.predicate.projection_ty, + obligation.predicate.projection_term, obligation.cause.clone(), obligation.recursion_depth, &mut obligations, @@ -290,7 +290,7 @@ fn project_and_unify_type<'cx, 'tcx>( /// there are unresolved type variables in the projection, we will /// instantiate it with a fresh type variable `$X` and generate a new /// obligation `::Item == $X` for later. -pub fn normalize_projection_type<'a, 'b, 'tcx>( +pub fn normalize_projection_ty<'a, 'b, 'tcx>( selcx: &'a mut SelectionContext<'b, 'tcx>, param_env: ty::ParamEnv<'tcx>, projection_ty: ty::AliasTy<'tcx>, @@ -298,10 +298,10 @@ pub fn normalize_projection_type<'a, 'b, 'tcx>( depth: usize, obligations: &mut Vec>, ) -> Term<'tcx> { - opt_normalize_projection_type( + opt_normalize_projection_term( selcx, param_env, - projection_ty, + projection_ty.into(), cause.clone(), depth, obligations, @@ -313,7 +313,10 @@ pub fn normalize_projection_type<'a, 'b, 'tcx>( // and a deferred predicate to resolve this when more type // information is available. - selcx.infcx.infer_projection(param_env, projection_ty, cause, depth + 1, obligations).into() + selcx + .infcx + .projection_ty_to_infer(param_env, projection_ty, cause, depth + 1, obligations) + .into() }) } @@ -328,10 +331,10 @@ pub fn normalize_projection_type<'a, 'b, 'tcx>( /// function takes an obligations vector and appends to it directly, which is /// slightly uglier but avoids the need for an extra short-lived allocation. #[instrument(level = "debug", skip(selcx, param_env, cause, obligations))] -pub(super) fn opt_normalize_projection_type<'a, 'b, 'tcx>( +pub(super) fn opt_normalize_projection_term<'a, 'b, 'tcx>( selcx: &'a mut SelectionContext<'b, 'tcx>, param_env: ty::ParamEnv<'tcx>, - projection_ty: ty::AliasTy<'tcx>, + projection_term: ty::AliasTerm<'tcx>, cause: ObligationCause<'tcx>, depth: usize, obligations: &mut Vec>, @@ -343,8 +346,8 @@ pub(super) fn opt_normalize_projection_type<'a, 'b, 'tcx>( // mode, which could lead to using incorrect cache results. let use_cache = !selcx.is_intercrate(); - let projection_ty = infcx.resolve_vars_if_possible(projection_ty); - let cache_key = ProjectionCacheKey::new(projection_ty, param_env); + let projection_term = infcx.resolve_vars_if_possible(projection_term); + let cache_key = ProjectionCacheKey::new(projection_term, param_env); // FIXME(#20304) For now, I am caching here, which is good, but it // means we don't capture the type variables that are created in @@ -410,14 +413,14 @@ pub(super) fn opt_normalize_projection_type<'a, 'b, 'tcx>( } Err(ProjectionCacheEntry::Error) => { debug!("opt_normalize_projection_type: found error"); - let result = normalize_to_error(selcx, param_env, projection_ty, cause, depth); + let result = normalize_to_error(selcx, param_env, projection_term, cause, depth); obligations.extend(result.obligations); return Ok(Some(result.value.into())); } } let obligation = - Obligation::with_depth(selcx.tcx(), cause.clone(), depth, param_env, projection_ty); + Obligation::with_depth(selcx.tcx(), cause.clone(), depth, param_env, projection_term); match project(selcx, &obligation) { Ok(Projected::Progress(Progress { @@ -480,7 +483,7 @@ pub(super) fn opt_normalize_projection_type<'a, 'b, 'tcx>( if use_cache { infcx.inner.borrow_mut().projection_cache().error(cache_key); } - let result = normalize_to_error(selcx, param_env, projection_ty, cause, depth); + let result = normalize_to_error(selcx, param_env, projection_term, cause, depth); obligations.extend(result.obligations); Ok(Some(result.value.into())) } @@ -509,19 +512,33 @@ pub(super) fn opt_normalize_projection_type<'a, 'b, 'tcx>( fn normalize_to_error<'a, 'tcx>( selcx: &SelectionContext<'a, 'tcx>, param_env: ty::ParamEnv<'tcx>, - projection_ty: ty::AliasTy<'tcx>, + projection_term: ty::AliasTerm<'tcx>, cause: ObligationCause<'tcx>, depth: usize, -) -> NormalizedTy<'tcx> { - let trait_ref = ty::Binder::dummy(projection_ty.trait_ref(selcx.tcx())); +) -> NormalizedTerm<'tcx> { + let trait_ref = ty::Binder::dummy(projection_term.trait_ref(selcx.tcx())); + let new_value = match projection_term.kind(selcx.tcx()) { + ty::AliasTermKind::ProjectionTy + | ty::AliasTermKind::InherentTy + | ty::AliasTermKind::OpaqueTy + | ty::AliasTermKind::WeakTy => selcx.infcx.next_ty_var(cause.span).into(), + ty::AliasTermKind::UnevaluatedConst => selcx + .infcx + .next_const_var( + selcx + .tcx() + .type_of(projection_term.def_id) + .instantiate(selcx.tcx(), projection_term.args), + cause.span, + ) + .into(), + }; let trait_obligation = Obligation { cause, recursion_depth: depth, param_env, predicate: trait_ref.to_predicate(selcx.tcx()), }; - let tcx = selcx.infcx.tcx; - let new_value = selcx.infcx.next_ty_var(tcx.def_span(projection_ty.def_id)); Normalized { value: new_value, obligations: vec![trait_obligation] } } @@ -675,7 +692,7 @@ impl<'tcx> Progress<'tcx> { #[instrument(level = "info", skip(selcx))] fn project<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, - obligation: &ProjectionTyObligation<'tcx>, + obligation: &ProjectionTermObligation<'tcx>, ) -> Result, ProjectionError<'tcx>> { if !selcx.tcx().recursion_limit().value_within_limit(obligation.recursion_depth) { // This should really be an immediate error, but some existing code @@ -750,7 +767,7 @@ fn project<'cx, 'tcx>( /// there that can answer this question. fn assemble_candidates_from_param_env<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, - obligation: &ProjectionTyObligation<'tcx>, + obligation: &ProjectionTermObligation<'tcx>, candidate_set: &mut ProjectionCandidateSet<'tcx>, ) { assemble_candidates_from_predicates( @@ -775,7 +792,7 @@ fn assemble_candidates_from_param_env<'cx, 'tcx>( /// Here, for example, we could conclude that the result is `i32`. fn assemble_candidates_from_trait_def<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, - obligation: &ProjectionTyObligation<'tcx>, + obligation: &ProjectionTermObligation<'tcx>, candidate_set: &mut ProjectionCandidateSet<'tcx>, ) { debug!("assemble_candidates_from_trait_def(..)"); @@ -833,7 +850,7 @@ fn assemble_candidates_from_trait_def<'cx, 'tcx>( /// `dyn Iterator: Iterator` again. fn assemble_candidates_from_object_ty<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, - obligation: &ProjectionTyObligation<'tcx>, + obligation: &ProjectionTermObligation<'tcx>, candidate_set: &mut ProjectionCandidateSet<'tcx>, ) { debug!("assemble_candidates_from_object_ty(..)"); @@ -877,7 +894,7 @@ fn assemble_candidates_from_object_ty<'cx, 'tcx>( )] fn assemble_candidates_from_predicates<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, - obligation: &ProjectionTyObligation<'tcx>, + obligation: &ProjectionTermObligation<'tcx>, candidate_set: &mut ProjectionCandidateSet<'tcx>, ctor: fn(ty::PolyProjectionPredicate<'tcx>) -> ProjectionCandidate<'tcx>, env_predicates: impl Iterator>, @@ -925,7 +942,7 @@ fn assemble_candidates_from_predicates<'cx, 'tcx>( #[instrument(level = "debug", skip(selcx, obligation, candidate_set))] fn assemble_candidates_from_impls<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, - obligation: &ProjectionTyObligation<'tcx>, + obligation: &ProjectionTermObligation<'tcx>, candidate_set: &mut ProjectionCandidateSet<'tcx>, ) { // If we are resolving `>::Item == Type`, @@ -1253,7 +1270,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>( fn confirm_candidate<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, - obligation: &ProjectionTyObligation<'tcx>, + obligation: &ProjectionTermObligation<'tcx>, candidate: ProjectionCandidate<'tcx>, ) -> Progress<'tcx> { debug!(?obligation, ?candidate, "confirm_candidate"); @@ -1285,7 +1302,7 @@ fn confirm_candidate<'cx, 'tcx>( fn confirm_select_candidate<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, - obligation: &ProjectionTyObligation<'tcx>, + obligation: &ProjectionTermObligation<'tcx>, impl_source: Selection<'tcx>, ) -> Progress<'tcx> { match impl_source { @@ -1333,7 +1350,7 @@ fn confirm_select_candidate<'cx, 'tcx>( fn confirm_coroutine_candidate<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, - obligation: &ProjectionTyObligation<'tcx>, + obligation: &ProjectionTermObligation<'tcx>, nested: Vec>, ) -> Progress<'tcx> { let self_ty = selcx.infcx.shallow_resolve(obligation.predicate.self_ty()); @@ -1377,7 +1394,7 @@ fn confirm_coroutine_candidate<'cx, 'tcx>( }; let predicate = ty::ProjectionPredicate { - projection_ty: ty::AliasTy::new(tcx, obligation.predicate.def_id, trait_ref.args), + projection_term: ty::AliasTerm::new(tcx, obligation.predicate.def_id, trait_ref.args), term: ty.into(), }; @@ -1388,7 +1405,7 @@ fn confirm_coroutine_candidate<'cx, 'tcx>( fn confirm_future_candidate<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, - obligation: &ProjectionTyObligation<'tcx>, + obligation: &ProjectionTermObligation<'tcx>, nested: Vec>, ) -> Progress<'tcx> { let self_ty = selcx.infcx.shallow_resolve(obligation.predicate.self_ty()); @@ -1421,7 +1438,7 @@ fn confirm_future_candidate<'cx, 'tcx>( debug_assert_eq!(tcx.associated_item(obligation.predicate.def_id).name, sym::Output); let predicate = ty::ProjectionPredicate { - projection_ty: ty::AliasTy::new(tcx, obligation.predicate.def_id, trait_ref.args), + projection_term: ty::AliasTerm::new(tcx, obligation.predicate.def_id, trait_ref.args), term: return_ty.into(), }; @@ -1432,7 +1449,7 @@ fn confirm_future_candidate<'cx, 'tcx>( fn confirm_iterator_candidate<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, - obligation: &ProjectionTyObligation<'tcx>, + obligation: &ProjectionTermObligation<'tcx>, nested: Vec>, ) -> Progress<'tcx> { let self_ty = selcx.infcx.shallow_resolve(obligation.predicate.self_ty()); @@ -1463,7 +1480,7 @@ fn confirm_iterator_candidate<'cx, 'tcx>( debug_assert_eq!(tcx.associated_item(obligation.predicate.def_id).name, sym::Item); let predicate = ty::ProjectionPredicate { - projection_ty: ty::AliasTy::new(tcx, obligation.predicate.def_id, trait_ref.args), + projection_term: ty::AliasTerm::new(tcx, obligation.predicate.def_id, trait_ref.args), term: yield_ty.into(), }; @@ -1474,7 +1491,7 @@ fn confirm_iterator_candidate<'cx, 'tcx>( fn confirm_async_iterator_candidate<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, - obligation: &ProjectionTyObligation<'tcx>, + obligation: &ProjectionTermObligation<'tcx>, nested: Vec>, ) -> Progress<'tcx> { let ty::Coroutine(_, args) = selcx.infcx.shallow_resolve(obligation.predicate.self_ty()).kind() @@ -1513,7 +1530,7 @@ fn confirm_async_iterator_candidate<'cx, 'tcx>( let item_ty = args.type_at(0); let predicate = ty::ProjectionPredicate { - projection_ty: ty::AliasTy::new(tcx, obligation.predicate.def_id, trait_ref.args), + projection_term: ty::AliasTerm::new(tcx, obligation.predicate.def_id, trait_ref.args), term: item_ty.into(), }; @@ -1524,7 +1541,7 @@ fn confirm_async_iterator_candidate<'cx, 'tcx>( fn confirm_builtin_candidate<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, - obligation: &ProjectionTyObligation<'tcx>, + obligation: &ProjectionTermObligation<'tcx>, data: Vec>, ) -> Progress<'tcx> { let tcx = selcx.tcx(); @@ -1582,8 +1599,10 @@ fn confirm_builtin_candidate<'cx, 'tcx>( bug!("unexpected builtin trait with associated type: {:?}", obligation.predicate); }; - let predicate = - ty::ProjectionPredicate { projection_ty: ty::AliasTy::new(tcx, item_def_id, args), term }; + let predicate = ty::ProjectionPredicate { + projection_term: ty::AliasTerm::new(tcx, item_def_id, args), + term, + }; confirm_param_env_candidate(selcx, obligation, ty::Binder::dummy(predicate), false) .with_addl_obligations(obligations) @@ -1592,7 +1611,7 @@ fn confirm_builtin_candidate<'cx, 'tcx>( fn confirm_fn_pointer_candidate<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, - obligation: &ProjectionTyObligation<'tcx>, + obligation: &ProjectionTermObligation<'tcx>, nested: Vec>, ) -> Progress<'tcx> { let tcx = selcx.tcx(); @@ -1628,7 +1647,7 @@ fn confirm_fn_pointer_candidate<'cx, 'tcx>( fn confirm_closure_candidate<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, - obligation: &ProjectionTyObligation<'tcx>, + obligation: &ProjectionTermObligation<'tcx>, nested: Vec>, ) -> Progress<'tcx> { let tcx = selcx.tcx(); @@ -1727,7 +1746,7 @@ fn confirm_closure_candidate<'cx, 'tcx>( fn confirm_callable_candidate<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, - obligation: &ProjectionTyObligation<'tcx>, + obligation: &ProjectionTermObligation<'tcx>, fn_sig: ty::PolyFnSig<'tcx>, flag: util::TupleArgumentsFlag, fn_host_effect: ty::Const<'tcx>, @@ -1748,7 +1767,7 @@ fn confirm_callable_candidate<'cx, 'tcx>( fn_host_effect, ) .map_bound(|(trait_ref, ret_type)| ty::ProjectionPredicate { - projection_ty: ty::AliasTy::new(tcx, fn_once_output_def_id, trait_ref.args), + projection_term: ty::AliasTerm::new(tcx, fn_once_output_def_id, trait_ref.args), term: ret_type.into(), }); @@ -1757,7 +1776,7 @@ fn confirm_callable_candidate<'cx, 'tcx>( fn confirm_async_closure_candidate<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, - obligation: &ProjectionTyObligation<'tcx>, + obligation: &ProjectionTermObligation<'tcx>, nested: Vec>, ) -> Progress<'tcx> { let tcx = selcx.tcx(); @@ -1836,13 +1855,13 @@ fn confirm_async_closure_candidate<'cx, 'tcx>( sym::Output => sig.return_ty, name => bug!("no such associated type: {name}"), }; - let projection_ty = match item_name { - sym::CallOnceFuture | sym::Output => ty::AliasTy::new( + let projection_term = match item_name { + sym::CallOnceFuture | sym::Output => ty::AliasTerm::new( tcx, obligation.predicate.def_id, [self_ty, sig.tupled_inputs_ty], ), - sym::CallRefFuture => ty::AliasTy::new( + sym::CallRefFuture => ty::AliasTerm::new( tcx, obligation.predicate.def_id, [ty::GenericArg::from(self_ty), sig.tupled_inputs_ty.into(), env_region.into()], @@ -1851,7 +1870,7 @@ fn confirm_async_closure_candidate<'cx, 'tcx>( }; args.coroutine_closure_sig() - .rebind(ty::ProjectionPredicate { projection_ty, term: term.into() }) + .rebind(ty::ProjectionPredicate { projection_term, term: term.into() }) } ty::FnDef(..) | ty::FnPtr(..) => { let bound_sig = self_ty.fn_sig(tcx); @@ -1871,13 +1890,13 @@ fn confirm_async_closure_candidate<'cx, 'tcx>( } name => bug!("no such associated type: {name}"), }; - let projection_ty = match item_name { - sym::CallOnceFuture | sym::Output => ty::AliasTy::new( + let projection_term = match item_name { + sym::CallOnceFuture | sym::Output => ty::AliasTerm::new( tcx, obligation.predicate.def_id, [self_ty, Ty::new_tup(tcx, sig.inputs())], ), - sym::CallRefFuture => ty::AliasTy::new( + sym::CallRefFuture => ty::AliasTerm::new( tcx, obligation.predicate.def_id, [ @@ -1889,7 +1908,7 @@ fn confirm_async_closure_candidate<'cx, 'tcx>( name => bug!("no such associated type: {name}"), }; - bound_sig.rebind(ty::ProjectionPredicate { projection_ty, term: term.into() }) + bound_sig.rebind(ty::ProjectionPredicate { projection_term, term: term.into() }) } ty::Closure(_, args) => { let args = args.as_closure(); @@ -1910,11 +1929,11 @@ fn confirm_async_closure_candidate<'cx, 'tcx>( } name => bug!("no such associated type: {name}"), }; - let projection_ty = match item_name { + let projection_term = match item_name { sym::CallOnceFuture | sym::Output => { - ty::AliasTy::new(tcx, obligation.predicate.def_id, [self_ty, sig.inputs()[0]]) + ty::AliasTerm::new(tcx, obligation.predicate.def_id, [self_ty, sig.inputs()[0]]) } - sym::CallRefFuture => ty::AliasTy::new( + sym::CallRefFuture => ty::AliasTerm::new( tcx, obligation.predicate.def_id, [ty::GenericArg::from(self_ty), sig.inputs()[0].into(), env_region.into()], @@ -1922,7 +1941,7 @@ fn confirm_async_closure_candidate<'cx, 'tcx>( name => bug!("no such associated type: {name}"), }; - bound_sig.rebind(ty::ProjectionPredicate { projection_ty, term: term.into() }) + bound_sig.rebind(ty::ProjectionPredicate { projection_term, term: term.into() }) } _ => bug!("expected callable type for AsyncFn candidate"), }; @@ -1933,7 +1952,7 @@ fn confirm_async_closure_candidate<'cx, 'tcx>( fn confirm_async_fn_kind_helper_candidate<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, - obligation: &ProjectionTyObligation<'tcx>, + obligation: &ProjectionTermObligation<'tcx>, nested: Vec>, ) -> Progress<'tcx> { let [ @@ -1950,7 +1969,7 @@ fn confirm_async_fn_kind_helper_candidate<'cx, 'tcx>( }; let predicate = ty::ProjectionPredicate { - projection_ty: ty::AliasTy::new( + projection_term: ty::AliasTerm::new( selcx.tcx(), obligation.predicate.def_id, obligation.predicate.args, @@ -1972,7 +1991,7 @@ fn confirm_async_fn_kind_helper_candidate<'cx, 'tcx>( fn confirm_param_env_candidate<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, - obligation: &ProjectionTyObligation<'tcx>, + obligation: &ProjectionTermObligation<'tcx>, poly_cache_entry: ty::PolyProjectionPredicate<'tcx>, potentially_unnormalized_candidate: bool, ) -> Progress<'tcx> { @@ -1986,7 +2005,7 @@ fn confirm_param_env_candidate<'cx, 'tcx>( poly_cache_entry, ); - let cache_projection = cache_entry.projection_ty; + let cache_projection = cache_entry.projection_term; let mut nested_obligations = Vec::new(); let obligation_projection = obligation.predicate; let obligation_projection = ensure_sufficient_stack(|| { @@ -2041,7 +2060,7 @@ fn confirm_param_env_candidate<'cx, 'tcx>( fn confirm_impl_candidate<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, - obligation: &ProjectionTyObligation<'tcx>, + obligation: &ProjectionTermObligation<'tcx>, impl_impl_source: ImplSourceUserDefinedData<'tcx, PredicateObligation<'tcx>>, ) -> Progress<'tcx> { let tcx = selcx.tcx(); @@ -2102,7 +2121,7 @@ fn confirm_impl_candidate<'cx, 'tcx>( // associated type itself. fn assoc_ty_own_obligations<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, - obligation: &ProjectionTyObligation<'tcx>, + obligation: &ProjectionTermObligation<'tcx>, nested: &mut Vec>, ) { let tcx = selcx.tcx(); @@ -2164,7 +2183,7 @@ impl<'cx, 'tcx> ProjectionCacheKeyExt<'cx, 'tcx> for ProjectionCacheKey<'tcx> { // from a specific call to `opt_normalize_projection_type` - if // there's no precise match, the original cache entry is "stranded" // anyway. - infcx.resolve_vars_if_possible(predicate.projection_ty), + infcx.resolve_vars_if_possible(predicate.projection_term), obligation.param_env, ) }) diff --git a/compiler/rustc_trait_selection/src/traits/query/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/normalize.rs index 8b39c23da56b2..1b5ffeebc01f8 100644 --- a/compiler/rustc_trait_selection/src/traits/query/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/query/normalize.rs @@ -222,7 +222,7 @@ impl<'cx, 'tcx> FallibleTypeFolder> for QueryNormalizer<'cx, 'tcx> .infcx .err_ctxt() .build_overflow_error( - OverflowCause::DeeplyNormalize(data), + OverflowCause::DeeplyNormalize(data.into()), self.cause.span, true, ) diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index 40d206b92b8df..19968fd362f13 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -944,7 +944,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } self.infcx.probe(|_| { - let ty = traits::normalize_projection_type( + let ty = traits::normalize_projection_ty( self, param_env, ty::AliasTy::new(tcx, tcx.lang_items().deref_target()?, trait_ref.args), diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 7aa2aabed7f72..d665f3c390773 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -8,7 +8,7 @@ use self::SelectionCandidate::*; use super::coherence::{self, Conflict}; use super::const_evaluatable; use super::project; -use super::project::ProjectionTyObligation; +use super::project::ProjectionTermObligation; use super::util; use super::util::closure_trait_ref_and_return_type; use super::wf; @@ -808,7 +808,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ty::PredicateKind::Clause(ty::ClauseKind::Projection(data)) => { let data = bound_predicate.rebind(data); let project_obligation = obligation.with(self.tcx(), data); - match project::poly_project_and_unify_type(self, &project_obligation) { + match project::poly_project_and_unify_term(self, &project_obligation) { ProjectAndUnifyResult::Holds(mut subobligations) => { 'compute_res: { // If we've previously marked this projection as 'complete', then @@ -1733,7 +1733,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { /// in cases like #91762. pub(super) fn match_projection_projections( &mut self, - obligation: &ProjectionTyObligation<'tcx>, + obligation: &ProjectionTermObligation<'tcx>, env_predicate: PolyProjectionPredicate<'tcx>, potentially_unnormalized_candidates: bool, ) -> ProjectionMatchesProjection { @@ -1752,12 +1752,12 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { obligation.param_env, obligation.cause.clone(), obligation.recursion_depth + 1, - infer_predicate.projection_ty, + infer_predicate.projection_term, &mut nested_obligations, ) }) } else { - infer_predicate.projection_ty + infer_predicate.projection_term }; let is_match = self diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index 562a82cc73d65..8a0ce3c1f98b1 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -165,11 +165,8 @@ pub fn clause_obligations<'tcx>( wf.compute(ty.into()); } ty::ClauseKind::Projection(t) => { - wf.compute_alias(t.projection_ty); - wf.compute(match t.term.unpack() { - ty::TermKind::Ty(ty) => ty.into(), - ty::TermKind::Const(c) => c.into(), - }) + wf.compute_alias_term(t.projection_term); + wf.compute(t.term.into_arg()); } ty::ClauseKind::ConstArgHasType(ct, ty) => { wf.compute(ct.into()); @@ -439,7 +436,37 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { /// Pushes the obligations required for an alias (except inherent) to be WF /// into `self.out`. - fn compute_alias(&mut self, data: ty::AliasTy<'tcx>) { + fn compute_alias_ty(&mut self, data: ty::AliasTy<'tcx>) { + // A projection is well-formed if + // + // (a) its predicates hold (*) + // (b) its args are wf + // + // (*) The predicates of an associated type include the predicates of + // the trait that it's contained in. For example, given + // + // trait A: Clone { + // type X where T: Copy; + // } + // + // The predicates of `<() as A>::X` are: + // [ + // `(): Sized` + // `(): Clone` + // `(): A` + // `i32: Sized` + // `i32: Clone` + // `i32: Copy` + // ] + let obligations = self.nominal_obligations(data.def_id, data.args); + self.out.extend(obligations); + + self.compute_projection_args(data.args); + } + + /// Pushes the obligations required for an alias (except inherent) to be WF + /// into `self.out`. + fn compute_alias_term(&mut self, data: ty::AliasTerm<'tcx>) { // A projection is well-formed if // // (a) its predicates hold (*) @@ -698,7 +725,7 @@ impl<'a, 'tcx> TypeVisitor> for WfPredicates<'a, 'tcx> { } ty::Alias(ty::Projection | ty::Opaque | ty::Weak, data) => { - self.compute_alias(data); + self.compute_alias_ty(data); return; // Subtree handled by compute_projection. } ty::Alias(ty::Inherent, data) => { diff --git a/compiler/rustc_traits/src/normalize_projection_ty.rs b/compiler/rustc_traits/src/normalize_projection_ty.rs index 559c05eb3e784..fee13078250fd 100644 --- a/compiler/rustc_traits/src/normalize_projection_ty.rs +++ b/compiler/rustc_traits/src/normalize_projection_ty.rs @@ -34,14 +34,8 @@ fn normalize_canonicalized_projection_ty<'tcx>( let selcx = &mut SelectionContext::new(ocx.infcx); let cause = ObligationCause::dummy(); let mut obligations = vec![]; - let answer = traits::normalize_projection_type( - selcx, - param_env, - goal, - cause, - 0, - &mut obligations, - ); + let answer = + traits::normalize_projection_ty(selcx, param_env, goal, cause, 0, &mut obligations); ocx.register_obligations(obligations); // #112047: With projections and opaques, we are able to create opaques that // are recursive (given some generic parameters of the opaque's type variables). diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index fa1085c7cd79a..87fcd3602e016 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -214,7 +214,7 @@ impl<'tcx> TypeVisitor> for ImplTraitInTraitFinder<'_, 'tcx> { self.predicates.push( ty::Binder::bind_with_vars( ty::ProjectionPredicate { - projection_ty: shifted_alias_ty, + projection_term: shifted_alias_ty.into(), term: default_ty.into(), }, self.bound_vars, diff --git a/compiler/rustc_type_ir/src/inherent.rs b/compiler/rustc_type_ir/src/inherent.rs index a50967a3b182a..5e98163643893 100644 --- a/compiler/rustc_type_ir/src/inherent.rs +++ b/compiler/rustc_type_ir/src/inherent.rs @@ -90,8 +90,7 @@ pub trait BoundVars { fn has_no_bound_vars(&self) -> bool; } -// FIXME: Uplift `AliasTy` -pub trait AliasTy: Copy + DebugWithInfcx + Hash + Eq + Sized { +pub trait AliasTerm: Copy + DebugWithInfcx + Hash + Eq + Sized { fn new( interner: I, trait_def_id: I::DefId, diff --git a/compiler/rustc_type_ir/src/interner.rs b/compiler/rustc_type_ir/src/interner.rs index 17d9f4242fdfa..af0e833b9e983 100644 --- a/compiler/rustc_type_ir/src/interner.rs +++ b/compiler/rustc_type_ir/src/interner.rs @@ -39,7 +39,7 @@ pub trait Interner: // Kinds of tys type Ty: Ty; type Tys: Copy + Debug + Hash + Eq + IntoIterator; - type AliasTy: AliasTy; + type AliasTy: Copy + DebugWithInfcx + Hash + Eq + Sized; type ParamTy: Copy + Debug + Hash + Eq; type BoundTy: Copy + Debug + Hash + Eq; type PlaceholderTy: PlaceholderLike; @@ -74,6 +74,7 @@ pub trait Interner: type RegionOutlivesPredicate: Copy + Debug + Hash + Eq; type TypeOutlivesPredicate: Copy + Debug + Hash + Eq; type ProjectionPredicate: Copy + Debug + Hash + Eq; + type AliasTerm: AliasTerm; type NormalizesTo: Copy + Debug + Hash + Eq; type SubtypePredicate: Copy + Debug + Hash + Eq; type CoercePredicate: Copy + Debug + Hash + Eq; diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs index 04cacd987d098..4560a54da82b3 100644 --- a/compiler/rustc_type_ir/src/lib.rs +++ b/compiler/rustc_type_ir/src/lib.rs @@ -54,7 +54,7 @@ pub use predicate_kind::*; pub use region_kind::*; pub use ty_info::*; pub use ty_kind::*; -pub use AliasKind::*; +pub use AliasTyKind::*; pub use DynKind::*; pub use InferTy::*; pub use RegionKind::*; diff --git a/compiler/rustc_type_ir/src/predicate.rs b/compiler/rustc_type_ir/src/predicate.rs index f84f8f47c6767..7f746492ea0dd 100644 --- a/compiler/rustc_type_ir/src/predicate.rs +++ b/compiler/rustc_type_ir/src/predicate.rs @@ -1,6 +1,7 @@ use std::fmt; -use rustc_macros::{HashStable_NoContext, TyDecodable, TyEncodable}; +#[cfg(feature = "nightly")] +use rustc_macros::{Decodable, Encodable, HashStable_NoContext, TyDecodable, TyEncodable}; use rustc_type_ir_macros::{Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic}; use crate::inherent::*; @@ -283,7 +284,7 @@ impl ExistentialProjection { debug_assert!(!self_ty.has_escaping_bound_vars()); ProjectionPredicate { - projection_ty: I::AliasTy::new( + projection_term: I::AliasTerm::new( tcx, self.def_id, [self_ty.into()].into_iter().chain(self.args), @@ -294,16 +295,47 @@ impl ExistentialProjection { pub fn erase_self_ty(tcx: I, projection_predicate: ProjectionPredicate) -> Self { // Assert there is a Self. - projection_predicate.projection_ty.args().type_at(0); + projection_predicate.projection_term.args().type_at(0); Self { - def_id: projection_predicate.projection_ty.def_id(), - args: tcx.mk_args(&projection_predicate.projection_ty.args()[1..]), + def_id: projection_predicate.projection_term.def_id(), + args: tcx.mk_args(&projection_predicate.projection_term.args()[1..]), term: projection_predicate.term, } } } +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] +#[cfg_attr(feature = "nightly", derive(Encodable, Decodable, HashStable_NoContext))] +pub enum AliasTermKind { + /// A projection `::AssocType`. + /// Can get normalized away if monomorphic enough. + ProjectionTy, + /// An associated type in an inherent `impl` + InherentTy, + /// An opaque type (usually from `impl Trait` in type aliases or function return types) + /// Can only be normalized away in RevealAll mode + OpaqueTy, + /// A type alias that actually checks its trait bounds. + /// Currently only used if the type alias references opaque types. + /// Can always be normalized away. + WeakTy, + /// UwU + UnevaluatedConst, +} + +impl AliasTermKind { + pub fn descr(self) -> &'static str { + match self { + AliasTermKind::ProjectionTy => "associated type", + AliasTermKind::InherentTy => "inherent associated type", + AliasTermKind::OpaqueTy => "opaque type", + AliasTermKind::WeakTy => "type alias", + AliasTermKind::UnevaluatedConst => "unevaluated constant", + } + } +} + /// This kind of predicate has no *direct* correspondent in the /// syntax, but it roughly corresponds to the syntactic forms: /// @@ -327,31 +359,31 @@ impl ExistentialProjection { #[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)] #[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))] pub struct ProjectionPredicate { - pub projection_ty: I::AliasTy, + pub projection_term: I::AliasTerm, pub term: I::Term, } impl ProjectionPredicate { pub fn self_ty(self) -> I::Ty { - self.projection_ty.self_ty() + self.projection_term.self_ty() } pub fn with_self_ty(self, tcx: I, self_ty: I::Ty) -> ProjectionPredicate { - Self { projection_ty: self.projection_ty.with_self_ty(tcx, self_ty), ..self } + Self { projection_term: self.projection_term.with_self_ty(tcx, self_ty), ..self } } pub fn trait_def_id(self, tcx: I) -> I::DefId { - self.projection_ty.trait_def_id(tcx) + self.projection_term.trait_def_id(tcx) } pub fn def_id(self) -> I::DefId { - self.projection_ty.def_id() + self.projection_term.def_id() } } impl fmt::Debug for ProjectionPredicate { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "ProjectionPredicate({:?}, {:?})", self.projection_ty, self.term) + write!(f, "ProjectionPredicate({:?}, {:?})", self.projection_term, self.term) } } @@ -368,7 +400,7 @@ impl fmt::Debug for ProjectionPredicate { #[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)] #[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))] pub struct NormalizesTo { - pub alias: I::AliasTy, + pub alias: I::AliasTerm, pub term: I::Term, } diff --git a/compiler/rustc_type_ir/src/ty_kind.rs b/compiler/rustc_type_ir/src/ty_kind.rs index d67327926ff3b..6e544d0e6ace4 100644 --- a/compiler/rustc_type_ir/src/ty_kind.rs +++ b/compiler/rustc_type_ir/src/ty_kind.rs @@ -31,7 +31,7 @@ pub enum DynKind { #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] #[cfg_attr(feature = "nightly", derive(Encodable, Decodable, HashStable_NoContext))] -pub enum AliasKind { +pub enum AliasTyKind { /// A projection `::AssocType`. /// Can get normalized away if monomorphic enough. Projection, @@ -46,13 +46,13 @@ pub enum AliasKind { Weak, } -impl AliasKind { +impl AliasTyKind { pub fn descr(self) -> &'static str { match self { - AliasKind::Projection => "associated type", - AliasKind::Inherent => "inherent associated type", - AliasKind::Opaque => "opaque type", - AliasKind::Weak => "type alias", + AliasTyKind::Projection => "associated type", + AliasTyKind::Inherent => "inherent associated type", + AliasTyKind::Opaque => "opaque type", + AliasTyKind::Weak => "type alias", } } } @@ -201,7 +201,7 @@ pub enum TyKind { /// A projection, opaque type, weak type alias, or inherent associated type. /// All of these types are represented as pairs of def-id and args, and can /// be normalized, so they are grouped conceptually. - Alias(AliasKind, I::AliasTy), + Alias(AliasTyKind, I::AliasTy), /// A type parameter; for example, `T` in `fn f(x: T) {}`. Param(I::ParamTy), diff --git a/compiler/stable_mir/src/ty.rs b/compiler/stable_mir/src/ty.rs index bc6fb34493a6c..562516138404b 100644 --- a/compiler/stable_mir/src/ty.rs +++ b/compiler/stable_mir/src/ty.rs @@ -897,6 +897,12 @@ pub struct AliasTy { pub args: GenericArgs, } +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct AliasTerm { + pub def_id: AliasDef, + pub args: GenericArgs, +} + pub type PolyFnSig = Binder; #[derive(Clone, Debug, Eq, PartialEq)] @@ -1350,7 +1356,7 @@ pub type TypeOutlivesPredicate = OutlivesPredicate; #[derive(Clone, Debug, Eq, PartialEq)] pub struct ProjectionPredicate { - pub projection_ty: AliasTy, + pub projection_term: AliasTerm, pub term: TermKind, } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 90f2e3d09fe86..0ab23d159a6cd 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -453,7 +453,15 @@ fn clean_projection_predicate<'tcx>( cx: &mut DocContext<'tcx>, ) -> WherePredicate { WherePredicate::EqPredicate { - lhs: clean_projection(pred.map_bound(|p| p.projection_ty), cx, None), + lhs: clean_projection( + pred.map_bound(|p| { + // FIXME: This needs to be made resilient for `AliasTerm`s that + // are associated consts. + p.projection_term.expect_ty(cx.tcx) + }), + cx, + None, + ), rhs: clean_middle_term(pred.map_bound(|p| p.term), cx), } } @@ -838,7 +846,7 @@ fn clean_ty_generics<'tcx>( } } ty::ClauseKind::Projection(p) => { - if let ty::Param(param) = p.projection_ty.self_ty().kind() { + if let ty::Param(param) = p.projection_term.self_ty().kind() { projection = Some(bound_p.rebind(p)); return Some(param.index); } @@ -857,7 +865,15 @@ fn clean_ty_generics<'tcx>( bounds.extend(pred.get_bounds().into_iter().flatten().cloned()); if let Some(proj) = projection - && let lhs = clean_projection(proj.map_bound(|p| p.projection_ty), cx, None) + && let lhs = clean_projection( + proj.map_bound(|p| { + // FIXME: This needs to be made resilient for `AliasTerm`s that + // are associated consts. + p.projection_term.expect_ty(cx.tcx) + }), + cx, + None, + ) && let Some((_, trait_did, name)) = lhs.projection() { impl_trait_proj.entry(param_idx).or_default().push(( @@ -2126,7 +2142,10 @@ pub(crate) fn clean_middle_ty<'tcx>( // HACK(compiler-errors): Doesn't actually matter what self // type we put here, because we're only using the GAT's args. .with_self_ty(cx.tcx, cx.tcx.types.self_param) - .projection_ty + .projection_term + // FIXME: This needs to be made resilient for `AliasTerm`s + // that are associated consts. + .expect_ty(cx.tcx) }), cx, ), @@ -2284,10 +2303,12 @@ fn clean_middle_opaque_bounds<'tcx>( .iter() .filter_map(|bound| { if let ty::ClauseKind::Projection(proj) = bound.kind().skip_binder() { - if proj.projection_ty.trait_ref(cx.tcx) == trait_ref.skip_binder() { + if proj.projection_term.trait_ref(cx.tcx) == trait_ref.skip_binder() { Some(TypeBinding { assoc: projection_to_path_segment( - bound.kind().rebind(proj.projection_ty), + // FIXME: This needs to be made resilient for `AliasTerm`s that + // are associated consts. + bound.kind().rebind(proj.projection_term.expect_ty(cx.tcx)), cx, ), kind: TypeBindingKind::Equality { diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs index d3347466be982..ae9aa83efd685 100644 --- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs +++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs @@ -417,7 +417,7 @@ fn get_input_traits_and_projections<'tcx>( } }, ClauseKind::Projection(projection_predicate) => { - if projection_predicate.projection_ty.self_ty() == input { + if projection_predicate.projection_term.self_ty() == input { projection_predicates.push(projection_predicate); } }, diff --git a/src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs b/src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs index e6c6a15b8d48a..8de5caf32b740 100644 --- a/src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs +++ b/src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs @@ -320,11 +320,11 @@ fn is_mixed_projection_predicate<'tcx>( && (term_param_ty.index as usize) < generics.parent_count { // The inner-most self type is a type parameter from the current function. - let mut projection_ty = projection_predicate.projection_ty; + let mut projection_ty = projection_predicate.projection_term; loop { - match projection_ty.self_ty().kind() { + match *projection_ty.self_ty().kind() { ty::Alias(ty::Projection, inner_projection_ty) => { - projection_ty = *inner_projection_ty; + projection_ty = inner_projection_ty.into(); }, ty::Param(param_ty) => { return (param_ty.index as usize) >= generics.parent_count; @@ -404,14 +404,11 @@ fn replace_types<'tcx>( // The `replaced.insert(...)` check provides some protection against infinite loops. if replaced.insert(param_ty.index) { for projection_predicate in projection_predicates { - if projection_predicate.projection_ty.self_ty() == param_ty.to_ty(cx.tcx) + if projection_predicate.projection_term.self_ty() == param_ty.to_ty(cx.tcx) && let Some(term_ty) = projection_predicate.term.ty() && let ty::Param(term_param_ty) = term_ty.kind() { - let projection = cx.tcx.mk_ty_from_kind(ty::Alias( - ty::Projection, - projection_predicate.projection_ty.with_self_ty(cx.tcx, new_ty), - )); + let projection = projection_predicate.projection_term.with_self_ty(cx.tcx, new_ty).expect_ty(cx.tcx).to_ty(cx.tcx); if let Ok(projected_ty) = cx.tcx.try_normalize_erasing_regions(cx.param_env, projection) && args[term_param_ty.index as usize] != GenericArg::from(projected_ty) diff --git a/src/tools/clippy/clippy_lints/src/unit_return_expecting_ord.rs b/src/tools/clippy/clippy_lints/src/unit_return_expecting_ord.rs index 214b69dc9250b..f0d1458a59b25 100644 --- a/src/tools/clippy/clippy_lints/src/unit_return_expecting_ord.rs +++ b/src/tools/clippy/clippy_lints/src/unit_return_expecting_ord.rs @@ -66,7 +66,7 @@ fn get_projection_pred<'tcx>( let projection_pred = cx .tcx .instantiate_bound_regions_with_erased(proj_pred.kind().rebind(pred)); - if projection_pred.projection_ty.args == trait_pred.trait_ref.args { + if projection_pred.projection_term.args == trait_pred.trait_ref.args { return Some(projection_pred); } } diff --git a/src/tools/clippy/clippy_utils/src/ty.rs b/src/tools/clippy/clippy_utils/src/ty.rs index 97bba8648c5f5..e3ab42c3107c5 100644 --- a/src/tools/clippy/clippy_utils/src/ty.rs +++ b/src/tools/clippy/clippy_utils/src/ty.rs @@ -795,7 +795,7 @@ fn sig_from_bounds<'tcx>( inputs = Some(i); }, ty::ClauseKind::Projection(p) - if Some(p.projection_ty.def_id) == lang_items.fn_once_output() && p.projection_ty.self_ty() == ty => + if Some(p.projection_term.def_id) == lang_items.fn_once_output() && p.projection_term.self_ty() == ty => { if output.is_some() { // Multiple different fn trait impls. Is this even allowed? @@ -834,7 +834,7 @@ fn sig_for_projection<'tcx>(cx: &LateContext<'tcx>, ty: AliasTy<'tcx>) -> Option } inputs = Some(i); }, - ty::ClauseKind::Projection(p) if Some(p.projection_ty.def_id) == lang_items.fn_once_output() => { + ty::ClauseKind::Projection(p) if Some(p.projection_term.def_id) == lang_items.fn_once_output() => { if output.is_some() { // Multiple different fn trait impls. Is this even allowed? return None; From 293b5cb1caa32487d986c052c4d72cd1fde9f250 Mon Sep 17 00:00:00 2001 From: Joshua Liebow-Feeser Date: Thu, 12 Oct 2023 15:17:18 -0700 Subject: [PATCH 162/179] [ptr] Document maximum allocation size --- library/core/src/ptr/mod.rs | 38 ++++++++++++++++++++++++++++++++----- 1 file changed, 33 insertions(+), 5 deletions(-) diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs index 5039ff53d0313..0ff44478d3563 100644 --- a/library/core/src/ptr/mod.rs +++ b/library/core/src/ptr/mod.rs @@ -59,11 +59,39 @@ //! //! ## Allocated object //! -//! For several operations, such as [`offset`] or field projections (`expr.field`), the notion of an -//! "allocated object" becomes relevant. An allocated object is a contiguous region of memory. -//! Common examples of allocated objects include stack-allocated variables (each variable is a -//! separate allocated object), heap allocations (each allocation created by the global allocator is -//! a separate allocated object), and `static` variables. +//! An *allocated object* is a subset of program memory which is addressable +//! from Rust, and within which pointer arithmetic is possible. Examples of +//! allocated objects include heap allocations, stack-allocated variables, +//! statics, and consts. The safety preconditions of some Rust operations - +//! such as `offset` and field projections (`expr.field`) - are defined in +//! terms of the allocated objects on which they operate. +//! +//! An allocated object has a base address, a size, and a set of memory +//! addresses. It is possible for an allocated object to have zero size, but +//! such an allocated object will still have a base address. The base address +//! of an allocated object is not necessarily unique. While it is currently the +//! case that an allocated object always has a set of memory addresses which is +//! fully contiguous (i.e., has no "holes"), there is no guarantee that this +//! will not change in the future. +//! +//! For any allocated object with `base` address, `size`, and a set of +//! `addresses`, the following are guaranteed: +//! - For all addresses `a` in `addresses`, `a` is in the range `base .. (base + +//! size)` (note that this requires `a < base + size`, not `a <= base + size`) +//! - `base` is not equal to [`null()`] (i.e., the address with the numerical +//! value 0) +//! - `base + size <= usize::MAX` +//! - `size <= isize::MAX` +//! +//! As a consequence of these guarantees, given any address `a` within the set +//! of addresses of an allocated object: +//! - It is guaranteed that `a - base` does not overflow `isize` +//! - It is guaranteed that `a - base` is non-negative +//! - It is guaranteed that, given `o = a - base` (i.e., the offset of `a` within +//! the allocated object), `base + o` will not wrap around the address space (in +//! other words, will not overflow `usize`) +//! +//! [`null()`]: null //! //! # Strict Provenance //! From 58ee9192e08e8394da6a3bfa3c26eb315213b77a Mon Sep 17 00:00:00 2001 From: Erick Tryzelaar Date: Mon, 13 May 2024 20:13:48 +0000 Subject: [PATCH 163/179] Migrate fuchsia docs from `pm` to `ffx` The `pm` tool has been deprecated, so this migrates the fuchsia documentation to the new `ffx` based tooling. --- src/doc/rustc/src/platform-support/fuchsia.md | 25 ++++++++----------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/src/doc/rustc/src/platform-support/fuchsia.md b/src/doc/rustc/src/platform-support/fuchsia.md index 9c2e05b57f5e8..3e1db692f50be 100644 --- a/src/doc/rustc/src/platform-support/fuchsia.md +++ b/src/doc/rustc/src/platform-support/fuchsia.md @@ -387,7 +387,7 @@ meta/hello_fuchsia.cm=pkg/meta/hello_fuchsia.cm ``` *Note: Relative manifest paths are resolved starting from the working directory -of `pm`. Make sure to fill out `` with the path to the downloaded +of `ffx`. Make sure to fill out `` with the path to the downloaded SDK.* The `.manifest` file will be used to describe the contents of the package by @@ -459,12 +459,10 @@ hello_fuchsia/ Next, we'll build a package manifest as defined by our manifest: ```sh -${SDK_PATH}/tools/${ARCH}/pm \ - -api-level $(${SDK_PATH}/tools/${ARCH}/ffx version -v | grep "api-level" | head -1 | awk -F ' ' '{print $2}') \ - -o pkg/hello_fuchsia_manifest \ - -m pkg/hello_fuchsia.manifest \ - build \ - -output-package-manifest pkg/hello_fuchsia_package_manifest +${SDK_PATH}/tools/${ARCH}/ffx package build \ + --api-level $(${SDK_PATH}/tools/${ARCH}/ffx --machine json version | jq .tool_version.api_level) \ + --out pkg/hello_fuchsia_manifest \ + pkg/hello_fuchsia.manifest ``` This will produce `pkg/hello_fuchsia_manifest/` which is a package manifest we can @@ -498,8 +496,7 @@ to. We can set up our repository with: ```sh -${SDK_PATH}/tools/${ARCH}/pm newrepo \ - -repo pkg/repo +${SDK_PATH}/tools/${ARCH}/ffx repository create pkg/repo ``` **Current directory structure** @@ -523,17 +520,17 @@ hello_fuchsia/ We can publish our new package to that repository with: ```sh -${SDK_PATH}/tools/${ARCH}/pm publish \ - -repo pkg/repo \ - -lp -f <(echo "pkg/hello_fuchsia_package_manifest") +${SDK_PATH}/tools/${ARCH}/ffx repository publish \ + --package pkg/hello_fuchsia_package_manifest \ + pkg/repo ``` Then we can add the repository to `ffx`'s package server as `hello-fuchsia` using: ```sh ${SDK_PATH}/tools/${ARCH}/ffx repository add-from-pm \ - pkg/repo \ - -r hello-fuchsia + --repository hello-fuchsia \ + pkg/repo ``` ## Running a Fuchsia component on an emulator From fa84018c2ef0aa35e46f11dce87f3e0410fae9a4 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 13 May 2024 14:34:47 -0400 Subject: [PATCH 164/179] Apply nits --- .../src/hir_ty_lowering/bounds.rs | 3 -- .../src/hir_ty_lowering/errors.rs | 18 +++----- .../src/impl_wf_check/min_specialization.rs | 11 ++--- .../rustc_hir_typeck/src/method/suggest.rs | 9 +--- compiler/rustc_infer/src/traits/project.rs | 13 +++--- compiler/rustc_middle/src/ty/mod.rs | 1 - compiler/rustc_middle/src/ty/print/pretty.rs | 3 +- compiler/rustc_middle/src/ty/relate.rs | 19 ++++---- compiler/rustc_middle/src/ty/sty.rs | 43 ++++++++++--------- .../rustc_smir/src/rustc_smir/convert/ty.rs | 4 +- .../src/traits/project.rs | 6 +-- .../rustc_trait_selection/src/traits/wf.rs | 26 +---------- compiler/rustc_type_ir/src/predicate.rs | 5 ++- .../src/needless_borrows_for_generic_args.rs | 6 +-- .../inline_cross/assoc-const-equality.rs | 1 + tests/ui/associated-consts/issue-105330.rs | 4 +- .../ui/associated-consts/issue-105330.stderr | 38 +++------------- 17 files changed, 73 insertions(+), 137 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs index 41e3abd7451f1..84e804160c4d1 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs @@ -421,9 +421,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { ); debug!(?alias_args); - // Note that we're indeed also using `AliasTy` (alias *type*) for associated - // *constants* to represent *const projections*. Alias *term* would be a more - // appropriate name but alas. ty::AliasTerm::new(tcx, assoc_item.def_id, alias_args) }); diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs index 8f68a670d01d3..4158b24f11da5 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs @@ -625,22 +625,14 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let bound_predicate = pred.kind(); match bound_predicate.skip_binder() { ty::PredicateKind::Clause(ty::ClauseKind::Projection(pred)) => { - let pred = bound_predicate.rebind(pred); // `::Item = String`. - let projection_term = pred.skip_binder().projection_term; - - let args_with_infer_self = tcx.mk_args_from_iter( - std::iter::once(Ty::new_var(tcx, ty::TyVid::ZERO).into()) - .chain(projection_term.args.iter().skip(1)), - ); - - let quiet_projection_ty = - ty::AliasTerm::new(tcx, projection_term.def_id, args_with_infer_self); - - let term = pred.skip_binder().term; + let projection_term = pred.projection_term; + let quiet_projection_term = + projection_term.with_self_ty(tcx, Ty::new_var(tcx, ty::TyVid::ZERO)); + let term = pred.term; let obligation = format!("{projection_term} = {term}"); - let quiet = format!("{quiet_projection_ty} = {term}"); + let quiet = format!("{quiet_projection_term} = {term}"); bound_span_label(projection_term.self_ty(), &obligation, &quiet); Some((obligation, projection_term.self_ty())) diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs index 61357d6504c90..6967cb4d9d0b9 100644 --- a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs +++ b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs @@ -258,23 +258,20 @@ fn unconstrained_parent_impl_args<'tcx>( // unconstrained parameters. for (clause, _) in impl_generic_predicates.predicates.iter() { if let ty::ClauseKind::Projection(proj) = clause.kind().skip_binder() { - let projection_term = proj.projection_term; - let projected_term = proj.term; - - let unbound_trait_ref = projection_term.trait_ref(tcx); + let unbound_trait_ref = proj.projection_term.trait_ref(tcx); if Some(unbound_trait_ref) == impl_trait_ref { continue; } - unconstrained_parameters.extend(cgp::parameters_for(tcx, projection_term, true)); + unconstrained_parameters.extend(cgp::parameters_for(tcx, proj.projection_term, true)); - for param in cgp::parameters_for(tcx, projected_term, false) { + for param in cgp::parameters_for(tcx, proj.term, false) { if !unconstrained_parameters.contains(¶m) { constrained_params.insert(param.0); } } - unconstrained_parameters.extend(cgp::parameters_for(tcx, projected_term, true)); + unconstrained_parameters.extend(cgp::parameters_for(tcx, proj.term, true)); } } diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 6d931d15008a6..aff9b75b25374 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -46,7 +46,6 @@ use std::borrow::Cow; use super::probe::{AutorefOrPtrAdjustment, IsSuggestion, Mode, ProbeScope}; use super::{CandidateSource, MethodError, NoMatchData}; use rustc_hir::intravisit::Visitor; -use std::iter; impl<'a, 'tcx> FnCtxt<'a, 'tcx> { fn is_fn_ty(&self, ty: Ty<'tcx>, span: Span) -> bool { @@ -788,14 +787,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let pred = bound_predicate.rebind(pred); // `::Item = String`. let projection_term = pred.skip_binder().projection_term; - - let args_with_infer_self = tcx.mk_args_from_iter( - iter::once(Ty::new_var(tcx, ty::TyVid::ZERO).into()) - .chain(projection_term.args.iter().skip(1)), - ); - let quiet_projection_term = - ty::AliasTerm::new(tcx, projection_term.def_id, args_with_infer_self); + projection_term.with_self_ty(tcx, Ty::new_var(tcx, ty::TyVid::ZERO)); let term = pred.skip_binder().term; diff --git a/compiler/rustc_infer/src/traits/project.rs b/compiler/rustc_infer/src/traits/project.rs index c1cfa5ca6b7c8..b696264aab03e 100644 --- a/compiler/rustc_infer/src/traits/project.rs +++ b/compiler/rustc_infer/src/traits/project.rs @@ -93,7 +93,7 @@ pub enum ProjectionCacheEntry<'tcx> { Ambiguous, Recur, Error, - NormalizedTy { + NormalizedTerm { ty: NormalizedTerm<'tcx>, /// If we were able to successfully evaluate the /// corresponding cache entry key during predicate @@ -186,7 +186,7 @@ impl<'tcx> ProjectionCache<'_, 'tcx> { return; } let fresh_key = - map.insert(key, ProjectionCacheEntry::NormalizedTy { ty: value, complete: None }); + map.insert(key, ProjectionCacheEntry::NormalizedTerm { ty: value, complete: None }); assert!(!fresh_key, "never started projecting `{key:?}`"); } @@ -197,13 +197,16 @@ impl<'tcx> ProjectionCache<'_, 'tcx> { pub fn complete(&mut self, key: ProjectionCacheKey<'tcx>, result: EvaluationResult) { let mut map = self.map(); match map.get(&key) { - Some(ProjectionCacheEntry::NormalizedTy { ty, complete: _ }) => { + Some(ProjectionCacheEntry::NormalizedTerm { ty, complete: _ }) => { info!("ProjectionCacheEntry::complete({:?}) - completing {:?}", key, ty); let mut ty = ty.clone(); if result.must_apply_considering_regions() { ty.obligations = vec![]; } - map.insert(key, ProjectionCacheEntry::NormalizedTy { ty, complete: Some(result) }); + map.insert( + key, + ProjectionCacheEntry::NormalizedTerm { ty, complete: Some(result) }, + ); } ref value => { // Type inference could "strand behind" old cache entries. Leave @@ -215,7 +218,7 @@ impl<'tcx> ProjectionCache<'_, 'tcx> { pub fn is_complete(&mut self, key: ProjectionCacheKey<'tcx>) -> Option { self.map().get(&key).and_then(|res| match res { - ProjectionCacheEntry::NormalizedTy { ty: _, complete } => *complete, + ProjectionCacheEntry::NormalizedTerm { ty: _, complete } => *complete, _ => None, }) } diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 02f6f4da4f169..dc5e881843a54 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -629,7 +629,6 @@ impl<'tcx> Term<'tcx> { } } - /// This function returns the inner `AliasTy` for a `ty::Alias` or `ConstKind::Unevaluated`. pub fn to_alias_term(self) -> Option> { match self.unpack() { TermKind::Ty(ty) => match *ty.kind() { diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index edd5bef33d5ec..8d8ed70a7574d 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -3216,7 +3216,8 @@ define_print_and_forward_display! { ty::AliasTermKind::ProjectionTy | ty::AliasTermKind::WeakTy | ty::AliasTermKind::OpaqueTy - | ty::AliasTermKind::UnevaluatedConst => { + | ty::AliasTermKind::UnevaluatedConst + | ty::AliasTermKind::ProjectionConst => { // If we're printing verbosely, or don't want to invoke queries // (`is_impl_trait_in_trait`), then fall back to printing the def path. // This is likely what you want if you're debugging the compiler anyways. diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs index 32d420f96a210..eaf5fdf57109c 100644 --- a/compiler/rustc_middle/src/ty/relate.rs +++ b/compiler/rustc_middle/src/ty/relate.rs @@ -10,7 +10,6 @@ use crate::ty::{ GenericArgKind, GenericArgsRef, ImplSubject, Term, TermKind, Ty, TyCtxt, TypeFoldable, }; use rustc_hir as hir; -use rustc_hir::def::DefKind; use rustc_hir::def_id::DefId; use rustc_macros::TypeVisitable; use rustc_target::spec::abi; @@ -227,8 +226,8 @@ impl<'tcx> Relate<'tcx> for ty::AliasTy<'tcx> { if a.def_id != b.def_id { Err(TypeError::ProjectionMismatched(expected_found(a.def_id, b.def_id))) } else { - let args = match relation.tcx().def_kind(a.def_id) { - DefKind::OpaqueTy => relate_args_with_variances( + let args = match a.kind(relation.tcx()) { + ty::Opaque => relate_args_with_variances( relation, a.def_id, relation.tcx().variances_of(a.def_id), @@ -236,10 +235,9 @@ impl<'tcx> Relate<'tcx> for ty::AliasTy<'tcx> { b.args, false, // do not fetch `type_of(a_def_id)`, as it will cause a cycle )?, - DefKind::AssocTy | DefKind::AssocConst | DefKind::TyAlias => { + ty::Projection | ty::Weak | ty::Inherent => { relate_args_invariantly(relation, a.args, b.args)? } - def => bug!("unknown alias DefKind: {def:?}"), }; Ok(ty::AliasTy::new(relation.tcx(), a.def_id, args)) } @@ -255,8 +253,8 @@ impl<'tcx> Relate<'tcx> for ty::AliasTerm<'tcx> { if a.def_id != b.def_id { Err(TypeError::ProjectionMismatched(expected_found(a.def_id, b.def_id))) } else { - let args = match relation.tcx().def_kind(a.def_id) { - DefKind::OpaqueTy => relate_args_with_variances( + let args = match a.kind(relation.tcx()) { + ty::AliasTermKind::OpaqueTy => relate_args_with_variances( relation, a.def_id, relation.tcx().variances_of(a.def_id), @@ -264,10 +262,13 @@ impl<'tcx> Relate<'tcx> for ty::AliasTerm<'tcx> { b.args, false, // do not fetch `type_of(a_def_id)`, as it will cause a cycle )?, - DefKind::AssocTy | DefKind::AssocConst | DefKind::TyAlias => { + ty::AliasTermKind::ProjectionTy + | ty::AliasTermKind::WeakTy + | ty::AliasTermKind::InherentTy + | ty::AliasTermKind::UnevaluatedConst + | ty::AliasTermKind::ProjectionConst => { relate_args_invariantly(relation, a.args, b.args)? } - def => bug!("unknown alias DefKind: {def:?}"), }; Ok(ty::AliasTerm::new(relation.tcx(), a.def_id, args)) } diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 7aca09c5cfbcb..163016332475e 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -22,7 +22,7 @@ use rustc_span::symbol::{sym, Symbol}; use rustc_span::{Span, DUMMY_SP}; use rustc_target::abi::{FieldIdx, VariantIdx, FIRST_VARIANT}; use rustc_target::spec::abi::{self, Abi}; -use std::assert_matches::{assert_matches, debug_assert_matches}; +use std::assert_matches::debug_assert_matches; use std::borrow::Cow; use std::iter; use std::ops::{ControlFlow, Deref, Range}; @@ -1137,8 +1137,8 @@ pub struct AliasTerm<'tcx> { /// aka. `tcx.parent(def_id)`. pub def_id: DefId, - /// This field exists to prevent the creation of `AliasTy` without using - /// [AliasTy::new]. + /// This field exists to prevent the creation of `AliasTerm` without using + /// [AliasTerm::new]. _use_alias_term_new_instead: (), } @@ -1202,13 +1202,15 @@ impl<'tcx> AliasTerm<'tcx> { } pub fn expect_ty(self, tcx: TyCtxt<'tcx>) -> AliasTy<'tcx> { - assert_matches!( - self.kind(tcx), + match self.kind(tcx) { ty::AliasTermKind::ProjectionTy - | ty::AliasTermKind::OpaqueTy - | ty::AliasTermKind::WeakTy - | ty::AliasTermKind::InherentTy - ); + | ty::AliasTermKind::InherentTy + | ty::AliasTermKind::OpaqueTy + | ty::AliasTermKind::WeakTy => {} + ty::AliasTermKind::UnevaluatedConst | ty::AliasTermKind::ProjectionConst => { + bug!("Cannot turn `UnevaluatedConst` into `AliasTy`") + } + } ty::AliasTy { def_id: self.def_id, args: self.args, _use_alias_ty_new_instead: () } } @@ -1223,13 +1225,14 @@ impl<'tcx> AliasTerm<'tcx> { } DefKind::OpaqueTy => ty::AliasTermKind::OpaqueTy, DefKind::TyAlias => ty::AliasTermKind::WeakTy, - DefKind::AssocConst | DefKind::AnonConst => ty::AliasTermKind::UnevaluatedConst, + DefKind::AnonConst => ty::AliasTermKind::UnevaluatedConst, + DefKind::AssocConst => ty::AliasTermKind::ProjectionConst, kind => bug!("unexpected DefKind in AliasTy: {kind:?}"), } } } -/// The following methods work only with (trait) associated type projections. +/// The following methods work only with (trait) associated item projections. impl<'tcx> AliasTerm<'tcx> { pub fn self_ty(self) -> Ty<'tcx> { self.args.type_at(0) @@ -1269,7 +1272,6 @@ impl<'tcx> AliasTerm<'tcx> { self, tcx: TyCtxt<'tcx>, ) -> (ty::TraitRef<'tcx>, &'tcx [ty::GenericArg<'tcx>]) { - debug_assert!(matches!(tcx.def_kind(self.def_id), DefKind::AssocTy | DefKind::AssocConst)); let trait_def_id = self.trait_def_id(tcx); let trait_generics = tcx.generics_of(trait_def_id); ( @@ -1304,12 +1306,14 @@ impl<'tcx> AliasTerm<'tcx> { AliasTy { def_id: self.def_id, args: self.args, _use_alias_ty_new_instead: () }, ) .into(), - ty::AliasTermKind::UnevaluatedConst => ty::Const::new_unevaluated( - tcx, - ty::UnevaluatedConst::new(self.def_id, self.args), - tcx.type_of(self.def_id).instantiate(tcx, self.args), - ) - .into(), + ty::AliasTermKind::UnevaluatedConst | ty::AliasTermKind::ProjectionConst => { + ty::Const::new_unevaluated( + tcx, + ty::UnevaluatedConst::new(self.def_id, self.args), + tcx.type_of(self.def_id).instantiate(tcx, self.args), + ) + .into() + } } } } @@ -1358,7 +1362,7 @@ pub struct AliasTy<'tcx> { /// aka. `tcx.parent(def_id)`. pub def_id: DefId, - /// This field exists to prevent the creation of `AliasTy` without using + /// This field exists to prevent the creation of `AliasT` without using /// [AliasTy::new]. _use_alias_ty_new_instead: (), } @@ -1422,7 +1426,6 @@ impl<'tcx> AliasTy<'tcx> { self, tcx: TyCtxt<'tcx>, ) -> (ty::TraitRef<'tcx>, &'tcx [ty::GenericArg<'tcx>]) { - debug_assert!(matches!(tcx.def_kind(self.def_id), DefKind::AssocTy | DefKind::AssocConst)); let trait_def_id = self.trait_def_id(tcx); let trait_generics = tcx.generics_of(trait_def_id); ( diff --git a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs index ec44b4c16fec9..44737e6ce4057 100644 --- a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs +++ b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs @@ -723,9 +723,9 @@ impl<'tcx> Stable<'tcx> for ty::ProjectionPredicate<'tcx> { type T = stable_mir::ty::ProjectionPredicate; fn stable(&self, tables: &mut Tables<'_>) -> Self::T { - let ty::ProjectionPredicate { projection_term: projection_ty, term } = self; + let ty::ProjectionPredicate { projection_term, term } = self; stable_mir::ty::ProjectionPredicate { - projection_term: projection_ty.stable(tables), + projection_term: projection_term.stable(tables), term: term.unpack().stable(tables), } } diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index 20b5a81bb0ee3..f2daefaf04511 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -232,7 +232,7 @@ pub(super) fn poly_project_and_unify_term<'cx, 'tcx>( /// ``` /// If successful, this may result in additional obligations. /// -/// See [poly_project_and_unify_type] for an explanation of the return value. +/// See [poly_project_and_unify_term] for an explanation of the return value. #[instrument(level = "debug", skip(selcx))] fn project_and_unify_term<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, @@ -395,7 +395,7 @@ pub(super) fn opt_normalize_projection_term<'a, 'b, 'tcx>( debug!("recur cache"); return Err(InProgress); } - Err(ProjectionCacheEntry::NormalizedTy { ty, complete: _ }) => { + Err(ProjectionCacheEntry::NormalizedTerm { ty, complete: _ }) => { // This is the hottest path in this function. // // If we find the value in the cache, then return it along @@ -522,7 +522,7 @@ fn normalize_to_error<'a, 'tcx>( | ty::AliasTermKind::InherentTy | ty::AliasTermKind::OpaqueTy | ty::AliasTermKind::WeakTy => selcx.infcx.next_ty_var(cause.span).into(), - ty::AliasTermKind::UnevaluatedConst => selcx + ty::AliasTermKind::UnevaluatedConst | ty::AliasTermKind::ProjectionConst => selcx .infcx .next_const_var( selcx diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index 8a0ce3c1f98b1..36e3abf5eb2df 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -437,31 +437,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { /// Pushes the obligations required for an alias (except inherent) to be WF /// into `self.out`. fn compute_alias_ty(&mut self, data: ty::AliasTy<'tcx>) { - // A projection is well-formed if - // - // (a) its predicates hold (*) - // (b) its args are wf - // - // (*) The predicates of an associated type include the predicates of - // the trait that it's contained in. For example, given - // - // trait A: Clone { - // type X where T: Copy; - // } - // - // The predicates of `<() as A>::X` are: - // [ - // `(): Sized` - // `(): Clone` - // `(): A` - // `i32: Sized` - // `i32: Clone` - // `i32: Copy` - // ] - let obligations = self.nominal_obligations(data.def_id, data.args); - self.out.extend(obligations); - - self.compute_projection_args(data.args); + self.compute_alias_term(data.into()); } /// Pushes the obligations required for an alias (except inherent) to be WF diff --git a/compiler/rustc_type_ir/src/predicate.rs b/compiler/rustc_type_ir/src/predicate.rs index 7f746492ea0dd..71f198d2b8e84 100644 --- a/compiler/rustc_type_ir/src/predicate.rs +++ b/compiler/rustc_type_ir/src/predicate.rs @@ -320,14 +320,17 @@ pub enum AliasTermKind { /// Currently only used if the type alias references opaque types. /// Can always be normalized away. WeakTy, - /// UwU + /// An unevaluated const coming from a generic const expression. UnevaluatedConst, + /// An unevaluated const coming from an associated const. + ProjectionConst, } impl AliasTermKind { pub fn descr(self) -> &'static str { match self { AliasTermKind::ProjectionTy => "associated type", + AliasTermKind::ProjectionConst => "associated const", AliasTermKind::InherentTy => "inherent associated type", AliasTermKind::OpaqueTy => "opaque type", AliasTermKind::WeakTy => "type alias", diff --git a/src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs b/src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs index 8de5caf32b740..ae6cf992ef7b4 100644 --- a/src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs +++ b/src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs @@ -320,11 +320,11 @@ fn is_mixed_projection_predicate<'tcx>( && (term_param_ty.index as usize) < generics.parent_count { // The inner-most self type is a type parameter from the current function. - let mut projection_ty = projection_predicate.projection_term; + let mut projection_term = projection_predicate.projection_term; loop { - match *projection_ty.self_ty().kind() { + match *projection_term.self_ty().kind() { ty::Alias(ty::Projection, inner_projection_ty) => { - projection_ty = inner_projection_ty.into(); + projection_term = inner_projection_ty.into(); }, ty::Param(param_ty) => { return (param_ty.index as usize) >= generics.parent_count; diff --git a/tests/rustdoc/inline_cross/assoc-const-equality.rs b/tests/rustdoc/inline_cross/assoc-const-equality.rs index 89ed808de6208..cdf74389e764a 100644 --- a/tests/rustdoc/inline_cross/assoc-const-equality.rs +++ b/tests/rustdoc/inline_cross/assoc-const-equality.rs @@ -1,5 +1,6 @@ //@ aux-crate:assoc_const_equality=assoc-const-equality.rs //@ edition:2021 +//@ ignore-test (FIXME: #125092) #![crate_name = "user"] diff --git a/tests/ui/associated-consts/issue-105330.rs b/tests/ui/associated-consts/issue-105330.rs index fb2169ab43f2e..959bb4fe7aca4 100644 --- a/tests/ui/associated-consts/issue-105330.rs +++ b/tests/ui/associated-consts/issue-105330.rs @@ -11,7 +11,6 @@ impl TraitWAssocConst for impl Demo { //~ ERROR E0404 fn foo>() { //~ ERROR E0658 foo::()(); //~^ ERROR is not satisfied - //~| ERROR type mismatch //~| ERROR expected function, found `()` } @@ -19,6 +18,5 @@ fn main>() { //~^ ERROR E0658 //~| ERROR E0131 foo::(); - //~^ ERROR type mismatch - //~| ERROR is not satisfied + //~^ ERROR is not satisfied } diff --git a/tests/ui/associated-consts/issue-105330.stderr b/tests/ui/associated-consts/issue-105330.stderr index bde3675b48c03..725271935554c 100644 --- a/tests/ui/associated-consts/issue-105330.stderr +++ b/tests/ui/associated-consts/issue-105330.stderr @@ -26,7 +26,7 @@ LL | fn foo>() { = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: associated const equality is incomplete - --> $DIR/issue-105330.rs:18:29 + --> $DIR/issue-105330.rs:17:29 | LL | fn main>() { | ^^^^ @@ -44,7 +44,7 @@ LL | impl TraitWAssocConst for impl Demo { = note: `impl Trait` is only allowed in arguments and return types of functions and methods error[E0131]: `main` function is not allowed to have generic parameters - --> $DIR/issue-105330.rs:18:8 + --> $DIR/issue-105330.rs:17:8 | LL | fn main>() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `main` cannot have generic parameters @@ -61,20 +61,6 @@ note: required by a bound in `foo` LL | fn foo>() { | ^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `foo` -error[E0271]: type mismatch resolving `::A == 32` - --> $DIR/issue-105330.rs:12:11 - | -LL | foo::()(); - | ^^^^ expected `32`, found `::A` - | - = note: expected constant `32` - found constant `::A` -note: required by a bound in `foo` - --> $DIR/issue-105330.rs:11:28 - | -LL | fn foo>() { - | ^^^^ required by this bound in `foo` - error[E0618]: expected function, found `()` --> $DIR/issue-105330.rs:12:5 | @@ -86,7 +72,7 @@ LL | foo::()(); | call expression requires function error[E0277]: the trait bound `Demo: TraitWAssocConst` is not satisfied - --> $DIR/issue-105330.rs:21:11 + --> $DIR/issue-105330.rs:20:11 | LL | foo::(); | ^^^^ the trait `TraitWAssocConst` is not implemented for `Demo` @@ -97,21 +83,7 @@ note: required by a bound in `foo` LL | fn foo>() { | ^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `foo` -error[E0271]: type mismatch resolving `::A == 32` - --> $DIR/issue-105330.rs:21:11 - | -LL | foo::(); - | ^^^^ expected `32`, found `::A` - | - = note: expected constant `32` - found constant `::A` -note: required by a bound in `foo` - --> $DIR/issue-105330.rs:11:28 - | -LL | fn foo>() { - | ^^^^ required by this bound in `foo` - -error: aborting due to 11 previous errors +error: aborting due to 9 previous errors -Some errors have detailed explanations: E0131, E0271, E0277, E0404, E0562, E0618, E0658. +Some errors have detailed explanations: E0131, E0277, E0404, E0562, E0618, E0658. For more information about an error, try `rustc --explain E0131`. From 95e519ecbf343c5246b2777b64d223fcd0f68b4c Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 22 Apr 2024 19:46:51 +1000 Subject: [PATCH 165/179] Remove `NtIdent` and `NtLifetime`. The extra span is now recorded in the new `TokenKind::NtIdent` and `TokenKind::NtLifetime`. These both consist of a single token, and so there's no operator precedence problems with inserting them directly into the token stream. The other way to do this would be to wrap the ident/lifetime in invisible delimiters, but there's a lot of code that assumes an interpolated ident/lifetime fits in a single token, and changing all that code to work with invisible delimiters would have been a pain. (Maybe it could be done in a follow-up.) This change might not seem like much of a win, but it's a first step toward the much bigger and long-desired removal of `Nonterminal` and `TokenKind::Interpolated`. That change is big and complex enough that it's worth doing this piece separately. (Indeed, this commit is based on part of a late commit in #114647, a prior attempt at that big and complex change.) --- compiler/rustc_ast/src/ast_traits.rs | 2 - compiler/rustc_ast/src/mut_visit.rs | 8 +- compiler/rustc_ast/src/token.rs | 77 ++++++++----------- compiler/rustc_ast/src/tokenstream.rs | 25 +++--- compiler/rustc_ast_pretty/src/pprust/state.rs | 12 +-- compiler/rustc_expand/src/config.rs | 15 +++- compiler/rustc_expand/src/mbe/transcribe.rs | 10 +++ .../rustc_expand/src/proc_macro_server.rs | 23 ++++-- compiler/rustc_parse/src/parser/expr.rs | 4 +- compiler/rustc_parse/src/parser/mod.rs | 6 ++ .../rustc_parse/src/parser/nonterminal.rs | 53 ++++++------- 11 files changed, 131 insertions(+), 104 deletions(-) diff --git a/compiler/rustc_ast/src/ast_traits.rs b/compiler/rustc_ast/src/ast_traits.rs index a0486227f2afb..2cf811e9122f6 100644 --- a/compiler/rustc_ast/src/ast_traits.rs +++ b/compiler/rustc_ast/src/ast_traits.rs @@ -240,7 +240,6 @@ impl HasTokens for Nonterminal { Nonterminal::NtPath(path) => path.tokens(), Nonterminal::NtVis(vis) => vis.tokens(), Nonterminal::NtBlock(block) => block.tokens(), - Nonterminal::NtIdent(..) | Nonterminal::NtLifetime(..) => None, } } fn tokens_mut(&mut self) -> Option<&mut Option> { @@ -254,7 +253,6 @@ impl HasTokens for Nonterminal { Nonterminal::NtPath(path) => path.tokens_mut(), Nonterminal::NtVis(vis) => vis.tokens_mut(), Nonterminal::NtBlock(block) => block.tokens_mut(), - Nonterminal::NtIdent(..) | Nonterminal::NtLifetime(..) => None, } } } diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index 07358047025ab..5c4162295bbc1 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -781,6 +781,12 @@ pub fn visit_token(t: &mut Token, vis: &mut T) { *span = ident.span; return; // Avoid visiting the span for the second time. } + token::NtIdent(ident, _is_raw) => { + vis.visit_ident(ident); + } + token::NtLifetime(ident) => { + vis.visit_ident(ident); + } token::Interpolated(nt) => { let nt = Lrc::make_mut(nt); visit_nonterminal(nt, vis); @@ -832,8 +838,6 @@ fn visit_nonterminal(nt: &mut token::Nonterminal, vis: &mut T) { token::NtPat(pat) => vis.visit_pat(pat), token::NtExpr(expr) => vis.visit_expr(expr), token::NtTy(ty) => vis.visit_ty(ty), - token::NtIdent(ident, _is_raw) => vis.visit_ident(ident), - token::NtLifetime(ident) => vis.visit_ident(ident), token::NtLiteral(expr) => vis.visit_expr(expr), token::NtMeta(item) => { let AttrItem { path, args, tokens } = item.deref_mut(); diff --git a/compiler/rustc_ast/src/token.rs b/compiler/rustc_ast/src/token.rs index 590c3daf0c223..d00352ea2e130 100644 --- a/compiler/rustc_ast/src/token.rs +++ b/compiler/rustc_ast/src/token.rs @@ -318,11 +318,20 @@ pub enum TokenKind { /// It's recommended to use `Token::(ident,uninterpolate,uninterpolated_span)` to /// treat regular and interpolated identifiers in the same way. Ident(Symbol, IdentIsRaw), + /// This identifier (and its span) is the identifier passed to the + /// declarative macro. The span in the surrounding `Token` is the span of + /// the `ident` metavariable in the macro's RHS. + NtIdent(Ident, IdentIsRaw), + /// Lifetime identifier token. /// Do not forget about `NtLifetime` when you want to match on lifetime identifiers. /// It's recommended to use `Token::(lifetime,uninterpolate,uninterpolated_span)` to /// treat regular and interpolated lifetime identifiers in the same way. Lifetime(Symbol), + /// This identifier (and its span) is the lifetime passed to the + /// declarative macro. The span in the surrounding `Token` is the span of + /// the `lifetime` metavariable in the macro's RHS. + NtLifetime(Ident), /// An embedded AST node, as produced by a macro. This only exists for /// historical reasons. We'd like to get rid of it, for multiple reasons. @@ -444,8 +453,9 @@ impl Token { /// Note that keywords are also identifiers, so they should use this /// if they keep spans or perform edition checks. pub fn uninterpolated_span(&self) -> Span { - match &self.kind { - Interpolated(nt) => nt.use_span(), + match self.kind { + NtIdent(ident, _) | NtLifetime(ident) => ident.span, + Interpolated(ref nt) => nt.use_span(), _ => self.span, } } @@ -463,7 +473,7 @@ impl Token { } OpenDelim(..) | CloseDelim(..) | Literal(..) | DocComment(..) | Ident(..) - | Lifetime(..) | Interpolated(..) | Eof => false, + | NtIdent(..) | Lifetime(..) | NtLifetime(..) | Interpolated(..) | Eof => false, } } @@ -613,14 +623,9 @@ impl Token { /// into the regular identifier or lifetime token it refers to, /// otherwise returns the original token. pub fn uninterpolate(&self) -> Cow<'_, Token> { - match &self.kind { - Interpolated(nt) => match &**nt { - NtIdent(ident, is_raw) => { - Cow::Owned(Token::new(Ident(ident.name, *is_raw), ident.span)) - } - NtLifetime(ident) => Cow::Owned(Token::new(Lifetime(ident.name), ident.span)), - _ => Cow::Borrowed(self), - }, + match self.kind { + NtIdent(ident, is_raw) => Cow::Owned(Token::new(Ident(ident.name, is_raw), ident.span)), + NtLifetime(ident) => Cow::Owned(Token::new(Lifetime(ident.name), ident.span)), _ => Cow::Borrowed(self), } } @@ -629,12 +634,9 @@ impl Token { #[inline] pub fn ident(&self) -> Option<(Ident, IdentIsRaw)> { // We avoid using `Token::uninterpolate` here because it's slow. - match &self.kind { - &Ident(name, is_raw) => Some((Ident::new(name, self.span), is_raw)), - Interpolated(nt) => match &**nt { - NtIdent(ident, is_raw) => Some((*ident, *is_raw)), - _ => None, - }, + match self.kind { + Ident(name, is_raw) => Some((Ident::new(name, self.span), is_raw)), + NtIdent(ident, is_raw) => Some((ident, is_raw)), _ => None, } } @@ -643,12 +645,9 @@ impl Token { #[inline] pub fn lifetime(&self) -> Option { // We avoid using `Token::uninterpolate` here because it's slow. - match &self.kind { - &Lifetime(name) => Some(Ident::new(name, self.span)), - Interpolated(nt) => match &**nt { - NtLifetime(ident) => Some(*ident), - _ => None, - }, + match self.kind { + Lifetime(name) => Some(Ident::new(name, self.span)), + NtLifetime(ident) => Some(ident), _ => None, } } @@ -837,8 +836,10 @@ impl Token { Le | EqEq | Ne | Ge | AndAnd | OrOr | Tilde | BinOpEq(..) | At | DotDotDot | DotDotEq | Comma | Semi | PathSep | RArrow | LArrow | FatArrow | Pound | Dollar - | Question | OpenDelim(..) | CloseDelim(..) | Literal(..) | Ident(..) - | Lifetime(..) | Interpolated(..) | DocComment(..) | Eof => return None, + | Question | OpenDelim(..) | CloseDelim(..) | Literal(..) | Ident(..) | NtIdent(..) + | Lifetime(..) | NtLifetime(..) | Interpolated(..) | DocComment(..) | Eof => { + return None; + } }; Some(Token::new(kind, self.span.to(joint.span))) @@ -861,9 +862,6 @@ pub enum Nonterminal { NtPat(P), NtExpr(P), NtTy(P), - /// The span is for the identifier argument passed to the macro. - NtIdent(Ident, IdentIsRaw), - NtLifetime(Ident), NtLiteral(P), /// Stuff inside brackets for attributes NtMeta(P), @@ -958,7 +956,6 @@ impl Nonterminal { NtPat(pat) => pat.span, NtExpr(expr) | NtLiteral(expr) => expr.span, NtTy(ty) => ty.span, - NtIdent(ident, _) | NtLifetime(ident) => ident.span, NtMeta(attr_item) => attr_item.span(), NtPath(path) => path.span, NtVis(vis) => vis.span, @@ -974,8 +971,6 @@ impl Nonterminal { NtExpr(..) => "expression", NtLiteral(..) => "literal", NtTy(..) => "type", - NtIdent(..) => "identifier", - NtLifetime(..) => "lifetime", NtMeta(..) => "attribute", NtPath(..) => "path", NtVis(..) => "visibility", @@ -984,18 +979,12 @@ impl Nonterminal { } impl PartialEq for Nonterminal { - fn eq(&self, rhs: &Self) -> bool { - match (self, rhs) { - (NtIdent(ident_lhs, is_raw_lhs), NtIdent(ident_rhs, is_raw_rhs)) => { - ident_lhs == ident_rhs && is_raw_lhs == is_raw_rhs - } - (NtLifetime(ident_lhs), NtLifetime(ident_rhs)) => ident_lhs == ident_rhs, - // FIXME: Assume that all "complex" nonterminal are not equal, we can't compare them - // correctly based on data from AST. This will prevent them from matching each other - // in macros. The comparison will become possible only when each nonterminal has an - // attached token stream from which it was parsed. - _ => false, - } + fn eq(&self, _rhs: &Self) -> bool { + // FIXME: Assume that all nonterminals are not equal, we can't compare them + // correctly based on data from AST. This will prevent them from matching each other + // in macros. The comparison will become possible only when each nonterminal has an + // attached token stream from which it was parsed. + false } } @@ -1008,12 +997,10 @@ impl fmt::Debug for Nonterminal { NtPat(..) => f.pad("NtPat(..)"), NtExpr(..) => f.pad("NtExpr(..)"), NtTy(..) => f.pad("NtTy(..)"), - NtIdent(..) => f.pad("NtIdent(..)"), NtLiteral(..) => f.pad("NtLiteral(..)"), NtMeta(..) => f.pad("NtMeta(..)"), NtPath(..) => f.pad("NtPath(..)"), NtVis(..) => f.pad("NtVis(..)"), - NtLifetime(..) => f.pad("NtLifetime(..)"), } } } diff --git a/compiler/rustc_ast/src/tokenstream.rs b/compiler/rustc_ast/src/tokenstream.rs index d532a884184ce..fb666550e9302 100644 --- a/compiler/rustc_ast/src/tokenstream.rs +++ b/compiler/rustc_ast/src/tokenstream.rs @@ -466,12 +466,6 @@ impl TokenStream { pub fn from_nonterminal_ast(nt: &Nonterminal) -> TokenStream { match nt { - Nonterminal::NtIdent(ident, is_raw) => { - TokenStream::token_alone(token::Ident(ident.name, *is_raw), ident.span) - } - Nonterminal::NtLifetime(ident) => { - TokenStream::token_alone(token::Lifetime(ident.name), ident.span) - } Nonterminal::NtItem(item) => TokenStream::from_ast(item), Nonterminal::NtBlock(block) => TokenStream::from_ast(block), Nonterminal::NtStmt(stmt) if let StmtKind::Empty = stmt.kind => { @@ -489,11 +483,17 @@ impl TokenStream { } fn flatten_token(token: &Token, spacing: Spacing) -> TokenTree { - match &token.kind { - token::Interpolated(nt) if let token::NtIdent(ident, is_raw) = &**nt => { - TokenTree::Token(Token::new(token::Ident(ident.name, *is_raw), ident.span), spacing) + match token.kind { + token::NtIdent(ident, is_raw) => { + TokenTree::Token(Token::new(token::Ident(ident.name, is_raw), ident.span), spacing) } - token::Interpolated(nt) => TokenTree::Delimited( + token::NtLifetime(ident) => TokenTree::Delimited( + DelimSpan::from_single(token.span), + DelimSpacing::new(Spacing::JointHidden, spacing), + Delimiter::Invisible, + TokenStream::token_alone(token::Lifetime(ident.name), ident.span), + ), + token::Interpolated(ref nt) => TokenTree::Delimited( DelimSpan::from_single(token.span), DelimSpacing::new(Spacing::JointHidden, spacing), Delimiter::Invisible, @@ -516,7 +516,10 @@ impl TokenStream { pub fn flattened(&self) -> TokenStream { fn can_skip(stream: &TokenStream) -> bool { stream.trees().all(|tree| match tree { - TokenTree::Token(token, _) => !matches!(token.kind, token::Interpolated(_)), + TokenTree::Token(token, _) => !matches!( + token.kind, + token::NtIdent(..) | token::NtLifetime(..) | token::Interpolated(..) + ), TokenTree::Delimited(.., inner) => can_skip(inner), }) } diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index f438cee4cd252..e9cce4b3c3449 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -852,8 +852,6 @@ pub trait PrintState<'a>: std::ops::Deref + std::ops::Dere token::NtBlock(e) => self.block_to_string(e), token::NtStmt(e) => self.stmt_to_string(e), token::NtPat(e) => self.pat_to_string(e), - &token::NtIdent(e, is_raw) => IdentPrinter::for_ast_ident(e, is_raw.into()).to_string(), - token::NtLifetime(e) => e.to_string(), token::NtLiteral(e) => self.expr_to_string(e), token::NtVis(e) => self.vis_to_string(e), } @@ -915,10 +913,14 @@ pub trait PrintState<'a>: std::ops::Deref + std::ops::Dere token::Literal(lit) => literal_to_string(lit).into(), /* Name components */ - token::Ident(s, is_raw) => { - IdentPrinter::new(s, is_raw.into(), convert_dollar_crate).to_string().into() + token::Ident(name, is_raw) => { + IdentPrinter::new(name, is_raw.into(), convert_dollar_crate).to_string().into() } - token::Lifetime(s) => s.to_string().into(), + token::NtIdent(ident, is_raw) => { + IdentPrinter::for_ast_ident(ident, is_raw.into()).to_string().into() + } + token::Lifetime(name) => name.to_string().into(), + token::NtLifetime(ident) => ident.name.to_string().into(), /* Other */ token::DocComment(comment_kind, attr_style, data) => { diff --git a/compiler/rustc_expand/src/config.rs b/compiler/rustc_expand/src/config.rs index 897420a11cdfb..67a5a9128ccb6 100644 --- a/compiler/rustc_expand/src/config.rs +++ b/compiler/rustc_expand/src/config.rs @@ -201,10 +201,17 @@ impl<'a> StripUnconfigured<'a> { inner = self.configure_tokens(&inner); Some(AttrTokenTree::Delimited(sp, spacing, delim, inner)).into_iter() } - AttrTokenTree::Token(ref token, _) - if let TokenKind::Interpolated(nt) = &token.kind => - { - panic!("Nonterminal should have been flattened at {:?}: {:?}", token.span, nt); + AttrTokenTree::Token( + Token { + kind: + TokenKind::NtIdent(..) + | TokenKind::NtLifetime(..) + | TokenKind::Interpolated(..), + .. + }, + _, + ) => { + panic!("Nonterminal should have been flattened: {:?}", tree); } AttrTokenTree::Token(token, spacing) => { Some(AttrTokenTree::Token(token, spacing)).into_iter() diff --git a/compiler/rustc_expand/src/mbe/transcribe.rs b/compiler/rustc_expand/src/mbe/transcribe.rs index 011aa95c8a116..e35eba0f859b8 100644 --- a/compiler/rustc_expand/src/mbe/transcribe.rs +++ b/compiler/rustc_expand/src/mbe/transcribe.rs @@ -261,6 +261,16 @@ pub(super) fn transcribe<'a>( // without wrapping them into groups. maybe_use_metavar_location(cx, &stack, sp, tt, &mut marker) } + MatchedSingle(ParseNtResult::Ident(ident, is_raw)) => { + marker.visit_span(&mut sp); + let kind = token::NtIdent(*ident, *is_raw); + TokenTree::token_alone(kind, sp) + } + MatchedSingle(ParseNtResult::Lifetime(ident)) => { + marker.visit_span(&mut sp); + let kind = token::NtLifetime(*ident); + TokenTree::token_alone(kind, sp) + } MatchedSingle(ParseNtResult::Nt(nt)) => { // Other variables are emitted into the output stream as groups with // `Delimiter::Invisible` to maintain parsing priorities. diff --git a/compiler/rustc_expand/src/proc_macro_server.rs b/compiler/rustc_expand/src/proc_macro_server.rs index 8cf9658016182..1f3547c841a90 100644 --- a/compiler/rustc_expand/src/proc_macro_server.rs +++ b/compiler/rustc_expand/src/proc_macro_server.rs @@ -220,6 +220,12 @@ impl FromInternal<(TokenStream, &mut Rustc<'_, '_>)> for Vec { trees.push(TokenTree::Ident(Ident { sym, is_raw: is_raw.into(), span })) } + NtIdent(ident, is_raw) => trees.push(TokenTree::Ident(Ident { + sym: ident.name, + is_raw: is_raw.into(), + span: ident.span, + })), + Lifetime(name) => { let ident = symbol::Ident::new(name, span).without_first_quote(); trees.extend([ @@ -227,6 +233,15 @@ impl FromInternal<(TokenStream, &mut Rustc<'_, '_>)> for Vec { + let stream = TokenStream::token_alone(token::Lifetime(ident.name), ident.span); + trees.push(TokenTree::Group(Group { + delimiter: pm::Delimiter::None, + stream: Some(stream), + span: DelimSpan::from_single(span), + })) + } + Literal(token::Lit { kind, symbol, suffix }) => { trees.push(TokenTree::Literal(self::Literal { kind: FromInternal::from_internal(kind), @@ -259,14 +274,6 @@ impl FromInternal<(TokenStream, &mut Rustc<'_, '_>)> for Vec { - trees.push(TokenTree::Ident(Ident { - sym: ident.name, - is_raw: matches!(is_raw, IdentIsRaw::Yes), - span: ident.span, - })) - } - Interpolated(nt) => { let stream = TokenStream::from_nonterminal_ast(&nt); // A hack used to pass AST fragments to attribute and derive diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 8e3cd0f8ea9d5..cbc7ce9ef7cfb 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -724,7 +724,9 @@ impl<'a> Parser<'a> { /// Returns the span of expr if it was not interpolated, or the span of the interpolated token. fn interpolated_or_expr_span(&self, expr: &Expr) -> Span { match self.prev_token.kind { - TokenKind::Interpolated(..) => self.prev_token.span, + TokenKind::NtIdent(..) | TokenKind::NtLifetime(..) | TokenKind::Interpolated(..) => { + self.prev_token.span + } _ => expr.span, } } diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index cc40c8a7126ed..3e0a98a55ae9b 100644 --- a/compiler/rustc_parse/src/parser/mod.rs +++ b/compiler/rustc_parse/src/parser/mod.rs @@ -407,6 +407,8 @@ pub(super) fn token_descr(token: &Token) -> String { (Some(TokenDescription::Keyword), _) => Some("keyword"), (Some(TokenDescription::ReservedKeyword), _) => Some("reserved keyword"), (Some(TokenDescription::DocComment), _) => Some("doc comment"), + (None, TokenKind::NtIdent(..)) => Some("identifier"), + (None, TokenKind::NtLifetime(..)) => Some("lifetime"), (None, TokenKind::Interpolated(node)) => Some(node.descr()), (None, _) => None, }; @@ -1633,5 +1635,9 @@ pub enum FlatToken { #[derive(Clone, Debug)] pub enum ParseNtResult { Tt(TokenTree), + Ident(Ident, IdentIsRaw), + Lifetime(Ident), + + /// This case will eventually be removed, along with `Token::Interpolate`. Nt(Lrc), } diff --git a/compiler/rustc_parse/src/parser/nonterminal.rs b/compiler/rustc_parse/src/parser/nonterminal.rs index 3a560382d327c..a6f0ab78b5c29 100644 --- a/compiler/rustc_parse/src/parser/nonterminal.rs +++ b/compiler/rustc_parse/src/parser/nonterminal.rs @@ -25,15 +25,13 @@ impl<'a> Parser<'a> { | NtPat(_) | NtExpr(_) | NtTy(_) - | NtIdent(..) | NtLiteral(_) // `true`, `false` | NtMeta(_) | NtPath(_) => true, NtItem(_) | NtBlock(_) - | NtVis(_) - | NtLifetime(_) => false, + | NtVis(_) => false, } } @@ -50,25 +48,30 @@ impl<'a> Parser<'a> { NonterminalKind::Literal => token.can_begin_literal_maybe_minus(), NonterminalKind::Vis => match token.kind { // The follow-set of :vis + "priv" keyword + interpolated - token::Comma | token::Ident(..) | token::Interpolated(_) => true, + token::Comma + | token::Ident(..) + | token::NtIdent(..) + | token::NtLifetime(..) + | token::Interpolated(_) => true, _ => token.can_begin_type(), }, NonterminalKind::Block => match &token.kind { token::OpenDelim(Delimiter::Brace) => true, + token::NtLifetime(..) => true, token::Interpolated(nt) => match &**nt { - NtBlock(_) | NtLifetime(_) | NtStmt(_) | NtExpr(_) | NtLiteral(_) => true, - NtItem(_) | NtPat(_) | NtTy(_) | NtIdent(..) | NtMeta(_) | NtPath(_) - | NtVis(_) => false, + NtBlock(_) | NtStmt(_) | NtExpr(_) | NtLiteral(_) => true, + NtItem(_) | NtPat(_) | NtTy(_) | NtMeta(_) | NtPath(_) | NtVis(_) => false, }, _ => false, }, NonterminalKind::Path | NonterminalKind::Meta => match &token.kind { - token::PathSep | token::Ident(..) => true, + token::PathSep | token::Ident(..) | token::NtIdent(..) => true, token::Interpolated(nt) => may_be_ident(nt), _ => false, }, NonterminalKind::PatParam { .. } | NonterminalKind::PatWithOr => match &token.kind { - token::Ident(..) | // box, ref, mut, and other identifiers (can stricten) + // box, ref, mut, and other identifiers (can stricten) + token::Ident(..) | token::NtIdent(..) | token::OpenDelim(Delimiter::Parenthesis) | // tuple pattern token::OpenDelim(Delimiter::Bracket) | // slice pattern token::BinOp(token::And) | // reference @@ -86,10 +89,7 @@ impl<'a> Parser<'a> { _ => false, }, NonterminalKind::Lifetime => match &token.kind { - token::Lifetime(_) => true, - token::Interpolated(nt) => { - matches!(&**nt, NtLifetime(_)) - } + token::Lifetime(_) | token::NtLifetime(..) => true, _ => false, }, NonterminalKind::TT | NonterminalKind::Item | NonterminalKind::Stmt => { @@ -154,15 +154,16 @@ impl<'a> Parser<'a> { } // this could be handled like a token, since it is one - NonterminalKind::Ident if let Some((ident, is_raw)) = get_macro_ident(&self.token) => { - self.bump(); - NtIdent(ident, is_raw) - } NonterminalKind::Ident => { - return Err(self.dcx().create_err(UnexpectedNonterminal::Ident { - span: self.token.span, - token: self.token.clone(), - })); + return if let Some((ident, is_raw)) = get_macro_ident(&self.token) { + self.bump(); + Ok(ParseNtResult::Ident(ident, is_raw)) + } else { + Err(self.dcx().create_err(UnexpectedNonterminal::Ident { + span: self.token.span, + token: self.token.clone(), + })) + }; } NonterminalKind::Path => { NtPath(P(self.collect_tokens_no_attrs(|this| this.parse_path(PathStyle::Type))?)) @@ -173,14 +174,14 @@ impl<'a> Parser<'a> { .collect_tokens_no_attrs(|this| this.parse_visibility(FollowedByType::Yes))?)) } NonterminalKind::Lifetime => { - if self.check_lifetime() { - NtLifetime(self.expect_lifetime().ident) + return if self.check_lifetime() { + Ok(ParseNtResult::Lifetime(self.expect_lifetime().ident)) } else { - return Err(self.dcx().create_err(UnexpectedNonterminal::Lifetime { + Err(self.dcx().create_err(UnexpectedNonterminal::Lifetime { span: self.token.span, token: self.token.clone(), - })); - } + })) + }; } }; From 812f89728a3a1fbf3979e552fcb888fe6a500c19 Mon Sep 17 00:00:00 2001 From: Oneirical Date: Mon, 13 May 2024 22:15:11 -0400 Subject: [PATCH 166/179] fix fmt --- tests/run-make/c-link-to-rust-va-list-fn/rmake.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/run-make/c-link-to-rust-va-list-fn/rmake.rs b/tests/run-make/c-link-to-rust-va-list-fn/rmake.rs index 489a637c44533..7a450efff942a 100644 --- a/tests/run-make/c-link-to-rust-va-list-fn/rmake.rs +++ b/tests/run-make/c-link-to-rust-va-list-fn/rmake.rs @@ -8,8 +8,7 @@ use run_make_support::{cc, extra_c_flags, run, rustc, static_lib}; fn main() { - rustc().input("checkrust.rs") - .run(); + rustc().input("checkrust.rs").run(); cc().input("test.c") .input(static_lib("checkrust")) .out_exe("test") From d57e57ca1ff5abe96aaab94913c5c81c6027f39c Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 18 Apr 2024 21:13:35 -0400 Subject: [PATCH 167/179] Implement initial IMPL_TRAIT_OVERCAPTURES lint --- compiler/rustc_lint/messages.ftl | 7 + .../rustc_lint/src/impl_trait_overcaptures.rs | 236 ++++++++++++++++++ compiler/rustc_lint/src/lib.rs | 3 + 3 files changed, 246 insertions(+) create mode 100644 compiler/rustc_lint/src/impl_trait_overcaptures.rs diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl index 676a7c21841a1..67b2121e5c008 100644 --- a/compiler/rustc_lint/messages.ftl +++ b/compiler/rustc_lint/messages.ftl @@ -9,6 +9,13 @@ lint_array_into_iter = .use_explicit_into_iter_suggestion = or use `IntoIterator::into_iter(..)` instead of `.into_iter()` to explicitly iterate by value +lint_impl_trait_overcaptures = `{$self_ty}` will capture more lifetimes than possibly intended in edition 2024 + .note = specifically, {$num_captured -> + [one] this lifetime is + *[other] these lifetimes are + } in scope but not mentioned in the type's bounds + .note2 = all lifetimes in scope will be captured by `impl Trait`s in edition 2024 + lint_async_fn_in_trait = use of `async fn` in public traits is discouraged as auto trait bounds cannot be specified .note = you can suppress this lint if you plan to use the trait only in your own code, or do not care about auto traits like `Send` on the `Future` .suggestion = you can alternatively desugar to a normal `fn` that returns `impl Future` and add any desired bounds such as `Send`, but these cannot be relaxed without a breaking API change diff --git a/compiler/rustc_lint/src/impl_trait_overcaptures.rs b/compiler/rustc_lint/src/impl_trait_overcaptures.rs new file mode 100644 index 0000000000000..a633f355f29de --- /dev/null +++ b/compiler/rustc_lint/src/impl_trait_overcaptures.rs @@ -0,0 +1,236 @@ +use rustc_data_structures::{fx::FxIndexSet, unord::UnordSet}; +use rustc_errors::LintDiagnostic; +use rustc_hir as hir; +use rustc_hir::def::DefKind; +use rustc_hir::def_id::{DefId, LocalDefId}; +use rustc_hir::intravisit; +use rustc_middle::ty::{ + self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, +}; +use rustc_span::Span; + +use crate::fluent_generated as fluent; +use crate::{LateContext, LateLintPass}; + +declare_lint! { + /// UwU + pub IMPL_TRAIT_OVERCAPTURES, + Warn, + "will capture more lifetimes than possibly intended in edition 2024", + @future_incompatible = FutureIncompatibleInfo { + reason: FutureIncompatibilityReason::EditionSemanticsChange(Edition::Edition2024), + reference: "", + }; +} + +declare_lint_pass!( + /// Lint for use of `async fn` in the definition of a publicly-reachable + /// trait. + ImplTraitOvercaptures => [IMPL_TRAIT_OVERCAPTURES] +); + +impl<'tcx> LateLintPass<'tcx> for ImplTraitOvercaptures { + fn check_fn( + &mut self, + cx: &LateContext<'tcx>, + _: intravisit::FnKind<'tcx>, + _: &'tcx hir::FnDecl<'tcx>, + _: &'tcx hir::Body<'tcx>, + _: Span, + parent_def_id: LocalDefId, + ) { + match cx.tcx.def_kind(parent_def_id) { + DefKind::AssocFn => { + // RPITITs already capture all lifetimes in scope, so skip them. + if matches!( + cx.tcx.def_kind(cx.tcx.local_parent(parent_def_id)), + DefKind::Trait | DefKind::Impl { of_trait: true } + ) { + return; + } + } + DefKind::Fn => { + // All freee functions need to check for overcaptures. + } + DefKind::Closure => return, + kind => { + unreachable!( + "expected function item, found {}", + kind.descr(parent_def_id.to_def_id()) + ) + } + } + + let sig = cx.tcx.fn_sig(parent_def_id).instantiate_identity(); + + let mut in_scope_parameters = FxIndexSet::default(); + let mut current_def_id = Some(parent_def_id.to_def_id()); + while let Some(def_id) = current_def_id { + let generics = cx.tcx.generics_of(def_id); + for param in &generics.params { + in_scope_parameters.insert(param.def_id); + } + current_def_id = generics.parent; + } + + sig.visit_with(&mut VisitOpaqueTypes { + tcx: cx.tcx, + parent_def_id, + in_scope_parameters, + seen: Default::default(), + }); + } +} + +struct VisitOpaqueTypes<'tcx> { + tcx: TyCtxt<'tcx>, + parent_def_id: LocalDefId, + in_scope_parameters: FxIndexSet, + seen: FxIndexSet, +} + +impl<'tcx> TypeVisitor> for VisitOpaqueTypes<'tcx> { + fn visit_binder>>( + &mut self, + t: &ty::Binder<'tcx, T>, + ) -> Self::Result { + let mut added = vec![]; + for arg in t.bound_vars() { + let arg: ty::BoundVariableKind = arg; + match arg { + ty::BoundVariableKind::Region(ty::BoundRegionKind::BrNamed(def_id, ..)) => { + added.push(def_id); + let unique = self.in_scope_parameters.insert(def_id); + assert!(unique); + } + ty::BoundVariableKind::Ty(_) => { + todo!("we don't support late-bound type params in `impl Trait`") + } + ty::BoundVariableKind::Region(..) => { + unreachable!("all AST-derived bound regions should have a name") + } + ty::BoundVariableKind::Const => { + unreachable!("non-lifetime binder consts are not allowed") + } + } + } + + t.super_visit_with(self); + + for arg in added.into_iter().rev() { + self.in_scope_parameters.shift_remove(&arg); + } + } + + fn visit_ty(&mut self, t: Ty<'tcx>) -> Self::Result { + if !t.has_opaque_types() { + return; + } + + if let ty::Alias(ty::Opaque, opaque_ty) = *t.kind() + && let Some(opaque_def_id) = opaque_ty.def_id.as_local() + && self.seen.insert(opaque_def_id) + && let opaque = + self.tcx.hir_node_by_def_id(opaque_def_id).expect_item().expect_opaque_ty() + && let hir::OpaqueTyOrigin::FnReturn(parent_def_id) = opaque.origin + && parent_def_id == self.parent_def_id + && opaque.precise_capturing_args.is_none() + { + let mut captured = UnordSet::default(); + let variances = self.tcx.variances_of(opaque_def_id); + let mut current_def_id = Some(opaque_def_id.to_def_id()); + while let Some(def_id) = current_def_id { + let generics = self.tcx.generics_of(def_id); + for param in &generics.params { + if variances[param.index as usize] != ty::Invariant { + continue; + } + captured.insert(extract_def_id_from_arg( + self.tcx, + generics, + opaque_ty.args[param.index as usize], + )); + } + current_def_id = generics.parent; + } + + let uncaptured_spans: Vec<_> = self + .in_scope_parameters + .iter() + .filter(|def_id| !captured.contains(def_id)) + .map(|def_id| self.tcx.def_span(def_id)) + .collect(); + + if !uncaptured_spans.is_empty() { + self.tcx.emit_node_lint( + IMPL_TRAIT_OVERCAPTURES, + self.tcx.local_def_id_to_hir_id(opaque_def_id), + ImplTraitOvercapturesLint { + opaque_span: self.tcx.def_span(opaque_def_id), + self_ty: t, + num_captured: uncaptured_spans.len(), + uncaptured_spans, + }, + ); + } + + for clause in + self.tcx.item_bounds(opaque_ty.def_id).iter_instantiated(self.tcx, opaque_ty.args) + { + clause.visit_with(self) + } + } + + t.super_visit_with(self); + } +} + +struct ImplTraitOvercapturesLint<'tcx> { + opaque_span: Span, + uncaptured_spans: Vec, + self_ty: Ty<'tcx>, + num_captured: usize, +} + +impl<'a> LintDiagnostic<'a, ()> for ImplTraitOvercapturesLint<'_> { + fn decorate_lint<'b>(self, diag: &'b mut rustc_errors::Diag<'a, ()>) { + diag.arg("self_ty", self.self_ty.to_string()) + .arg("num_captured", self.num_captured) + .span(self.opaque_span) + .span_note(self.uncaptured_spans, fluent::lint_note) + .note(fluent::lint_note2); + } + + fn msg(&self) -> rustc_errors::DiagMessage { + fluent::lint_impl_trait_overcaptures + } +} + +fn extract_def_id_from_arg<'tcx>( + tcx: TyCtxt<'tcx>, + generics: &'tcx ty::Generics, + arg: ty::GenericArg<'tcx>, +) -> DefId { + match arg.unpack() { + ty::GenericArgKind::Lifetime(re) => match *re { + ty::ReEarlyParam(ebr) => generics.region_param(ebr, tcx).def_id, + ty::ReBound( + _, + ty::BoundRegion { kind: ty::BoundRegionKind::BrNamed(def_id, ..), .. }, + ) => def_id, + _ => unreachable!(), + }, + ty::GenericArgKind::Type(ty) => { + let ty::Param(param_ty) = *ty.kind() else { + bug!(); + }; + generics.type_param(param_ty, tcx).def_id + } + ty::GenericArgKind::Const(ct) => { + let ty::ConstKind::Param(param_ct) = ct.kind() else { + bug!(); + }; + generics.const_param(param_ct, tcx).def_id + } + } +} diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index a78b410f500c1..d93edadcfbcc2 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -55,6 +55,7 @@ mod expect; mod for_loops_over_fallibles; mod foreign_modules; pub mod hidden_unicode_codepoints; +mod impl_trait_overcaptures; mod internal; mod invalid_from_utf8; mod late; @@ -94,6 +95,7 @@ use drop_forget_useless::*; use enum_intrinsics_non_enums::EnumIntrinsicsNonEnums; use for_loops_over_fallibles::*; use hidden_unicode_codepoints::*; +use impl_trait_overcaptures::ImplTraitOvercaptures; use internal::*; use invalid_from_utf8::*; use let_underscore::*; @@ -228,6 +230,7 @@ late_lint_methods!( MissingDoc: MissingDoc, AsyncFnInTrait: AsyncFnInTrait, NonLocalDefinitions: NonLocalDefinitions::default(), + ImplTraitOvercaptures: ImplTraitOvercaptures, ] ] ); From 554becc180b42c41c35a25811cdc7059c7acc4fb Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 18 Apr 2024 21:19:22 -0400 Subject: [PATCH 168/179] Add some commenting --- .../rustc_lint/src/impl_trait_overcaptures.rs | 27 ++++++++++++++++--- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_lint/src/impl_trait_overcaptures.rs b/compiler/rustc_lint/src/impl_trait_overcaptures.rs index a633f355f29de..b5fa322d89fbd 100644 --- a/compiler/rustc_lint/src/impl_trait_overcaptures.rs +++ b/compiler/rustc_lint/src/impl_trait_overcaptures.rs @@ -24,8 +24,8 @@ declare_lint! { } declare_lint_pass!( - /// Lint for use of `async fn` in the definition of a publicly-reachable - /// trait. + /// Lint for opaque types that will begin capturing in-scope but unmentioned lifetimes + /// in edition 2024. ImplTraitOvercaptures => [IMPL_TRAIT_OVERCAPTURES] ); @@ -50,7 +50,7 @@ impl<'tcx> LateLintPass<'tcx> for ImplTraitOvercaptures { } } DefKind::Fn => { - // All freee functions need to check for overcaptures. + // All free functions need to check for overcaptures. } DefKind::Closure => return, kind => { @@ -64,6 +64,7 @@ impl<'tcx> LateLintPass<'tcx> for ImplTraitOvercaptures { let sig = cx.tcx.fn_sig(parent_def_id).instantiate_identity(); let mut in_scope_parameters = FxIndexSet::default(); + // Populate the in_scope_parameters list first with all of the generics in scope let mut current_def_id = Some(parent_def_id.to_def_id()); while let Some(def_id) = current_def_id { let generics = cx.tcx.generics_of(def_id); @@ -73,6 +74,8 @@ impl<'tcx> LateLintPass<'tcx> for ImplTraitOvercaptures { current_def_id = generics.parent; } + // Then visit the signature to walk through all the binders (incl. the late-bound + // vars on the function itself, which we need to count too). sig.visit_with(&mut VisitOpaqueTypes { tcx: cx.tcx, parent_def_id, @@ -94,6 +97,7 @@ impl<'tcx> TypeVisitor> for VisitOpaqueTypes<'tcx> { &mut self, t: &ty::Binder<'tcx, T>, ) -> Self::Result { + // When we get into a binder, we need to add its own bound vars to the scope. let mut added = vec![]; for arg in t.bound_vars() { let arg: ty::BoundVariableKind = arg; @@ -117,6 +121,8 @@ impl<'tcx> TypeVisitor> for VisitOpaqueTypes<'tcx> { t.super_visit_with(self); + // And remove them. The `shift_remove` should be `O(1)` since we're popping + // them off from the end. for arg in added.into_iter().rev() { self.in_scope_parameters.shift_remove(&arg); } @@ -129,22 +135,29 @@ impl<'tcx> TypeVisitor> for VisitOpaqueTypes<'tcx> { if let ty::Alias(ty::Opaque, opaque_ty) = *t.kind() && let Some(opaque_def_id) = opaque_ty.def_id.as_local() + // Don't recurse infinitely on an opaque && self.seen.insert(opaque_def_id) + // If it's owned by this function && let opaque = self.tcx.hir_node_by_def_id(opaque_def_id).expect_item().expect_opaque_ty() && let hir::OpaqueTyOrigin::FnReturn(parent_def_id) = opaque.origin && parent_def_id == self.parent_def_id + // And if the opaque doesn't already have `use<>` syntax on it... && opaque.precise_capturing_args.is_none() { + // Compute the set of args that are captured by the opaque... let mut captured = UnordSet::default(); let variances = self.tcx.variances_of(opaque_def_id); let mut current_def_id = Some(opaque_def_id.to_def_id()); while let Some(def_id) = current_def_id { let generics = self.tcx.generics_of(def_id); - for param in &generics.params { + for param in &generics.own_params { + // A param is captured if it's invariant. if variances[param.index as usize] != ty::Invariant { continue; } + // We need to turn all `ty::Param`/`ConstKind::Param` and + // `ReEarlyParam`/`ReBound` into def ids. captured.insert(extract_def_id_from_arg( self.tcx, generics, @@ -154,6 +167,8 @@ impl<'tcx> TypeVisitor> for VisitOpaqueTypes<'tcx> { current_def_id = generics.parent; } + // Compute the set of in scope params that are not captured. Get their spans, + // since that's all we really care about them for emitting the diagnostic. let uncaptured_spans: Vec<_> = self .in_scope_parameters .iter() @@ -174,6 +189,10 @@ impl<'tcx> TypeVisitor> for VisitOpaqueTypes<'tcx> { ); } + // Walk into the bounds of the opaque, too, since we want to get nested opaques + // in this lint as well. Interestingly, one place that I expect this lint to fire + // is for `impl for<'a> Bound`, since `impl Other` will begin + // to capture `'a` in e2024 (even though late-bound vars in opaques are not allowed). for clause in self.tcx.item_bounds(opaque_ty.def_id).iter_instantiated(self.tcx, opaque_ty.args) { From 6afe1352d934a15d1cfacf7eaef774898e76011f Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 18 Apr 2024 21:57:07 -0400 Subject: [PATCH 169/179] Suggest adding use<> syntax --- compiler/rustc_lint/messages.ftl | 1 + .../rustc_lint/src/impl_trait_overcaptures.rs | 47 ++++++++++++++++--- 2 files changed, 42 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl index 67b2121e5c008..d54e9a3c6eb32 100644 --- a/compiler/rustc_lint/messages.ftl +++ b/compiler/rustc_lint/messages.ftl @@ -15,6 +15,7 @@ lint_impl_trait_overcaptures = `{$self_ty}` will capture more lifetimes than pos *[other] these lifetimes are } in scope but not mentioned in the type's bounds .note2 = all lifetimes in scope will be captured by `impl Trait`s in edition 2024 + .suggestion = use the precise capturing `use<...>` syntax to make the captures explicit lint_async_fn_in_trait = use of `async fn` in public traits is discouraged as auto trait bounds cannot be specified .note = you can suppress this lint if you plan to use the trait only in your own code, or do not care about auto traits like `Send` on the `Future` diff --git a/compiler/rustc_lint/src/impl_trait_overcaptures.rs b/compiler/rustc_lint/src/impl_trait_overcaptures.rs index b5fa322d89fbd..7272618c5f20d 100644 --- a/compiler/rustc_lint/src/impl_trait_overcaptures.rs +++ b/compiler/rustc_lint/src/impl_trait_overcaptures.rs @@ -1,5 +1,5 @@ -use rustc_data_structures::{fx::FxIndexSet, unord::UnordSet}; -use rustc_errors::LintDiagnostic; +use rustc_data_structures::fx::FxIndexSet; +use rustc_errors::{Applicability, LintDiagnostic}; use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LocalDefId}; @@ -7,7 +7,9 @@ use rustc_hir::intravisit; use rustc_middle::ty::{ self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, }; -use rustc_span::Span; +use rustc_session::lint::FutureIncompatibilityReason; +use rustc_span::edition::Edition; +use rustc_span::{BytePos, Span}; use crate::fluent_generated as fluent; use crate::{LateContext, LateLintPass}; @@ -146,7 +148,7 @@ impl<'tcx> TypeVisitor> for VisitOpaqueTypes<'tcx> { && opaque.precise_capturing_args.is_none() { // Compute the set of args that are captured by the opaque... - let mut captured = UnordSet::default(); + let mut captured = FxIndexSet::default(); let variances = self.tcx.variances_of(opaque_def_id); let mut current_def_id = Some(opaque_def_id.to_def_id()); while let Some(def_id) = current_def_id { @@ -172,19 +174,43 @@ impl<'tcx> TypeVisitor> for VisitOpaqueTypes<'tcx> { let uncaptured_spans: Vec<_> = self .in_scope_parameters .iter() - .filter(|def_id| !captured.contains(def_id)) + .filter(|def_id| !captured.contains(*def_id)) .map(|def_id| self.tcx.def_span(def_id)) .collect(); if !uncaptured_spans.is_empty() { + let opaque_span = self.tcx.def_span(opaque_def_id); + + let suggestion = if let Ok(snippet) = + self.tcx.sess.source_map().span_to_snippet(opaque_span) + && snippet.starts_with("impl ") + { + let (lifetimes, others): (Vec<_>, Vec<_>) = captured + .into_iter() + .partition(|def_id| self.tcx.def_kind(*def_id) == DefKind::LifetimeParam); + // Take all lifetime params first, then all others (ty/ct). + let generics: Vec<_> = lifetimes + .into_iter() + .chain(others) + .map(|def_id| self.tcx.item_name(def_id).to_string()) + .collect(); + Some(( + format!(" use<{}>", generics.join(", ")), + opaque_span.with_lo(opaque_span.lo() + BytePos(4)).shrink_to_lo(), + )) + } else { + None + }; + self.tcx.emit_node_lint( IMPL_TRAIT_OVERCAPTURES, self.tcx.local_def_id_to_hir_id(opaque_def_id), ImplTraitOvercapturesLint { - opaque_span: self.tcx.def_span(opaque_def_id), + opaque_span, self_ty: t, num_captured: uncaptured_spans.len(), uncaptured_spans, + suggestion, }, ); } @@ -209,6 +235,7 @@ struct ImplTraitOvercapturesLint<'tcx> { uncaptured_spans: Vec, self_ty: Ty<'tcx>, num_captured: usize, + suggestion: Option<(String, Span)>, } impl<'a> LintDiagnostic<'a, ()> for ImplTraitOvercapturesLint<'_> { @@ -218,6 +245,14 @@ impl<'a> LintDiagnostic<'a, ()> for ImplTraitOvercapturesLint<'_> { .span(self.opaque_span) .span_note(self.uncaptured_spans, fluent::lint_note) .note(fluent::lint_note2); + if let Some((suggestion, span)) = self.suggestion { + diag.span_suggestion( + span, + fluent::lint_suggestion, + suggestion, + Applicability::MachineApplicable, + ); + } } fn msg(&self) -> rustc_errors::DiagMessage { From f3fb727b08587e75a6adacca1a8f06f62e31d87e Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 18 Apr 2024 22:04:14 -0400 Subject: [PATCH 170/179] Don't suggest using use<> syntax to capture APITs --- compiler/rustc_lint/src/impl_trait_overcaptures.rs | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_lint/src/impl_trait_overcaptures.rs b/compiler/rustc_lint/src/impl_trait_overcaptures.rs index 7272618c5f20d..7659b6da1811e 100644 --- a/compiler/rustc_lint/src/impl_trait_overcaptures.rs +++ b/compiler/rustc_lint/src/impl_trait_overcaptures.rs @@ -194,10 +194,15 @@ impl<'tcx> TypeVisitor> for VisitOpaqueTypes<'tcx> { .chain(others) .map(|def_id| self.tcx.item_name(def_id).to_string()) .collect(); - Some(( - format!(" use<{}>", generics.join(", ")), - opaque_span.with_lo(opaque_span.lo() + BytePos(4)).shrink_to_lo(), - )) + // Make sure that we're not trying to name any APITs + if generics.iter().all(|name| !name.starts_with("impl ")) { + Some(( + format!(" use<{}>", generics.join(", ")), + opaque_span.with_lo(opaque_span.lo() + BytePos(4)).shrink_to_lo(), + )) + } else { + None + } } else { None }; From 1529c661e4f1f5294877a471e388d9097e742414 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 20 Apr 2024 11:22:06 -0400 Subject: [PATCH 171/179] Warn against redundant use<...> --- compiler/rustc_ast_lowering/src/lib.rs | 15 +- compiler/rustc_hir/src/hir.rs | 11 +- compiler/rustc_hir/src/intravisit.rs | 2 +- .../rustc_hir_analysis/src/check/check.rs | 2 +- compiler/rustc_lint/messages.ftl | 19 +- .../rustc_lint/src/impl_trait_overcaptures.rs | 207 ++++++++++++------ compiler/rustc_parse/src/parser/ty.rs | 58 ++--- .../impl-trait/precise-capturing/apit.stderr | 2 +- .../impl-trait/precise-capturing/redundant.rs | 25 +++ .../precise-capturing/redundant.stderr | 45 ++++ 10 files changed, 272 insertions(+), 114 deletions(-) create mode 100644 tests/ui/impl-trait/precise-capturing/redundant.rs create mode 100644 tests/ui/impl-trait/precise-capturing/redundant.stderr diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index a76935761f0a4..c23da8aa01e47 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -1407,7 +1407,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { bounds, fn_kind, itctx, - precise_capturing.as_deref().map(|(args, _)| args.as_slice()), + precise_capturing.as_deref().map(|(args, span)| (args.as_slice(), *span)), ), ImplTraitContext::Universal => { if let Some(&(_, span)) = precise_capturing.as_deref() { @@ -1523,7 +1523,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { bounds: &GenericBounds, fn_kind: Option, itctx: ImplTraitContext, - precise_capturing_args: Option<&[PreciseCapturingArg]>, + precise_capturing_args: Option<(&[PreciseCapturingArg], Span)>, ) -> hir::TyKind<'hir> { // Make sure we know that some funky desugaring has been going on here. // This is a first: there is code in other places like for loop @@ -1533,7 +1533,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let opaque_ty_span = self.mark_span_with_reason(DesugaringKind::OpaqueTy, span, None); let captured_lifetimes_to_duplicate = - if let Some(precise_capturing) = precise_capturing_args { + if let Some((precise_capturing, _)) = precise_capturing_args { // We'll actually validate these later on; all we need is the list of // lifetimes to duplicate during this portion of lowering. precise_capturing @@ -1607,7 +1607,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { captured_lifetimes_to_duplicate: FxIndexSet, span: Span, opaque_ty_span: Span, - precise_capturing_args: Option<&[PreciseCapturingArg]>, + precise_capturing_args: Option<(&[PreciseCapturingArg], Span)>, lower_item_bounds: impl FnOnce(&mut Self) -> &'hir [hir::GenericBound<'hir>], ) -> hir::TyKind<'hir> { let opaque_ty_def_id = self.create_def( @@ -1698,8 +1698,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { this.with_remapping(captured_to_synthesized_mapping, |this| { ( lower_item_bounds(this), - precise_capturing_args.map(|precise_capturing| { - this.lower_precise_capturing_args(precise_capturing) + precise_capturing_args.map(|(precise_capturing, span)| { + ( + this.lower_precise_capturing_args(precise_capturing), + this.lower_span(span), + ) }), ) }); diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 7d991e21ff3d2..6e4cef068c59f 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -2631,7 +2631,7 @@ pub struct OpaqueTy<'hir> { /// lowered as an associated type. pub in_trait: bool, /// List of arguments captured via `impl use<'a, P, ...> Trait` syntax. - pub precise_capturing_args: Option<&'hir [PreciseCapturingArg<'hir>]>, + pub precise_capturing_args: Option<(&'hir [PreciseCapturingArg<'hir>], Span)>, } #[derive(Debug, Clone, Copy, HashStable_Generic)] @@ -2641,6 +2641,15 @@ pub enum PreciseCapturingArg<'hir> { Param(PreciseCapturingNonLifetimeArg), } +impl PreciseCapturingArg<'_> { + pub fn hir_id(self) -> HirId { + match self { + PreciseCapturingArg::Lifetime(lt) => lt.hir_id, + PreciseCapturingArg::Param(param) => param.hir_id, + } + } +} + /// We need to have a [`Node`] for the [`HirId`] that we attach the type/const param /// resolution to. Lifetimes don't have this problem, and for them, it's actually /// kind of detrimental to use a custom node type versus just using [`Lifetime`], diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index 0b095db953b08..664784cd2c603 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -533,7 +533,7 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) -> V:: try_visit!(visitor.visit_id(item.hir_id())); try_visit!(walk_generics(visitor, generics)); walk_list!(visitor, visit_param_bound, bounds); - if let Some(precise_capturing_args) = precise_capturing_args { + if let Some((precise_capturing_args, _)) = precise_capturing_args { for arg in precise_capturing_args { try_visit!(visitor.visit_precise_capturing_arg(arg)); } diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 652c18850737f..b5c067514059a 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -486,7 +486,7 @@ fn sanity_check_found_hidden_type<'tcx>( fn check_opaque_precise_captures<'tcx>(tcx: TyCtxt<'tcx>, opaque_def_id: LocalDefId) { let hir::OpaqueTy { precise_capturing_args, .. } = *tcx.hir_node_by_def_id(opaque_def_id).expect_item().expect_opaque_ty(); - let Some(precise_capturing_args) = precise_capturing_args else { + let Some((precise_capturing_args, _)) = precise_capturing_args else { // No precise capturing args; nothing to validate return; }; diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl index d54e9a3c6eb32..5180fce2eb378 100644 --- a/compiler/rustc_lint/messages.ftl +++ b/compiler/rustc_lint/messages.ftl @@ -9,14 +9,6 @@ lint_array_into_iter = .use_explicit_into_iter_suggestion = or use `IntoIterator::into_iter(..)` instead of `.into_iter()` to explicitly iterate by value -lint_impl_trait_overcaptures = `{$self_ty}` will capture more lifetimes than possibly intended in edition 2024 - .note = specifically, {$num_captured -> - [one] this lifetime is - *[other] these lifetimes are - } in scope but not mentioned in the type's bounds - .note2 = all lifetimes in scope will be captured by `impl Trait`s in edition 2024 - .suggestion = use the precise capturing `use<...>` syntax to make the captures explicit - lint_async_fn_in_trait = use of `async fn` in public traits is discouraged as auto trait bounds cannot be specified .note = you can suppress this lint if you plan to use the trait only in your own code, or do not care about auto traits like `Send` on the `Future` .suggestion = you can alternatively desugar to a normal `fn` that returns `impl Future` and add any desired bounds such as `Send`, but these cannot be relaxed without a breaking API change @@ -277,6 +269,17 @@ lint_identifier_uncommon_codepoints = identifier contains {$codepoints_len -> lint_ignored_unless_crate_specified = {$level}({$name}) is ignored unless specified at crate level +lint_impl_trait_overcaptures = `{$self_ty}` will capture more lifetimes than possibly intended in edition 2024 + .note = specifically, {$num_captured -> + [one] this lifetime is + *[other] these lifetimes are + } in scope but not mentioned in the type's bounds + .note2 = all lifetimes in scope will be captured by `impl Trait`s in edition 2024 + .suggestion = use the precise capturing `use<...>` syntax to make the captures explicit + +lint_impl_trait_redundant_captures = all possible in-scope parameters are already captured, so `use<...>` syntax is redundant + .suggestion = remove the `use<...>` syntax + lint_improper_ctypes = `extern` {$desc} uses type `{$ty}`, which is not FFI-safe .label = not FFI-safe .note = the type is defined here diff --git a/compiler/rustc_lint/src/impl_trait_overcaptures.rs b/compiler/rustc_lint/src/impl_trait_overcaptures.rs index 7659b6da1811e..a239f38006bdc 100644 --- a/compiler/rustc_lint/src/impl_trait_overcaptures.rs +++ b/compiler/rustc_lint/src/impl_trait_overcaptures.rs @@ -1,9 +1,11 @@ use rustc_data_structures::fx::FxIndexSet; +use rustc_data_structures::unord::UnordSet; use rustc_errors::{Applicability, LintDiagnostic}; use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LocalDefId}; -use rustc_hir::intravisit; +use rustc_macros::LintDiagnostic; +use rustc_middle::middle::resolve_bound_vars::ResolvedArg; use rustc_middle::ty::{ self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, }; @@ -14,10 +16,12 @@ use rustc_span::{BytePos, Span}; use crate::fluent_generated as fluent; use crate::{LateContext, LateLintPass}; +// TODO: feature gate these too + declare_lint! { /// UwU pub IMPL_TRAIT_OVERCAPTURES, - Warn, + Allow, "will capture more lifetimes than possibly intended in edition 2024", @future_incompatible = FutureIncompatibleInfo { reason: FutureIncompatibilityReason::EditionSemanticsChange(Edition::Edition2024), @@ -25,66 +29,64 @@ declare_lint! { }; } +declare_lint! { + /// UwU + pub IMPL_TRAIT_REDUNDANT_CAPTURES, + Warn, + "uwu 2" +} + declare_lint_pass!( /// Lint for opaque types that will begin capturing in-scope but unmentioned lifetimes /// in edition 2024. - ImplTraitOvercaptures => [IMPL_TRAIT_OVERCAPTURES] + ImplTraitOvercaptures => [IMPL_TRAIT_OVERCAPTURES, IMPL_TRAIT_REDUNDANT_CAPTURES] ); impl<'tcx> LateLintPass<'tcx> for ImplTraitOvercaptures { - fn check_fn( - &mut self, - cx: &LateContext<'tcx>, - _: intravisit::FnKind<'tcx>, - _: &'tcx hir::FnDecl<'tcx>, - _: &'tcx hir::Body<'tcx>, - _: Span, - parent_def_id: LocalDefId, - ) { - match cx.tcx.def_kind(parent_def_id) { - DefKind::AssocFn => { - // RPITITs already capture all lifetimes in scope, so skip them. - if matches!( - cx.tcx.def_kind(cx.tcx.local_parent(parent_def_id)), - DefKind::Trait | DefKind::Impl { of_trait: true } - ) { - return; - } - } - DefKind::Fn => { - // All free functions need to check for overcaptures. - } - DefKind::Closure => return, - kind => { - unreachable!( - "expected function item, found {}", - kind.descr(parent_def_id.to_def_id()) - ) - } + fn check_item(&mut self, cx: &LateContext<'tcx>, it: &'tcx hir::Item<'tcx>) { + match &it.kind { + hir::ItemKind::Fn(..) => check_fn(cx.tcx, it.owner_id.def_id), + _ => {} } + } - let sig = cx.tcx.fn_sig(parent_def_id).instantiate_identity(); + fn check_impl_item(&mut self, cx: &LateContext<'tcx>, it: &'tcx hir::ImplItem<'tcx>) { + match &it.kind { + hir::ImplItemKind::Fn(_, _) => check_fn(cx.tcx, it.owner_id.def_id), + _ => {} + } + } - let mut in_scope_parameters = FxIndexSet::default(); - // Populate the in_scope_parameters list first with all of the generics in scope - let mut current_def_id = Some(parent_def_id.to_def_id()); - while let Some(def_id) = current_def_id { - let generics = cx.tcx.generics_of(def_id); - for param in &generics.params { - in_scope_parameters.insert(param.def_id); - } - current_def_id = generics.parent; + fn check_trait_item(&mut self, cx: &LateContext<'tcx>, it: &'tcx hir::TraitItem<'tcx>) { + match &it.kind { + hir::TraitItemKind::Fn(_, _) => check_fn(cx.tcx, it.owner_id.def_id), + _ => {} } + } +} - // Then visit the signature to walk through all the binders (incl. the late-bound - // vars on the function itself, which we need to count too). - sig.visit_with(&mut VisitOpaqueTypes { - tcx: cx.tcx, - parent_def_id, - in_scope_parameters, - seen: Default::default(), - }); +fn check_fn(tcx: TyCtxt<'_>, parent_def_id: LocalDefId) { + let sig = tcx.fn_sig(parent_def_id).instantiate_identity(); + + let mut in_scope_parameters = FxIndexSet::default(); + // Populate the in_scope_parameters list first with all of the generics in scope + let mut current_def_id = Some(parent_def_id.to_def_id()); + while let Some(def_id) = current_def_id { + let generics = tcx.generics_of(def_id); + for param in &generics.own_params { + in_scope_parameters.insert(param.def_id); + } + current_def_id = generics.parent; } + + // Then visit the signature to walk through all the binders (incl. the late-bound + // vars on the function itself, which we need to count too). + sig.visit_with(&mut VisitOpaqueTypes { + tcx, + parent_def_id, + in_scope_parameters, + seen: Default::default(), + }); } struct VisitOpaqueTypes<'tcx> { @@ -109,14 +111,11 @@ impl<'tcx> TypeVisitor> for VisitOpaqueTypes<'tcx> { let unique = self.in_scope_parameters.insert(def_id); assert!(unique); } - ty::BoundVariableKind::Ty(_) => { - todo!("we don't support late-bound type params in `impl Trait`") - } - ty::BoundVariableKind::Region(..) => { - unreachable!("all AST-derived bound regions should have a name") - } - ty::BoundVariableKind::Const => { - unreachable!("non-lifetime binder consts are not allowed") + _ => { + self.tcx.dcx().span_delayed_bug( + self.tcx.def_span(self.parent_def_id), + format!("unsupported bound variable kind: {arg:?}"), + ); } } } @@ -131,11 +130,19 @@ impl<'tcx> TypeVisitor> for VisitOpaqueTypes<'tcx> { } fn visit_ty(&mut self, t: Ty<'tcx>) -> Self::Result { - if !t.has_opaque_types() { + if !t.has_aliases() { return; } - if let ty::Alias(ty::Opaque, opaque_ty) = *t.kind() + if let ty::Alias(ty::Projection, opaque_ty) = *t.kind() + && self.tcx.is_impl_trait_in_trait(opaque_ty.def_id) + { + // visit the opaque of the RPITIT + self.tcx + .type_of(opaque_ty.def_id) + .instantiate(self.tcx, opaque_ty.args) + .visit_with(self) + } else if let ty::Alias(ty::Opaque, opaque_ty) = *t.kind() && let Some(opaque_def_id) = opaque_ty.def_id.as_local() // Don't recurse infinitely on an opaque && self.seen.insert(opaque_def_id) @@ -144,8 +151,6 @@ impl<'tcx> TypeVisitor> for VisitOpaqueTypes<'tcx> { self.tcx.hir_node_by_def_id(opaque_def_id).expect_item().expect_opaque_ty() && let hir::OpaqueTyOrigin::FnReturn(parent_def_id) = opaque.origin && parent_def_id == self.parent_def_id - // And if the opaque doesn't already have `use<>` syntax on it... - && opaque.precise_capturing_args.is_none() { // Compute the set of args that are captured by the opaque... let mut captured = FxIndexSet::default(); @@ -178,9 +183,16 @@ impl<'tcx> TypeVisitor> for VisitOpaqueTypes<'tcx> { .map(|def_id| self.tcx.def_span(def_id)) .collect(); - if !uncaptured_spans.is_empty() { - let opaque_span = self.tcx.def_span(opaque_def_id); + let opaque_span = self.tcx.def_span(opaque_def_id); + let new_capture_rules = + opaque_span.at_least_rust_2024() || self.tcx.features().lifetime_capture_rules_2024; + // If we have uncaptured args, and if the opaque doesn't already have + // `use<>` syntax on it, and we're < edition 2024, then warn the user. + if !new_capture_rules + && opaque.precise_capturing_args.is_none() + && !uncaptured_spans.is_empty() + { let suggestion = if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(opaque_span) && snippet.starts_with("impl ") @@ -207,11 +219,11 @@ impl<'tcx> TypeVisitor> for VisitOpaqueTypes<'tcx> { None }; - self.tcx.emit_node_lint( + self.tcx.emit_node_span_lint( IMPL_TRAIT_OVERCAPTURES, self.tcx.local_def_id_to_hir_id(opaque_def_id), + opaque_span, ImplTraitOvercapturesLint { - opaque_span, self_ty: t, num_captured: uncaptured_spans.len(), uncaptured_spans, @@ -219,6 +231,60 @@ impl<'tcx> TypeVisitor> for VisitOpaqueTypes<'tcx> { }, ); } + // Otherwise, if we are edition 2024, have `use<>` syntax, and + // have no uncaptured args, then we should warn to the user that + // it's redundant to capture all args explicitly. + else if new_capture_rules + && let Some((captured_args, capturing_span)) = opaque.precise_capturing_args + { + let mut explicitly_captured = UnordSet::default(); + for arg in captured_args { + match self.tcx.named_bound_var(arg.hir_id()) { + Some( + ResolvedArg::EarlyBound(def_id) | ResolvedArg::LateBound(_, _, def_id), + ) => { + if self.tcx.def_kind(self.tcx.parent(def_id)) == DefKind::OpaqueTy { + let (ty::ReEarlyParam(ty::EarlyParamRegion { def_id, .. }) + | ty::ReLateParam(ty::LateParamRegion { + bound_region: ty::BoundRegionKind::BrNamed(def_id, _), + .. + })) = self + .tcx + .map_opaque_lifetime_to_parent_lifetime(def_id.expect_local()) + .kind() + else { + span_bug!( + self.tcx.def_span(def_id), + "variable should have been duplicated from a parent" + ); + }; + explicitly_captured.insert(def_id); + } else { + explicitly_captured.insert(def_id); + } + } + _ => { + self.tcx.dcx().span_delayed_bug( + self.tcx().hir().span(arg.hir_id()), + "no valid for captured arg", + ); + } + } + } + + if self + .in_scope_parameters + .iter() + .all(|def_id| explicitly_captured.contains(def_id)) + { + self.tcx.emit_node_span_lint( + IMPL_TRAIT_REDUNDANT_CAPTURES, + self.tcx.local_def_id_to_hir_id(opaque_def_id), + opaque_span, + ImplTraitRedundantCapturesLint { capturing_span }, + ); + } + } // Walk into the bounds of the opaque, too, since we want to get nested opaques // in this lint as well. Interestingly, one place that I expect this lint to fire @@ -236,7 +302,6 @@ impl<'tcx> TypeVisitor> for VisitOpaqueTypes<'tcx> { } struct ImplTraitOvercapturesLint<'tcx> { - opaque_span: Span, uncaptured_spans: Vec, self_ty: Ty<'tcx>, num_captured: usize, @@ -247,7 +312,6 @@ impl<'a> LintDiagnostic<'a, ()> for ImplTraitOvercapturesLint<'_> { fn decorate_lint<'b>(self, diag: &'b mut rustc_errors::Diag<'a, ()>) { diag.arg("self_ty", self.self_ty.to_string()) .arg("num_captured", self.num_captured) - .span(self.opaque_span) .span_note(self.uncaptured_spans, fluent::lint_note) .note(fluent::lint_note2); if let Some((suggestion, span)) = self.suggestion { @@ -265,6 +329,13 @@ impl<'a> LintDiagnostic<'a, ()> for ImplTraitOvercapturesLint<'_> { } } +#[derive(LintDiagnostic)] +#[diag(lint_impl_trait_redundant_captures)] +struct ImplTraitRedundantCapturesLint { + #[suggestion(lint_suggestion, code = "", applicability = "machine-applicable")] + capturing_span: Span, +} + fn extract_def_id_from_arg<'tcx>( tcx: TyCtxt<'tcx>, generics: &'tcx ty::Generics, diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs index 7096b201f847a..2f08a48c7bcd0 100644 --- a/compiler/rustc_parse/src/parser/ty.rs +++ b/compiler/rustc_parse/src/parser/ty.rs @@ -675,8 +675,8 @@ impl<'a> Parser<'a> { let precise_capturing = if self.eat_keyword(kw::Use) { let use_span = self.prev_token.span; self.psess.gated_spans.gate(sym::precise_capturing, use_span); - let args = self.parse_precise_capturing_args()?; - Some(P((args, use_span))) + let (args, args_span) = self.parse_precise_capturing_args()?; + Some(P((args, use_span.to(args_span)))) } else { None }; @@ -689,32 +689,34 @@ impl<'a> Parser<'a> { Ok(TyKind::ImplTrait(ast::DUMMY_NODE_ID, bounds, precise_capturing)) } - fn parse_precise_capturing_args(&mut self) -> PResult<'a, ThinVec> { - Ok(self - .parse_unspanned_seq( - &TokenKind::Lt, - &TokenKind::Gt, - SeqSep::trailing_allowed(token::Comma), - |self_| { - if self_.check_keyword(kw::SelfUpper) { - self_.bump(); - Ok(PreciseCapturingArg::Arg( - ast::Path::from_ident(self_.prev_token.ident().unwrap().0), - DUMMY_NODE_ID, - )) - } else if self_.check_ident() { - Ok(PreciseCapturingArg::Arg( - ast::Path::from_ident(self_.parse_ident()?), - DUMMY_NODE_ID, - )) - } else if self_.check_lifetime() { - Ok(PreciseCapturingArg::Lifetime(self_.expect_lifetime())) - } else { - self_.unexpected_any() - } - }, - )? - .0) + fn parse_precise_capturing_args( + &mut self, + ) -> PResult<'a, (ThinVec, Span)> { + let lo = self.token.span; + let (args, _) = self.parse_unspanned_seq( + &TokenKind::Lt, + &TokenKind::Gt, + SeqSep::trailing_allowed(token::Comma), + |self_| { + if self_.check_keyword(kw::SelfUpper) { + self_.bump(); + Ok(PreciseCapturingArg::Arg( + ast::Path::from_ident(self_.prev_token.ident().unwrap().0), + DUMMY_NODE_ID, + )) + } else if self_.check_ident() { + Ok(PreciseCapturingArg::Arg( + ast::Path::from_ident(self_.parse_ident()?), + DUMMY_NODE_ID, + )) + } else if self_.check_lifetime() { + Ok(PreciseCapturingArg::Lifetime(self_.expect_lifetime())) + } else { + self_.unexpected_any() + } + }, + )?; + Ok((args, lo.to(self.prev_token.span))) } /// Is a `dyn B0 + ... + Bn` type allowed here? diff --git a/tests/ui/impl-trait/precise-capturing/apit.stderr b/tests/ui/impl-trait/precise-capturing/apit.stderr index 36bf80d9e2f96..96548f5732f57 100644 --- a/tests/ui/impl-trait/precise-capturing/apit.stderr +++ b/tests/ui/impl-trait/precise-capturing/apit.stderr @@ -11,7 +11,7 @@ error: `use<...>` precise capturing syntax not allowed on argument-position `imp --> $DIR/apit.rs:4:18 | LL | fn hello(_: impl use<> Sized) {} - | ^^^ + | ^^^^^ error: aborting due to 1 previous error; 1 warning emitted diff --git a/tests/ui/impl-trait/precise-capturing/redundant.rs b/tests/ui/impl-trait/precise-capturing/redundant.rs new file mode 100644 index 0000000000000..108a4cb64aa8d --- /dev/null +++ b/tests/ui/impl-trait/precise-capturing/redundant.rs @@ -0,0 +1,25 @@ +//@ compile-flags: -Zunstable-options --edition=2024 +//@ check-pass + +#![feature(precise_capturing)] +//~^ WARN the feature `precise_capturing` is incomplete + +fn hello<'a>() -> impl use<'a> Sized {} +//~^ WARN all possible in-scope parameters are already captured + +struct Inherent; +impl Inherent { + fn inherent(&self) -> impl use<'_> Sized {} + //~^ WARN all possible in-scope parameters are already captured +} + +trait Test<'a> { + fn in_trait() -> impl use<'a, Self> Sized; + //~^ WARN all possible in-scope parameters are already captured +} +impl<'a> Test<'a> for () { + fn in_trait() -> impl use<'a> Sized {} + //~^ WARN all possible in-scope parameters are already captured +} + +fn main() {} diff --git a/tests/ui/impl-trait/precise-capturing/redundant.stderr b/tests/ui/impl-trait/precise-capturing/redundant.stderr new file mode 100644 index 0000000000000..325f04d3536a2 --- /dev/null +++ b/tests/ui/impl-trait/precise-capturing/redundant.stderr @@ -0,0 +1,45 @@ +warning: the feature `precise_capturing` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/redundant.rs:4:12 + | +LL | #![feature(precise_capturing)] + | ^^^^^^^^^^^^^^^^^ + | + = note: see issue #123432 for more information + = note: `#[warn(incomplete_features)]` on by default + +warning: all possible in-scope parameters are already captured, so `use<...>` syntax is redundant + --> $DIR/redundant.rs:7:19 + | +LL | fn hello<'a>() -> impl use<'a> Sized {} + | ^^^^^-------^^^^^^ + | | + | help: remove the `use<...>` syntax + | + = note: `#[warn(impl_trait_redundant_captures)]` on by default + +warning: all possible in-scope parameters are already captured, so `use<...>` syntax is redundant + --> $DIR/redundant.rs:12:27 + | +LL | fn inherent(&self) -> impl use<'_> Sized {} + | ^^^^^-------^^^^^^ + | | + | help: remove the `use<...>` syntax + +warning: all possible in-scope parameters are already captured, so `use<...>` syntax is redundant + --> $DIR/redundant.rs:17:22 + | +LL | fn in_trait() -> impl use<'a, Self> Sized; + | ^^^^^-------------^^^^^^ + | | + | help: remove the `use<...>` syntax + +warning: all possible in-scope parameters are already captured, so `use<...>` syntax is redundant + --> $DIR/redundant.rs:21:22 + | +LL | fn in_trait() -> impl use<'a> Sized {} + | ^^^^^-------^^^^^^ + | | + | help: remove the `use<...>` syntax + +warning: 5 warnings emitted + From 052de1da4f579f63d2403f8045f2d6e342a90200 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 21 Apr 2024 11:27:27 -0400 Subject: [PATCH 172/179] And finally add tests --- .../rustc_lint/src/impl_trait_overcaptures.rs | 89 +++++++++++++++---- .../precise-capturing/overcaptures-2024.fixed | 29 ++++++ .../precise-capturing/overcaptures-2024.rs | 29 ++++++ .../overcaptures-2024.stderr | 75 ++++++++++++++++ 4 files changed, 207 insertions(+), 15 deletions(-) create mode 100644 tests/ui/impl-trait/precise-capturing/overcaptures-2024.fixed create mode 100644 tests/ui/impl-trait/precise-capturing/overcaptures-2024.rs create mode 100644 tests/ui/impl-trait/precise-capturing/overcaptures-2024.stderr diff --git a/compiler/rustc_lint/src/impl_trait_overcaptures.rs b/compiler/rustc_lint/src/impl_trait_overcaptures.rs index a239f38006bdc..30bf80b915b87 100644 --- a/compiler/rustc_lint/src/impl_trait_overcaptures.rs +++ b/compiler/rustc_lint/src/impl_trait_overcaptures.rs @@ -9,31 +9,89 @@ use rustc_middle::middle::resolve_bound_vars::ResolvedArg; use rustc_middle::ty::{ self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, }; -use rustc_session::lint::FutureIncompatibilityReason; -use rustc_span::edition::Edition; -use rustc_span::{BytePos, Span}; +use rustc_middle::{bug, span_bug}; +use rustc_session::{declare_lint, declare_lint_pass}; +use rustc_span::{sym, BytePos, Span}; use crate::fluent_generated as fluent; use crate::{LateContext, LateLintPass}; -// TODO: feature gate these too - declare_lint! { - /// UwU + /// The `impl_trait_overcaptures` lint warns against cases where lifetime + /// capture behavior will differ in edition 2024. + /// + /// In the 2024 edition, `impl Trait`s will capture all lifetimes in scope, + /// rather than just the lifetimes that are mentioned in the bounds of the type. + /// Often these sets are equal, but if not, it means that the `impl Trait` may + /// cause erroneous borrow-checker errors. + /// + /// ### Example + /// + /// ```rust,compile_fail + /// # #![feature(precise_capturing)] + /// # #![allow(incomplete_features)] + /// # #![deny(impl_trait_overcaptures)] + /// # use std::fmt::Display; + /// let mut x = vec![]; + /// x.push(1); + /// + /// fn test(x: &Vec) -> impl Display { + /// x[0] + /// } + /// + /// let element = test(&x); + /// x.push(2); + /// println!("{element}"); + /// ``` + /// + /// {{produces}} + /// + /// ### Explanation + /// + /// In edition < 2024, the returned `impl Display` doesn't capture the + /// lifetime from the `&Vec`, so the vector can be mutably borrowed + /// while the `impl Display` is live. + /// + /// To fix this, we can explicitly state that the `impl Display` doesn't + /// capture any lifetimes, using `impl use<> Display`. pub IMPL_TRAIT_OVERCAPTURES, Allow, - "will capture more lifetimes than possibly intended in edition 2024", - @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::EditionSemanticsChange(Edition::Edition2024), - reference: "", - }; + "`impl Trait` will capture more lifetimes than possibly intended in edition 2024", + @feature_gate = sym::precise_capturing; + //@future_incompatible = FutureIncompatibleInfo { + // reason: FutureIncompatibilityReason::EditionSemanticsChange(Edition::Edition2024), + // reference: "", + //}; } declare_lint! { - /// UwU + /// The `impl_trait_redundant_captures` lint warns against cases where use of the + /// precise capturing `use<...>` syntax is not needed. + /// + /// In the 2024 edition, `impl Trait`s will capture all lifetimes in scope. + /// If precise-capturing `use<...>` syntax is used, and the set of parameters + /// that are captures are *equal* to the set of parameters in scope, then + /// the syntax is redundant, and can be removed. + /// + /// ### Example + /// + /// ```rust,compile_fail + /// # #![feature(precise_capturing, lifetime_capture_rules_2024)] + /// # #![allow(incomplete_features)] + /// # #![deny(impl_trait_redundant_captures)] + /// fn test<'a>(x: &'a i32) -> impl use<'a> Sized { x } + /// ``` + /// + /// {{produces}} + /// + /// ### Explanation + /// + /// To fix this, remove the `use<'a>`, since the lifetime is already captured + /// since it is in scope. pub IMPL_TRAIT_REDUNDANT_CAPTURES, Warn, - "uwu 2" + "redundant precise-capturing `use<...>` syntax on an `impl Trait`", + @feature_gate = sym::precise_capturing; } declare_lint_pass!( @@ -106,7 +164,8 @@ impl<'tcx> TypeVisitor> for VisitOpaqueTypes<'tcx> { for arg in t.bound_vars() { let arg: ty::BoundVariableKind = arg; match arg { - ty::BoundVariableKind::Region(ty::BoundRegionKind::BrNamed(def_id, ..)) => { + ty::BoundVariableKind::Region(ty::BoundRegionKind::BrNamed(def_id, ..)) + | ty::BoundVariableKind::Ty(ty::BoundTyKind::Param(def_id, _)) => { added.push(def_id); let unique = self.in_scope_parameters.insert(def_id); assert!(unique); @@ -265,7 +324,7 @@ impl<'tcx> TypeVisitor> for VisitOpaqueTypes<'tcx> { } _ => { self.tcx.dcx().span_delayed_bug( - self.tcx().hir().span(arg.hir_id()), + self.tcx.hir().span(arg.hir_id()), "no valid for captured arg", ); } diff --git a/tests/ui/impl-trait/precise-capturing/overcaptures-2024.fixed b/tests/ui/impl-trait/precise-capturing/overcaptures-2024.fixed new file mode 100644 index 0000000000000..014ab23e4ebc2 --- /dev/null +++ b/tests/ui/impl-trait/precise-capturing/overcaptures-2024.fixed @@ -0,0 +1,29 @@ +//@ run-rustfix + +#![feature(precise_capturing)] +#![allow(unused, incomplete_features)] +#![deny(impl_trait_overcaptures)] + +fn named<'a>(x: &'a i32) -> impl use<> Sized { *x } +//~^ ERROR `impl Sized` will capture more lifetimes than possibly intended in edition 2024 + +fn implicit(x: &i32) -> impl use<> Sized { *x } +//~^ ERROR `impl Sized` will capture more lifetimes than possibly intended in edition 2024 + +struct W; +impl W { + fn hello(&self, x: &i32) -> impl use<'_> Sized + '_ { self } + //~^ ERROR `impl Sized + '_` will capture more lifetimes than possibly intended in edition 2024 +} + +trait Higher<'a> { + type Output; +} +impl Higher<'_> for () { + type Output = (); +} + +fn hrtb() -> impl for<'a> Higher<'a, Output = impl use<> Sized> {} +//~^ ERROR `impl Sized` will capture more lifetimes than possibly intended in edition 2024 + +fn main() {} diff --git a/tests/ui/impl-trait/precise-capturing/overcaptures-2024.rs b/tests/ui/impl-trait/precise-capturing/overcaptures-2024.rs new file mode 100644 index 0000000000000..e4b7828d60ffd --- /dev/null +++ b/tests/ui/impl-trait/precise-capturing/overcaptures-2024.rs @@ -0,0 +1,29 @@ +//@ run-rustfix + +#![feature(precise_capturing)] +#![allow(unused, incomplete_features)] +#![deny(impl_trait_overcaptures)] + +fn named<'a>(x: &'a i32) -> impl Sized { *x } +//~^ ERROR `impl Sized` will capture more lifetimes than possibly intended in edition 2024 + +fn implicit(x: &i32) -> impl Sized { *x } +//~^ ERROR `impl Sized` will capture more lifetimes than possibly intended in edition 2024 + +struct W; +impl W { + fn hello(&self, x: &i32) -> impl Sized + '_ { self } + //~^ ERROR `impl Sized + '_` will capture more lifetimes than possibly intended in edition 2024 +} + +trait Higher<'a> { + type Output; +} +impl Higher<'_> for () { + type Output = (); +} + +fn hrtb() -> impl for<'a> Higher<'a, Output = impl Sized> {} +//~^ ERROR `impl Sized` will capture more lifetimes than possibly intended in edition 2024 + +fn main() {} diff --git a/tests/ui/impl-trait/precise-capturing/overcaptures-2024.stderr b/tests/ui/impl-trait/precise-capturing/overcaptures-2024.stderr new file mode 100644 index 0000000000000..16cb8b7e94b11 --- /dev/null +++ b/tests/ui/impl-trait/precise-capturing/overcaptures-2024.stderr @@ -0,0 +1,75 @@ +error: `impl Sized` will capture more lifetimes than possibly intended in edition 2024 + --> $DIR/overcaptures-2024.rs:7:29 + | +LL | fn named<'a>(x: &'a i32) -> impl Sized { *x } + | ^^^^^^^^^^ + | +note: specifically, this lifetime is in scope but not mentioned in the type's bounds + --> $DIR/overcaptures-2024.rs:7:10 + | +LL | fn named<'a>(x: &'a i32) -> impl Sized { *x } + | ^^ + = note: all lifetimes in scope will be captured by `impl Trait`s in edition 2024 +note: the lint level is defined here + --> $DIR/overcaptures-2024.rs:5:9 + | +LL | #![deny(impl_trait_overcaptures)] + | ^^^^^^^^^^^^^^^^^^^^^^^ +help: use the precise capturing `use<...>` syntax to make the captures explicit + | +LL | fn named<'a>(x: &'a i32) -> impl use<> Sized { *x } + | +++++ + +error: `impl Sized` will capture more lifetimes than possibly intended in edition 2024 + --> $DIR/overcaptures-2024.rs:10:25 + | +LL | fn implicit(x: &i32) -> impl Sized { *x } + | ^^^^^^^^^^ + | +note: specifically, this lifetime is in scope but not mentioned in the type's bounds + --> $DIR/overcaptures-2024.rs:10:16 + | +LL | fn implicit(x: &i32) -> impl Sized { *x } + | ^ + = note: all lifetimes in scope will be captured by `impl Trait`s in edition 2024 +help: use the precise capturing `use<...>` syntax to make the captures explicit + | +LL | fn implicit(x: &i32) -> impl use<> Sized { *x } + | +++++ + +error: `impl Sized + '_` will capture more lifetimes than possibly intended in edition 2024 + --> $DIR/overcaptures-2024.rs:15:33 + | +LL | fn hello(&self, x: &i32) -> impl Sized + '_ { self } + | ^^^^^^^^^^^^^^^ + | +note: specifically, this lifetime is in scope but not mentioned in the type's bounds + --> $DIR/overcaptures-2024.rs:15:24 + | +LL | fn hello(&self, x: &i32) -> impl Sized + '_ { self } + | ^ + = note: all lifetimes in scope will be captured by `impl Trait`s in edition 2024 +help: use the precise capturing `use<...>` syntax to make the captures explicit + | +LL | fn hello(&self, x: &i32) -> impl use<'_> Sized + '_ { self } + | +++++++ + +error: `impl Sized` will capture more lifetimes than possibly intended in edition 2024 + --> $DIR/overcaptures-2024.rs:26:47 + | +LL | fn hrtb() -> impl for<'a> Higher<'a, Output = impl Sized> {} + | ^^^^^^^^^^ + | +note: specifically, this lifetime is in scope but not mentioned in the type's bounds + --> $DIR/overcaptures-2024.rs:26:23 + | +LL | fn hrtb() -> impl for<'a> Higher<'a, Output = impl Sized> {} + | ^^ + = note: all lifetimes in scope will be captured by `impl Trait`s in edition 2024 +help: use the precise capturing `use<...>` syntax to make the captures explicit + | +LL | fn hrtb() -> impl for<'a> Higher<'a, Output = impl use<> Sized> {} + | +++++ + +error: aborting due to 4 previous errors + From 68407f90491972e10cf5f3a400c07a0566217c5a Mon Sep 17 00:00:00 2001 From: Federico Maria Morrone Date: Tue, 14 May 2024 10:28:00 +0200 Subject: [PATCH 173/179] fix typo in x86_64-unknown-linux-none docs Co-authored-by: Trevor Gross --- src/doc/rustc/src/platform-support/x86_64-unknown-linux-none.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustc/src/platform-support/x86_64-unknown-linux-none.md b/src/doc/rustc/src/platform-support/x86_64-unknown-linux-none.md index 90bafa7e4fba8..5608b5cb77811 100644 --- a/src/doc/rustc/src/platform-support/x86_64-unknown-linux-none.md +++ b/src/doc/rustc/src/platform-support/x86_64-unknown-linux-none.md @@ -12,7 +12,7 @@ Freestanding x86-64 linux binary with no dependency on libc. This target is cross compiled and can be built from any host. -This target has no support for host tools, std and alloc. +This target has no support for host tools, std, or alloc. ## Building the target From 809b84edba988408071630b1e89a8c06be07aeed Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Thu, 11 Apr 2024 14:23:25 -0400 Subject: [PATCH 174/179] Add v0 symbol mangling for `f16` and `f128` As discussed at , use the crate encoding to represent new primitives. --- compiler/rustc_symbol_mangling/src/v0.rs | 5 ++--- src/doc/rustc/src/symbol-mangling/v0.md | 2 ++ 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs index 1de2ecbb7006d..9fb217d2f8435 100644 --- a/compiler/rustc_symbol_mangling/src/v0.rs +++ b/compiler/rustc_symbol_mangling/src/v0.rs @@ -319,11 +319,10 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> { ty::Uint(UintTy::U64) => "y", ty::Uint(UintTy::U128) => "o", ty::Uint(UintTy::Usize) => "j", - // FIXME(f16_f128): update these once `rustc-demangle` supports the new types - ty::Float(FloatTy::F16) => unimplemented!("f16_f128"), + ty::Float(FloatTy::F16) => "C3f16", ty::Float(FloatTy::F32) => "f", ty::Float(FloatTy::F64) => "d", - ty::Float(FloatTy::F128) => unimplemented!("f16_f128"), + ty::Float(FloatTy::F128) => "C4f128", ty::Never => "z", // Placeholders (should be demangled as `_`). diff --git a/src/doc/rustc/src/symbol-mangling/v0.md b/src/doc/rustc/src/symbol-mangling/v0.md index 61f747fac837c..763694a9fdac8 100644 --- a/src/doc/rustc/src/symbol-mangling/v0.md +++ b/src/doc/rustc/src/symbol-mangling/v0.md @@ -739,6 +739,8 @@ The type encodings based on the initial tag character are: * `z` — `!` * `p` — [placeholder] `_` +Remaining primitives are encoded as a crate production, e.g. `C4f128`. + * `A` — An [array][reference-array] `[T; N]`. > array-type → `A` *[type]* *[const]* From 792a9bdd4bf79e498b9e6a966c4cd9ef4d4085ce Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Fri, 12 Apr 2024 13:48:03 -0400 Subject: [PATCH 175/179] Enable v0 mangling tests and add checks for `f16`/`f128` --- tests/ui/symbol-names/types.legacy.stderr | 194 ++++--- tests/ui/symbol-names/types.rs | 267 ++++++--- tests/ui/symbol-names/types.v0.stderr | 506 ++++++++++++++++++ .../symbol-names/types.verbose-legacy.stderr | 194 ++++--- 4 files changed, 920 insertions(+), 241 deletions(-) create mode 100644 tests/ui/symbol-names/types.v0.stderr diff --git a/tests/ui/symbol-names/types.legacy.stderr b/tests/ui/symbol-names/types.legacy.stderr index a4984d5629f7d..87c3acae0bd6c 100644 --- a/tests/ui/symbol-names/types.legacy.stderr +++ b/tests/ui/symbol-names/types.legacy.stderr @@ -1,470 +1,506 @@ error: symbol-name(_ZN1a1b16Type$LT$bool$GT$17h[HASH]E) - --> $DIR/types.rs:13:5 + --> $DIR/types.rs:18:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(a::b::Type::h[HASH]) - --> $DIR/types.rs:13:5 + --> $DIR/types.rs:18:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(a::b::Type) - --> $DIR/types.rs:13:5 + --> $DIR/types.rs:18:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: symbol-name(_ZN1a1b16Type$LT$char$GT$17h[HASH]E) - --> $DIR/types.rs:19:5 + --> $DIR/types.rs:27:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(a::b::Type::h[HASH]) - --> $DIR/types.rs:19:5 + --> $DIR/types.rs:27:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(a::b::Type) - --> $DIR/types.rs:19:5 + --> $DIR/types.rs:27:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: symbol-name(_ZN1a1b14Type$LT$i8$GT$17h[HASH]E) - --> $DIR/types.rs:25:5 + --> $DIR/types.rs:36:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(a::b::Type::h[HASH]) - --> $DIR/types.rs:25:5 + --> $DIR/types.rs:36:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(a::b::Type) - --> $DIR/types.rs:25:5 + --> $DIR/types.rs:36:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: symbol-name(_ZN1a1b15Type$LT$i16$GT$17h[HASH]E) - --> $DIR/types.rs:31:5 + --> $DIR/types.rs:45:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(a::b::Type::h[HASH]) - --> $DIR/types.rs:31:5 + --> $DIR/types.rs:45:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(a::b::Type) - --> $DIR/types.rs:31:5 + --> $DIR/types.rs:45:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: symbol-name(_ZN1a1b15Type$LT$i32$GT$17h[HASH]E) - --> $DIR/types.rs:37:5 + --> $DIR/types.rs:54:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(a::b::Type::h[HASH]) - --> $DIR/types.rs:37:5 + --> $DIR/types.rs:54:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(a::b::Type) - --> $DIR/types.rs:37:5 + --> $DIR/types.rs:54:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: symbol-name(_ZN1a1b15Type$LT$i64$GT$17h[HASH]E) - --> $DIR/types.rs:43:5 + --> $DIR/types.rs:63:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(a::b::Type::h[HASH]) - --> $DIR/types.rs:43:5 + --> $DIR/types.rs:63:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(a::b::Type) - --> $DIR/types.rs:43:5 + --> $DIR/types.rs:63:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: symbol-name(_ZN1a1b14Type$LT$u8$GT$17h[HASH]E) - --> $DIR/types.rs:49:5 + --> $DIR/types.rs:72:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(a::b::Type::h[HASH]) - --> $DIR/types.rs:49:5 + --> $DIR/types.rs:72:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(a::b::Type) - --> $DIR/types.rs:49:5 + --> $DIR/types.rs:72:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: symbol-name(_ZN1a1b15Type$LT$u16$GT$17h[HASH]E) - --> $DIR/types.rs:55:5 + --> $DIR/types.rs:81:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(a::b::Type::h[HASH]) - --> $DIR/types.rs:55:5 + --> $DIR/types.rs:81:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(a::b::Type) - --> $DIR/types.rs:55:5 + --> $DIR/types.rs:81:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: symbol-name(_ZN1a1b15Type$LT$u32$GT$17h[HASH]E) - --> $DIR/types.rs:61:5 + --> $DIR/types.rs:90:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(a::b::Type::h[HASH]) - --> $DIR/types.rs:61:5 + --> $DIR/types.rs:90:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(a::b::Type) - --> $DIR/types.rs:61:5 + --> $DIR/types.rs:90:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: symbol-name(_ZN1a1b15Type$LT$u64$GT$17h[HASH]E) - --> $DIR/types.rs:67:5 + --> $DIR/types.rs:99:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(a::b::Type::h[HASH]) - --> $DIR/types.rs:67:5 + --> $DIR/types.rs:99:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(a::b::Type) - --> $DIR/types.rs:67:5 + --> $DIR/types.rs:99:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: symbol-name(_ZN1a1b15Type$LT$f16$GT$17h[HASH]E) + --> $DIR/types.rs:108:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling(a::b::Type::h[HASH]) + --> $DIR/types.rs:108:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling-alt(a::b::Type) + --> $DIR/types.rs:108:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: symbol-name(_ZN1a1b15Type$LT$f32$GT$17h[HASH]E) - --> $DIR/types.rs:73:5 + --> $DIR/types.rs:117:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(a::b::Type::h[HASH]) - --> $DIR/types.rs:73:5 + --> $DIR/types.rs:117:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(a::b::Type) - --> $DIR/types.rs:73:5 + --> $DIR/types.rs:117:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: symbol-name(_ZN1a1b15Type$LT$f64$GT$17h[HASH]E) - --> $DIR/types.rs:79:5 + --> $DIR/types.rs:126:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(a::b::Type::h[HASH]) - --> $DIR/types.rs:79:5 + --> $DIR/types.rs:126:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(a::b::Type) - --> $DIR/types.rs:79:5 + --> $DIR/types.rs:126:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: symbol-name(_ZN1a1b16Type$LT$f128$GT$17h[HASH]E) + --> $DIR/types.rs:135:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling(a::b::Type::h[HASH]) + --> $DIR/types.rs:135:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling-alt(a::b::Type) + --> $DIR/types.rs:135:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: symbol-name(_ZN1a1b15Type$LT$str$GT$17h[HASH]E) - --> $DIR/types.rs:85:5 + --> $DIR/types.rs:144:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(a::b::Type::h[HASH]) - --> $DIR/types.rs:85:5 + --> $DIR/types.rs:144:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(a::b::Type) - --> $DIR/types.rs:85:5 + --> $DIR/types.rs:144:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: symbol-name(_ZN1a1b17Type$LT$$u21$$GT$17h[HASH]E) - --> $DIR/types.rs:91:5 + --> $DIR/types.rs:153:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(a::b::Type::h[HASH]) - --> $DIR/types.rs:91:5 + --> $DIR/types.rs:153:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(a::b::Type) - --> $DIR/types.rs:91:5 + --> $DIR/types.rs:153:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: symbol-name(_ZN1a1b20Type$LT$$LP$$RP$$GT$17h[HASH]E) - --> $DIR/types.rs:97:5 + --> $DIR/types.rs:162:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(a::b::Type<()>::h[HASH]) - --> $DIR/types.rs:97:5 + --> $DIR/types.rs:162:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(a::b::Type<()>) - --> $DIR/types.rs:97:5 + --> $DIR/types.rs:162:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: symbol-name(_ZN1a1b25Type$LT$$LP$u8$C$$RP$$GT$17h[HASH]E) - --> $DIR/types.rs:103:5 + --> $DIR/types.rs:171:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(a::b::Type<(u8,)>::h[HASH]) - --> $DIR/types.rs:103:5 + --> $DIR/types.rs:171:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(a::b::Type<(u8,)>) - --> $DIR/types.rs:103:5 + --> $DIR/types.rs:171:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: symbol-name(_ZN1a1b28Type$LT$$LP$u8$C$u16$RP$$GT$17h[HASH]E) - --> $DIR/types.rs:109:5 + --> $DIR/types.rs:180:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(a::b::Type<(u8,u16)>::h[HASH]) - --> $DIR/types.rs:109:5 + --> $DIR/types.rs:180:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(a::b::Type<(u8,u16)>) - --> $DIR/types.rs:109:5 + --> $DIR/types.rs:180:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: symbol-name(_ZN1a1b34Type$LT$$LP$u8$C$u16$C$u32$RP$$GT$17h[HASH]E) - --> $DIR/types.rs:115:5 + --> $DIR/types.rs:189:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(a::b::Type<(u8,u16,u32)>::h[HASH]) - --> $DIR/types.rs:115:5 + --> $DIR/types.rs:189:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(a::b::Type<(u8,u16,u32)>) - --> $DIR/types.rs:115:5 + --> $DIR/types.rs:189:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: symbol-name(_ZN1a1b28Type$LT$$BP$const$u20$u8$GT$17h[HASH]E) - --> $DIR/types.rs:121:5 + --> $DIR/types.rs:198:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(a::b::Type<*const u8>::h[HASH]) - --> $DIR/types.rs:121:5 + --> $DIR/types.rs:198:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(a::b::Type<*const u8>) - --> $DIR/types.rs:121:5 + --> $DIR/types.rs:198:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: symbol-name(_ZN1a1b26Type$LT$$BP$mut$u20$u8$GT$17h[HASH]E) - --> $DIR/types.rs:127:5 + --> $DIR/types.rs:207:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(a::b::Type<*mut u8>::h[HASH]) - --> $DIR/types.rs:127:5 + --> $DIR/types.rs:207:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(a::b::Type<*mut u8>) - --> $DIR/types.rs:127:5 + --> $DIR/types.rs:207:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: symbol-name(_ZN1a1b19Type$LT$$RF$str$GT$17h[HASH]E) - --> $DIR/types.rs:133:5 + --> $DIR/types.rs:216:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(a::b::Type<&str>::h[HASH]) - --> $DIR/types.rs:133:5 + --> $DIR/types.rs:216:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(a::b::Type<&str>) - --> $DIR/types.rs:133:5 + --> $DIR/types.rs:216:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: symbol-name(_ZN1a1b27Type$LT$$RF$mut$u20$str$GT$17h[HASH]E) - --> $DIR/types.rs:139:5 + --> $DIR/types.rs:225:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(a::b::Type<&mut str>::h[HASH]) - --> $DIR/types.rs:139:5 + --> $DIR/types.rs:225:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(a::b::Type<&mut str>) - --> $DIR/types.rs:139:5 + --> $DIR/types.rs:225:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: symbol-name(_ZN1a1b35Type$LT$$u5b$u8$u3b$$u20$0$u5d$$GT$17h[HASH]E) - --> $DIR/types.rs:145:5 + --> $DIR/types.rs:234:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(a::b::Type<[u8; 0]>::h[HASH]) - --> $DIR/types.rs:145:5 + --> $DIR/types.rs:234:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(a::b::Type<[u8; 0]>) - --> $DIR/types.rs:145:5 + --> $DIR/types.rs:234:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: symbol-name(_ZN1a1b22Type$LT$fn$LP$$RP$$GT$17h[HASH]E) - --> $DIR/types.rs:151:5 + --> $DIR/types.rs:243:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(a::b::Type::h[HASH]) - --> $DIR/types.rs:151:5 + --> $DIR/types.rs:243:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(a::b::Type) - --> $DIR/types.rs:151:5 + --> $DIR/types.rs:243:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: symbol-name(_ZN1a1b60Type$LT$unsafe$u20$extern$u20$$u22$C$u22$$u20$fn$LP$$RP$$GT$17h[HASH]E) - --> $DIR/types.rs:157:5 + --> $DIR/types.rs:252:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(a::b::Type::h[HASH]) - --> $DIR/types.rs:157:5 + --> $DIR/types.rs:252:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(a::b::Type) - --> $DIR/types.rs:157:5 + --> $DIR/types.rs:252:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: symbol-name(_ZN1a1b34Type$LT$$u5b$T$u3b$$u20$N$u5d$$GT$17h[HASH]E) - --> $DIR/types.rs:163:5 + --> $DIR/types.rs:261:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(a::b::Type<[T; N]>::h[HASH]) - --> $DIR/types.rs:163:5 + --> $DIR/types.rs:261:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(a::b::Type<[T; N]>) - --> $DIR/types.rs:163:5 + --> $DIR/types.rs:261:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 78 previous errors +error: aborting due to 84 previous errors diff --git a/tests/ui/symbol-names/types.rs b/tests/ui/symbol-names/types.rs index b121408c843b5..7ed19e0e5a825 100644 --- a/tests/ui/symbol-names/types.rs +++ b/tests/ui/symbol-names/types.rs @@ -1,169 +1,270 @@ //@ build-fail -//@ revisions: legacy verbose-legacy -//@ compile-flags: --crate-name=a -C symbol-mangling-version=legacy -Z unstable-options -//@[verbose-legacy]compile-flags: -Zverbose-internals +//@ revisions: legacy verbose-legacy v0 +//@ compile-flags: --crate-name=a -Z unstable-options +//@ [legacy] compile-flags: -Csymbol-mangling-version=legacy +//@ [verbose-legacy] compile-flags: -Csymbol-mangling-version=legacy -Zverbose-internals +//@ [v0] compile-flags: -Csymbol-mangling-version=v0 //@ normalize-stderr-test: "h[[:xdigit:]]{16}" -> "h[HASH]" +//@ [v0] normalize-stderr-test: "\[[[:xdigit:]]{16}\]" -> "[HASH]" #![feature(never_type)] #![feature(rustc_attrs)] +#![feature(f128)] +#![feature(f16)] pub fn b() { struct Type(T); #[rustc_symbol_name] - //~^ ERROR symbol-name(_ZN1a1b16Type$LT$bool$GT$ - //~| ERROR demangling(a::b::Type:: - //~| ERROR demangling-alt(a::b::Type) + //[legacy,verbose-legacy]~^ ERROR symbol-name(_ZN1a1b16Type$LT$bool$GT$ + //[legacy,verbose-legacy]~| ERROR demangling(a::b::Type:: + //[legacy,verbose-legacy]~| ERROR demangling-alt(a::b::Type) + //[v0]~^^^^ ERROR symbol-name(_RMNvCsCRATE_HASH_1a1bINtB_4TypebE) + //[v0]~| ERROR ::b::Type>) + //[v0]~| ERROR demangling-alt(>) impl Type {} #[rustc_symbol_name] - //~^ ERROR symbol-name(_ZN1a1b16Type$LT$char$GT$ - //~| ERROR demangling(a::b::Type:: - //~| ERROR demangling-alt(a::b::Type) + //[legacy,verbose-legacy]~^ ERROR symbol-name(_ZN1a1b16Type$LT$char$GT$ + //[legacy,verbose-legacy]~| ERROR demangling(a::b::Type:: + //[legacy,verbose-legacy]~| ERROR demangling-alt(a::b::Type) + //[v0]~^^^^ ERROR symbol-name(_RMs_NvCsCRATE_HASH_1a1bINtB_4TypecE) + //[v0]~| ERROR ::b::Type>) + //[v0]~| ERROR demangling-alt(>) impl Type {} #[rustc_symbol_name] - //~^ ERROR symbol-name(_ZN1a1b14Type$LT$i8$GT$ - //~| ERROR demangling(a::b::Type:: - //~| ERROR demangling-alt(a::b::Type) + //[legacy,verbose-legacy]~^ ERROR symbol-name(_ZN1a1b14Type$LT$i8$GT$ + //[legacy,verbose-legacy]~| ERROR demangling(a::b::Type:: + //[legacy,verbose-legacy]~| ERROR demangling-alt(a::b::Type) + //[v0]~^^^^ ERROR symbol-name(_RMs0_NvCsCRATE_HASH_1a1bINtB_4TypeaE) + //[v0]~| ERROR ::b::Type>) + //[v0]~| ERROR demangling-alt(>) impl Type {} #[rustc_symbol_name] - //~^ ERROR symbol-name(_ZN1a1b15Type$LT$i16$GT$ - //~| ERROR demangling(a::b::Type:: - //~| ERROR demangling-alt(a::b::Type) + //[legacy,verbose-legacy]~^ ERROR symbol-name(_ZN1a1b15Type$LT$i16$GT$ + //[legacy,verbose-legacy]~| ERROR demangling(a::b::Type:: + //[legacy,verbose-legacy]~| ERROR demangling-alt(a::b::Type) + //[v0]~^^^^ ERROR symbol-name(_RMs1_NvCsCRATE_HASH_1a1bINtB_4TypesE) + //[v0]~| ERROR ::b::Type>) + //[v0]~| ERROR demangling-alt(>) impl Type {} #[rustc_symbol_name] - //~^ ERROR symbol-name(_ZN1a1b15Type$LT$i32$GT$ - //~| ERROR demangling(a::b::Type:: - //~| ERROR demangling-alt(a::b::Type) + //[legacy,verbose-legacy]~^ ERROR symbol-name(_ZN1a1b15Type$LT$i32$GT$ + //[legacy,verbose-legacy]~| ERROR demangling(a::b::Type:: + //[legacy,verbose-legacy]~| ERROR demangling-alt(a::b::Type) + //[v0]~^^^^ ERROR symbol-name(_RMs2_NvCsCRATE_HASH_1a1bINtB_4TypelE) + //[v0]~| ERROR ::b::Type>) + //[v0]~| ERROR demangling-alt(>) impl Type {} #[rustc_symbol_name] - //~^ ERROR symbol-name(_ZN1a1b15Type$LT$i64$GT$ - //~| ERROR demangling(a::b::Type:: - //~| ERROR demangling-alt(a::b::Type) + //[legacy,verbose-legacy]~^ ERROR symbol-name(_ZN1a1b15Type$LT$i64$GT$ + //[legacy,verbose-legacy]~| ERROR demangling(a::b::Type:: + //[legacy,verbose-legacy]~| ERROR demangling-alt(a::b::Type) + //[v0]~^^^^ ERROR symbol-name(_RMs3_NvCsCRATE_HASH_1a1bINtB_4TypexE) + //[v0]~| ERROR ::b::Type>) + //[v0]~| ERROR demangling-alt(>) impl Type {} #[rustc_symbol_name] - //~^ ERROR symbol-name(_ZN1a1b14Type$LT$u8$GT$ - //~| ERROR demangling(a::b::Type:: - //~| ERROR demangling-alt(a::b::Type) + //[legacy,verbose-legacy]~^ ERROR symbol-name(_ZN1a1b14Type$LT$u8$GT$ + //[legacy,verbose-legacy]~| ERROR demangling(a::b::Type:: + //[legacy,verbose-legacy]~| ERROR demangling-alt(a::b::Type) + //[v0]~^^^^ ERROR symbol-name(_RMs4_NvCsCRATE_HASH_1a1bINtB_4TypehE) + //[v0]~| ERROR ::b::Type>) + //[v0]~| ERROR demangling-alt(>) impl Type {} #[rustc_symbol_name] - //~^ ERROR symbol-name(_ZN1a1b15Type$LT$u16$GT$ - //~| ERROR demangling(a::b::Type:: - //~| ERROR demangling-alt(a::b::Type) + //[legacy,verbose-legacy]~^ ERROR symbol-name(_ZN1a1b15Type$LT$u16$GT$ + //[legacy,verbose-legacy]~| ERROR demangling(a::b::Type:: + //[legacy,verbose-legacy]~| ERROR demangling-alt(a::b::Type) + //[v0]~^^^^ ERROR symbol-name(_RMs5_NvCsCRATE_HASH_1a1bINtB_4TypetE) + //[v0]~| ERROR ::b::Type>) + //[v0]~| ERROR demangling-alt(>) impl Type {} #[rustc_symbol_name] - //~^ ERROR symbol-name(_ZN1a1b15Type$LT$u32$GT$ - //~| ERROR demangling(a::b::Type:: - //~| ERROR demangling-alt(a::b::Type) + //[legacy,verbose-legacy]~^ ERROR symbol-name(_ZN1a1b15Type$LT$u32$GT$ + //[legacy,verbose-legacy]~| ERROR demangling(a::b::Type:: + //[legacy,verbose-legacy]~| ERROR demangling-alt(a::b::Type) + //[v0]~^^^^ ERROR symbol-name(_RMs6_NvCsCRATE_HASH_1a1bINtB_4TypemE) + //[v0]~| ERROR ::b::Type>) + //[v0]~| ERROR demangling-alt(>) impl Type {} #[rustc_symbol_name] - //~^ ERROR symbol-name(_ZN1a1b15Type$LT$u64$GT$ - //~| ERROR demangling(a::b::Type:: - //~| ERROR demangling-alt(a::b::Type) + //[legacy,verbose-legacy]~^ ERROR symbol-name(_ZN1a1b15Type$LT$u64$GT$ + //[legacy,verbose-legacy]~| ERROR demangling(a::b::Type:: + //[legacy,verbose-legacy]~| ERROR demangling-alt(a::b::Type) + //[v0]~^^^^ ERROR symbol-name(_RMs7_NvCsCRATE_HASH_1a1bINtB_4TypeyE) + //[v0]~| ERROR ::b::Type>) + //[v0]~| ERROR demangling-alt(>) impl Type {} #[rustc_symbol_name] - //~^ ERROR symbol-name(_ZN1a1b15Type$LT$f32$GT$ - //~| ERROR demangling(a::b::Type:: - //~| ERROR demangling-alt(a::b::Type) + //[legacy,verbose-legacy]~^ ERROR symbol-name(_ZN1a1b15Type$LT$f16$GT$ + //[legacy,verbose-legacy]~| ERROR demangling(a::b::Type:: + //[legacy,verbose-legacy]~| ERROR demangling-alt(a::b::Type) + //[v0]~^^^^ ERROR symbol-name(_RMs8_NvCsCRATE_HASH_1a1bINtB_4TypeC3f16E) + //[v0]~| ERROR ::b::Type>) + //[v0]~| ERROR demangling-alt(>) + impl Type {} + + #[rustc_symbol_name] + //[legacy,verbose-legacy]~^ ERROR symbol-name(_ZN1a1b15Type$LT$f32$GT$ + //[legacy,verbose-legacy]~| ERROR demangling(a::b::Type:: + //[legacy,verbose-legacy]~| ERROR demangling-alt(a::b::Type) + //[v0]~^^^^ ERROR symbol-name(_RMs9_NvCsCRATE_HASH_1a1bINtB_4TypefE) + //[v0]~| ERROR ::b::Type>) + //[v0]~| ERROR demangling-alt(>) impl Type {} #[rustc_symbol_name] - //~^ ERROR symbol-name(_ZN1a1b15Type$LT$f64$GT$ - //~| ERROR demangling(a::b::Type:: - //~| ERROR demangling-alt(a::b::Type) + //[legacy,verbose-legacy]~^ ERROR symbol-name(_ZN1a1b15Type$LT$f64$GT$ + //[legacy,verbose-legacy]~| ERROR demangling(a::b::Type:: + //[legacy,verbose-legacy]~| ERROR demangling-alt(a::b::Type) + //[v0]~^^^^ ERROR symbol-name(_RMsa_NvCsCRATE_HASH_1a1bINtB_4TypedE) + //[v0]~| ERROR ::b::Type>) + //[v0]~| ERROR demangling-alt(>) impl Type {} #[rustc_symbol_name] - //~^ ERROR symbol-name(_ZN1a1b15Type$LT$str$GT$ - //~| ERROR demangling(a::b::Type:: - //~| ERROR demangling-alt(a::b::Type) + //[legacy,verbose-legacy]~^ ERROR symbol-name(_ZN1a1b16Type$LT$f128$GT$ + //[legacy,verbose-legacy]~| ERROR demangling(a::b::Type:: + //[legacy,verbose-legacy]~| ERROR demangling-alt(a::b::Type) + //[v0]~^^^^ ERROR symbol-name(_RMsb_NvCsCRATE_HASH_1a1bINtB_4TypeC4f128E) + //[v0]~| ERROR ::b::Type>) + //[v0]~| ERROR demangling-alt(>) + impl Type {} + + #[rustc_symbol_name] + //[legacy,verbose-legacy]~^ ERROR symbol-name(_ZN1a1b15Type$LT$str$GT$ + //[legacy,verbose-legacy]~| ERROR demangling(a::b::Type:: + //[legacy,verbose-legacy]~| ERROR demangling-alt(a::b::Type) + //[v0]~^^^^ ERROR symbol-name(_RMsc_NvCsCRATE_HASH_1a1bINtB_4TypeeE) + //[v0]~| ERROR ::b::Type>) + //[v0]~| ERROR demangling-alt(>) impl Type {} #[rustc_symbol_name] - //~^ ERROR symbol-name(_ZN1a1b17Type$LT$$u21$$GT$ - //~| ERROR demangling(a::b::Type:: - //~| ERROR demangling-alt(a::b::Type) + //[legacy,verbose-legacy]~^ ERROR symbol-name(_ZN1a1b17Type$LT$$u21$$GT$ + //[legacy,verbose-legacy]~| ERROR demangling(a::b::Type:: + //[legacy,verbose-legacy]~| ERROR demangling-alt(a::b::Type) + //[v0]~^^^^ ERROR symbol-name(_RMsd_NvCsCRATE_HASH_1a1bINtB_4TypezE) + //[v0]~| ERROR ::b::Type>) + //[v0]~| ERROR demangling-alt(>) impl Type {} #[rustc_symbol_name] - //~^ ERROR symbol-name(_ZN1a1b20Type$LT$$LP$$RP$$GT - //~| ERROR demangling(a::b::Type<()>:: - //~| ERROR demangling-alt(a::b::Type<()>) + //[legacy,verbose-legacy]~^ ERROR symbol-name(_ZN1a1b20Type$LT$$LP$$RP$$GT$ + //[legacy,verbose-legacy]~| ERROR demangling(a::b::Type<()>:: + //[legacy,verbose-legacy]~| ERROR demangling-alt(a::b::Type<()>) + //[v0]~^^^^ ERROR symbol-name(_RMse_NvCsCRATE_HASH_1a1bINtB_4TypeuE) + //[v0]~| ERROR ::b::Type<()>>) + //[v0]~| ERROR demangling-alt(>) impl Type<()> {} #[rustc_symbol_name] - //~^ ERROR symbol-name(_ZN1a1b25Type$LT$$LP$u8$C$$RP$$GT$ - //~| ERROR demangling(a::b::Type<(u8,)>:: - //~| ERROR demangling-alt(a::b::Type<(u8,)>) + //[legacy,verbose-legacy]~^ ERROR symbol-name(_ZN1a1b25Type$LT$$LP$u8$C$$RP$$GT$ + //[legacy,verbose-legacy]~| ERROR demangling(a::b::Type<(u8,)>:: + //[legacy,verbose-legacy]~| ERROR demangling-alt(a::b::Type<(u8,)>) + //[v0]~^^^^ ERROR symbol-name(_RMsf_NvCsCRATE_HASH_1a1bINtB_4TypeThEE) + //[v0]~| ERROR ::b::Type<(u8,)>>) + //[v0]~| ERROR demangling-alt(>) impl Type<(u8,)> {} #[rustc_symbol_name] - //~^ ERROR symbol-name(_ZN1a1b28Type$LT$$LP$u8$C$u16$RP$$GT$ - //~| ERROR demangling(a::b::Type<(u8,u16)>:: - //~| ERROR demangling-alt(a::b::Type<(u8,u16)>) - impl Type<(u8,u16)> {} + //[legacy,verbose-legacy]~^ ERROR symbol-name(_ZN1a1b28Type$LT$$LP$u8$C$u16$RP$$GT$ + //[legacy,verbose-legacy]~| ERROR demangling(a::b::Type<(u8,u16)>:: + //[legacy,verbose-legacy]~| ERROR demangling-alt(a::b::Type<(u8,u16)>) + //[v0]~^^^^ ERROR symbol-name(_RMsg_NvCsCRATE_HASH_1a1bINtB_4TypeThtEE) + //[v0]~| ERROR ::b::Type<(u8, u16)>>) + //[v0]~| ERROR demangling-alt(>) + impl Type<(u8, u16)> {} #[rustc_symbol_name] - //~^ ERROR symbol-name(_ZN1a1b34Type$LT$$LP$u8$C$u16$C$u32$RP$$GT$ - //~| ERROR demangling(a::b::Type<(u8,u16,u32)>:: - //~| ERROR demangling-alt(a::b::Type<(u8,u16,u32)>) - impl Type<(u8,u16,u32)> {} + //[legacy,verbose-legacy]~^ ERROR symbol-name(_ZN1a1b34Type$LT$$LP$u8$C$u16$C$u32$RP$$GT$ + //[legacy,verbose-legacy]~| ERROR demangling(a::b::Type<(u8,u16,u32)>:: + //[legacy,verbose-legacy]~| ERROR demangling-alt(a::b::Type<(u8,u16,u32)>) + //[v0]~^^^^ ERROR symbol-name(_RMsh_NvCsCRATE_HASH_1a1bINtB_4TypeThtmEE) + //[v0]~| ERROR ::b::Type<(u8, u16, u32)>>) + //[v0]~| ERROR demangling-alt(>) + impl Type<(u8, u16, u32)> {} #[rustc_symbol_name] - //~^ ERROR symbol-name(_ZN1a1b28Type$LT$$BP$const$u20$u8$GT$ - //~| ERROR demangling(a::b::Type<*const u8>:: - //~| ERROR demangling-alt(a::b::Type<*const u8>) + //[legacy,verbose-legacy]~^ ERROR symbol-name(_ZN1a1b28Type$LT$$BP$const$u20$u8$GT$ + //[legacy,verbose-legacy]~| ERROR demangling(a::b::Type<*const u8>:: + //[legacy,verbose-legacy]~| ERROR demangling-alt(a::b::Type<*const u8>) + //[v0]~^^^^ ERROR symbol-name(_RMsi_NvCsCRATE_HASH_1a1bINtB_4TypePhE) + //[v0]~| ERROR ::b::Type<*const u8>>) + //[v0]~| ERROR demangling-alt(>) impl Type<*const u8> {} #[rustc_symbol_name] - //~^ ERROR symbol-name(_ZN1a1b26Type$LT$$BP$mut$u20$u8$GT$ - //~| ERROR demangling(a::b::Type<*mut u8>:: - //~| ERROR demangling-alt(a::b::Type<*mut u8>) + //[legacy,verbose-legacy]~^ ERROR symbol-name(_ZN1a1b26Type$LT$$BP$mut$u20$u8$GT$ + //[legacy,verbose-legacy]~| ERROR demangling(a::b::Type<*mut u8>:: + //[legacy,verbose-legacy]~| ERROR demangling-alt(a::b::Type<*mut u8>) + //[v0]~^^^^ ERROR symbol-name(_RMsj_NvCsCRATE_HASH_1a1bINtB_4TypeOhE) + //[v0]~| ERROR ::b::Type<*mut u8>>) + //[v0]~| ERROR demangling-alt(>) impl Type<*mut u8> {} #[rustc_symbol_name] - //~^ ERROR symbol-name(_ZN1a1b19Type$LT$$RF$str$GT$ - //~| ERROR demangling(a::b::Type<&str>:: - //~| ERROR demangling-alt(a::b::Type<&str>) + //[legacy,verbose-legacy]~^ ERROR symbol-name(_ZN1a1b19Type$LT$$RF$str$GT$ + //[legacy,verbose-legacy]~| ERROR demangling(a::b::Type<&str>:: + //[legacy,verbose-legacy]~| ERROR demangling-alt(a::b::Type<&str>) + //[v0]~^^^^ ERROR symbol-name(_RMsk_NvCsCRATE_HASH_1a1bINtB_4TypeReE) + //[v0]~| ERROR ::b::Type<&str>>) + //[v0]~| ERROR demangling-alt(>) impl Type<&str> {} #[rustc_symbol_name] - //~^ ERROR symbol-name(_ZN1a1b27Type$LT$$RF$mut$u20$str$GT$ - //~| ERROR demangling(a::b::Type<&mut str>:: - //~| ERROR demangling-alt(a::b::Type<&mut str>) + //[legacy,verbose-legacy]~^ ERROR symbol-name(_ZN1a1b27Type$LT$$RF$mut$u20$str$GT$ + //[legacy,verbose-legacy]~| ERROR demangling(a::b::Type<&mut str>:: + //[legacy,verbose-legacy]~| ERROR demangling-alt(a::b::Type<&mut str>) + //[v0]~^^^^ ERROR symbol-name(_RMsl_NvCsCRATE_HASH_1a1bINtB_4TypeQeE) + //[v0]~| ERROR ::b::Type<&mut str>>) + //[v0]~| ERROR demangling-alt(>) impl Type<&mut str> {} #[rustc_symbol_name] - //~^ ERROR symbol-name(_ZN1a1b35Type$LT$$u5b$u8$u3b$$u20$0$u5d$$GT$ - //~| ERROR demangling(a::b::Type<[u8; 0]>:: - //~| ERROR demangling-alt(a::b::Type<[u8; 0]>) + //[legacy,verbose-legacy]~^ ERROR symbol-name(_ZN1a1b35Type$LT$$u5b$u8$u3b$$u20$0$u5d$$GT$ + //[legacy,verbose-legacy]~| ERROR demangling(a::b::Type<[u8; 0]>:: + //[legacy,verbose-legacy]~| ERROR demangling-alt(a::b::Type<[u8; 0]>) + //[v0]~^^^^ ERROR symbol-name(_RMsm_NvCsCRATE_HASH_1a1bINtB_4TypeAhj0_E) + //[v0]~| ERROR ::b::Type<[u8; 0usize]>>) + //[v0]~| ERROR demangling-alt(>) impl Type<[u8; 0]> {} #[rustc_symbol_name] - //~^ ERROR symbol-name(_ZN1a1b22Type$LT$fn$LP$$RP$$GT$ - //~| ERROR demangling(a::b::Type:: - //~| ERROR demangling-alt(a::b::Type) + //[legacy,verbose-legacy]~^ ERROR symbol-name(_ZN1a1b22Type$LT$fn$LP$$RP$$GT$ + //[legacy,verbose-legacy]~| ERROR demangling(a::b::Type:: + //[legacy,verbose-legacy]~| ERROR demangling-alt(a::b::Type) + //[v0]~^^^^ ERROR symbol-name(_RMsn_NvCsCRATE_HASH_1a1bINtB_4TypeFEuE) + //[v0]~| ERROR ::b::Type>) + //[v0]~| ERROR demangling-alt(>) impl Type {} #[rustc_symbol_name] - //~^ ERROR symbol-name(_ZN1a1b60Type$LT$unsafe$u20$extern$u20$$u22$C$u22$$u20$fn$LP$$RP$$GT$ - //~| ERROR demangling(a::b::Type:: - //~| ERROR demangling-alt(a::b::Type) + //[legacy,verbose-legacy]~^ ERROR symbol-name(_ZN1a1b60Type$LT$unsafe$u20$extern$u20$$u22$C$u22$$u20$fn$LP$$RP$$GT$ + //[legacy,verbose-legacy]~| ERROR demangling(a::b::Type:: + //[legacy,verbose-legacy]~| ERROR demangling-alt(a::b::Type) + //[v0]~^^^^ ERROR symbol-name(_RMso_NvCsCRATE_HASH_1a1bINtB_4TypeFUKCEuE) + //[v0]~| ERROR ::b::Type>) + //[v0]~| ERROR demangling-alt(>) impl Type {} #[rustc_symbol_name] - //~^ ERROR symbol-name(_ZN1a1b34Type$LT$$u5b$T$u3b$$u20$N$u5d$$GT$ - //~| ERROR demangling(a::b::Type<[T; N]>:: - //~| ERROR demangling-alt(a::b::Type<[T; N]>) + //[legacy,verbose-legacy]~^ ERROR symbol-name(_ZN1a1b34Type$LT$$u5b$T$u3b$$u20$N$u5d$$GT$ + //[legacy,verbose-legacy]~| ERROR demangling(a::b::Type<[T; N]>:: + //[legacy,verbose-legacy]~| ERROR demangling-alt(a::b::Type<[T; N]>) + //[v0]~^^^^ ERROR symbol-name(_RMsp_NvCsCRATE_HASH_1a1bINtB_4TypeAppEB_) + //[v0]~| ERROR ::b::Type<[_; _]>>) + //[v0]~| ERROR demangling-alt(>) impl Type<[T; N]> {} } diff --git a/tests/ui/symbol-names/types.v0.stderr b/tests/ui/symbol-names/types.v0.stderr new file mode 100644 index 0000000000000..58680e002022a --- /dev/null +++ b/tests/ui/symbol-names/types.v0.stderr @@ -0,0 +1,506 @@ +error: symbol-name(_RMNvCsCRATE_HASH_1a1bINtB_4TypebE) + --> $DIR/types.rs:18:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling(>) + --> $DIR/types.rs:18:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling-alt(>) + --> $DIR/types.rs:18:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: symbol-name(_RMs_NvCsCRATE_HASH_1a1bINtB_4TypecE) + --> $DIR/types.rs:27:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling(>) + --> $DIR/types.rs:27:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling-alt(>) + --> $DIR/types.rs:27:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: symbol-name(_RMs0_NvCsCRATE_HASH_1a1bINtB_4TypeaE) + --> $DIR/types.rs:36:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling(>) + --> $DIR/types.rs:36:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling-alt(>) + --> $DIR/types.rs:36:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: symbol-name(_RMs1_NvCsCRATE_HASH_1a1bINtB_4TypesE) + --> $DIR/types.rs:45:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling(>) + --> $DIR/types.rs:45:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling-alt(>) + --> $DIR/types.rs:45:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: symbol-name(_RMs2_NvCsCRATE_HASH_1a1bINtB_4TypelE) + --> $DIR/types.rs:54:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling(>) + --> $DIR/types.rs:54:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling-alt(>) + --> $DIR/types.rs:54:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: symbol-name(_RMs3_NvCsCRATE_HASH_1a1bINtB_4TypexE) + --> $DIR/types.rs:63:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling(>) + --> $DIR/types.rs:63:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling-alt(>) + --> $DIR/types.rs:63:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: symbol-name(_RMs4_NvCsCRATE_HASH_1a1bINtB_4TypehE) + --> $DIR/types.rs:72:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling(>) + --> $DIR/types.rs:72:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling-alt(>) + --> $DIR/types.rs:72:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: symbol-name(_RMs5_NvCsCRATE_HASH_1a1bINtB_4TypetE) + --> $DIR/types.rs:81:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling(>) + --> $DIR/types.rs:81:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling-alt(>) + --> $DIR/types.rs:81:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: symbol-name(_RMs6_NvCsCRATE_HASH_1a1bINtB_4TypemE) + --> $DIR/types.rs:90:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling(>) + --> $DIR/types.rs:90:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling-alt(>) + --> $DIR/types.rs:90:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: symbol-name(_RMs7_NvCsCRATE_HASH_1a1bINtB_4TypeyE) + --> $DIR/types.rs:99:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling(>) + --> $DIR/types.rs:99:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling-alt(>) + --> $DIR/types.rs:99:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: symbol-name(_RMs8_NvCsCRATE_HASH_1a1bINtB_4TypeC3f16E) + --> $DIR/types.rs:108:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling(>) + --> $DIR/types.rs:108:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling-alt(>) + --> $DIR/types.rs:108:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: symbol-name(_RMs9_NvCsCRATE_HASH_1a1bINtB_4TypefE) + --> $DIR/types.rs:117:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling(>) + --> $DIR/types.rs:117:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling-alt(>) + --> $DIR/types.rs:117:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: symbol-name(_RMsa_NvCsCRATE_HASH_1a1bINtB_4TypedE) + --> $DIR/types.rs:126:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling(>) + --> $DIR/types.rs:126:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling-alt(>) + --> $DIR/types.rs:126:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: symbol-name(_RMsb_NvCsCRATE_HASH_1a1bINtB_4TypeC4f128E) + --> $DIR/types.rs:135:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling(>) + --> $DIR/types.rs:135:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling-alt(>) + --> $DIR/types.rs:135:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: symbol-name(_RMsc_NvCsCRATE_HASH_1a1bINtB_4TypeeE) + --> $DIR/types.rs:144:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling(>) + --> $DIR/types.rs:144:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling-alt(>) + --> $DIR/types.rs:144:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: symbol-name(_RMsd_NvCsCRATE_HASH_1a1bINtB_4TypezE) + --> $DIR/types.rs:153:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling(>) + --> $DIR/types.rs:153:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling-alt(>) + --> $DIR/types.rs:153:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: symbol-name(_RMse_NvCsCRATE_HASH_1a1bINtB_4TypeuE) + --> $DIR/types.rs:162:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling(>) + --> $DIR/types.rs:162:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling-alt(>) + --> $DIR/types.rs:162:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: symbol-name(_RMsf_NvCsCRATE_HASH_1a1bINtB_4TypeThEE) + --> $DIR/types.rs:171:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling(>) + --> $DIR/types.rs:171:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling-alt(>) + --> $DIR/types.rs:171:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: symbol-name(_RMsg_NvCsCRATE_HASH_1a1bINtB_4TypeThtEE) + --> $DIR/types.rs:180:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling(>) + --> $DIR/types.rs:180:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling-alt(>) + --> $DIR/types.rs:180:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: symbol-name(_RMsh_NvCsCRATE_HASH_1a1bINtB_4TypeThtmEE) + --> $DIR/types.rs:189:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling(>) + --> $DIR/types.rs:189:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling-alt(>) + --> $DIR/types.rs:189:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: symbol-name(_RMsi_NvCsCRATE_HASH_1a1bINtB_4TypePhE) + --> $DIR/types.rs:198:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling(>) + --> $DIR/types.rs:198:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling-alt(>) + --> $DIR/types.rs:198:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: symbol-name(_RMsj_NvCsCRATE_HASH_1a1bINtB_4TypeOhE) + --> $DIR/types.rs:207:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling(>) + --> $DIR/types.rs:207:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling-alt(>) + --> $DIR/types.rs:207:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: symbol-name(_RMsk_NvCsCRATE_HASH_1a1bINtB_4TypeReE) + --> $DIR/types.rs:216:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling(>) + --> $DIR/types.rs:216:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling-alt(>) + --> $DIR/types.rs:216:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: symbol-name(_RMsl_NvCsCRATE_HASH_1a1bINtB_4TypeQeE) + --> $DIR/types.rs:225:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling(>) + --> $DIR/types.rs:225:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling-alt(>) + --> $DIR/types.rs:225:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: symbol-name(_RMsm_NvCsCRATE_HASH_1a1bINtB_4TypeAhj0_E) + --> $DIR/types.rs:234:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling(>) + --> $DIR/types.rs:234:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling-alt(>) + --> $DIR/types.rs:234:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: symbol-name(_RMsn_NvCsCRATE_HASH_1a1bINtB_4TypeFEuE) + --> $DIR/types.rs:243:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling(>) + --> $DIR/types.rs:243:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling-alt(>) + --> $DIR/types.rs:243:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: symbol-name(_RMso_NvCsCRATE_HASH_1a1bINtB_4TypeFUKCEuE) + --> $DIR/types.rs:252:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling(>) + --> $DIR/types.rs:252:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling-alt(>) + --> $DIR/types.rs:252:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: symbol-name(_RMsp_NvCsCRATE_HASH_1a1bINtB_4TypeAppEB_) + --> $DIR/types.rs:261:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling(>) + --> $DIR/types.rs:261:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling-alt(>) + --> $DIR/types.rs:261:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 84 previous errors + diff --git a/tests/ui/symbol-names/types.verbose-legacy.stderr b/tests/ui/symbol-names/types.verbose-legacy.stderr index a4984d5629f7d..87c3acae0bd6c 100644 --- a/tests/ui/symbol-names/types.verbose-legacy.stderr +++ b/tests/ui/symbol-names/types.verbose-legacy.stderr @@ -1,470 +1,506 @@ error: symbol-name(_ZN1a1b16Type$LT$bool$GT$17h[HASH]E) - --> $DIR/types.rs:13:5 + --> $DIR/types.rs:18:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(a::b::Type::h[HASH]) - --> $DIR/types.rs:13:5 + --> $DIR/types.rs:18:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(a::b::Type) - --> $DIR/types.rs:13:5 + --> $DIR/types.rs:18:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: symbol-name(_ZN1a1b16Type$LT$char$GT$17h[HASH]E) - --> $DIR/types.rs:19:5 + --> $DIR/types.rs:27:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(a::b::Type::h[HASH]) - --> $DIR/types.rs:19:5 + --> $DIR/types.rs:27:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(a::b::Type) - --> $DIR/types.rs:19:5 + --> $DIR/types.rs:27:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: symbol-name(_ZN1a1b14Type$LT$i8$GT$17h[HASH]E) - --> $DIR/types.rs:25:5 + --> $DIR/types.rs:36:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(a::b::Type::h[HASH]) - --> $DIR/types.rs:25:5 + --> $DIR/types.rs:36:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(a::b::Type) - --> $DIR/types.rs:25:5 + --> $DIR/types.rs:36:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: symbol-name(_ZN1a1b15Type$LT$i16$GT$17h[HASH]E) - --> $DIR/types.rs:31:5 + --> $DIR/types.rs:45:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(a::b::Type::h[HASH]) - --> $DIR/types.rs:31:5 + --> $DIR/types.rs:45:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(a::b::Type) - --> $DIR/types.rs:31:5 + --> $DIR/types.rs:45:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: symbol-name(_ZN1a1b15Type$LT$i32$GT$17h[HASH]E) - --> $DIR/types.rs:37:5 + --> $DIR/types.rs:54:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(a::b::Type::h[HASH]) - --> $DIR/types.rs:37:5 + --> $DIR/types.rs:54:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(a::b::Type) - --> $DIR/types.rs:37:5 + --> $DIR/types.rs:54:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: symbol-name(_ZN1a1b15Type$LT$i64$GT$17h[HASH]E) - --> $DIR/types.rs:43:5 + --> $DIR/types.rs:63:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(a::b::Type::h[HASH]) - --> $DIR/types.rs:43:5 + --> $DIR/types.rs:63:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(a::b::Type) - --> $DIR/types.rs:43:5 + --> $DIR/types.rs:63:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: symbol-name(_ZN1a1b14Type$LT$u8$GT$17h[HASH]E) - --> $DIR/types.rs:49:5 + --> $DIR/types.rs:72:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(a::b::Type::h[HASH]) - --> $DIR/types.rs:49:5 + --> $DIR/types.rs:72:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(a::b::Type) - --> $DIR/types.rs:49:5 + --> $DIR/types.rs:72:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: symbol-name(_ZN1a1b15Type$LT$u16$GT$17h[HASH]E) - --> $DIR/types.rs:55:5 + --> $DIR/types.rs:81:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(a::b::Type::h[HASH]) - --> $DIR/types.rs:55:5 + --> $DIR/types.rs:81:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(a::b::Type) - --> $DIR/types.rs:55:5 + --> $DIR/types.rs:81:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: symbol-name(_ZN1a1b15Type$LT$u32$GT$17h[HASH]E) - --> $DIR/types.rs:61:5 + --> $DIR/types.rs:90:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(a::b::Type::h[HASH]) - --> $DIR/types.rs:61:5 + --> $DIR/types.rs:90:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(a::b::Type) - --> $DIR/types.rs:61:5 + --> $DIR/types.rs:90:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: symbol-name(_ZN1a1b15Type$LT$u64$GT$17h[HASH]E) - --> $DIR/types.rs:67:5 + --> $DIR/types.rs:99:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(a::b::Type::h[HASH]) - --> $DIR/types.rs:67:5 + --> $DIR/types.rs:99:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(a::b::Type) - --> $DIR/types.rs:67:5 + --> $DIR/types.rs:99:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: symbol-name(_ZN1a1b15Type$LT$f16$GT$17h[HASH]E) + --> $DIR/types.rs:108:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling(a::b::Type::h[HASH]) + --> $DIR/types.rs:108:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling-alt(a::b::Type) + --> $DIR/types.rs:108:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: symbol-name(_ZN1a1b15Type$LT$f32$GT$17h[HASH]E) - --> $DIR/types.rs:73:5 + --> $DIR/types.rs:117:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(a::b::Type::h[HASH]) - --> $DIR/types.rs:73:5 + --> $DIR/types.rs:117:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(a::b::Type) - --> $DIR/types.rs:73:5 + --> $DIR/types.rs:117:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: symbol-name(_ZN1a1b15Type$LT$f64$GT$17h[HASH]E) - --> $DIR/types.rs:79:5 + --> $DIR/types.rs:126:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(a::b::Type::h[HASH]) - --> $DIR/types.rs:79:5 + --> $DIR/types.rs:126:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(a::b::Type) - --> $DIR/types.rs:79:5 + --> $DIR/types.rs:126:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: symbol-name(_ZN1a1b16Type$LT$f128$GT$17h[HASH]E) + --> $DIR/types.rs:135:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling(a::b::Type::h[HASH]) + --> $DIR/types.rs:135:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling-alt(a::b::Type) + --> $DIR/types.rs:135:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: symbol-name(_ZN1a1b15Type$LT$str$GT$17h[HASH]E) - --> $DIR/types.rs:85:5 + --> $DIR/types.rs:144:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(a::b::Type::h[HASH]) - --> $DIR/types.rs:85:5 + --> $DIR/types.rs:144:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(a::b::Type) - --> $DIR/types.rs:85:5 + --> $DIR/types.rs:144:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: symbol-name(_ZN1a1b17Type$LT$$u21$$GT$17h[HASH]E) - --> $DIR/types.rs:91:5 + --> $DIR/types.rs:153:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(a::b::Type::h[HASH]) - --> $DIR/types.rs:91:5 + --> $DIR/types.rs:153:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(a::b::Type) - --> $DIR/types.rs:91:5 + --> $DIR/types.rs:153:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: symbol-name(_ZN1a1b20Type$LT$$LP$$RP$$GT$17h[HASH]E) - --> $DIR/types.rs:97:5 + --> $DIR/types.rs:162:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(a::b::Type<()>::h[HASH]) - --> $DIR/types.rs:97:5 + --> $DIR/types.rs:162:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(a::b::Type<()>) - --> $DIR/types.rs:97:5 + --> $DIR/types.rs:162:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: symbol-name(_ZN1a1b25Type$LT$$LP$u8$C$$RP$$GT$17h[HASH]E) - --> $DIR/types.rs:103:5 + --> $DIR/types.rs:171:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(a::b::Type<(u8,)>::h[HASH]) - --> $DIR/types.rs:103:5 + --> $DIR/types.rs:171:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(a::b::Type<(u8,)>) - --> $DIR/types.rs:103:5 + --> $DIR/types.rs:171:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: symbol-name(_ZN1a1b28Type$LT$$LP$u8$C$u16$RP$$GT$17h[HASH]E) - --> $DIR/types.rs:109:5 + --> $DIR/types.rs:180:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(a::b::Type<(u8,u16)>::h[HASH]) - --> $DIR/types.rs:109:5 + --> $DIR/types.rs:180:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(a::b::Type<(u8,u16)>) - --> $DIR/types.rs:109:5 + --> $DIR/types.rs:180:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: symbol-name(_ZN1a1b34Type$LT$$LP$u8$C$u16$C$u32$RP$$GT$17h[HASH]E) - --> $DIR/types.rs:115:5 + --> $DIR/types.rs:189:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(a::b::Type<(u8,u16,u32)>::h[HASH]) - --> $DIR/types.rs:115:5 + --> $DIR/types.rs:189:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(a::b::Type<(u8,u16,u32)>) - --> $DIR/types.rs:115:5 + --> $DIR/types.rs:189:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: symbol-name(_ZN1a1b28Type$LT$$BP$const$u20$u8$GT$17h[HASH]E) - --> $DIR/types.rs:121:5 + --> $DIR/types.rs:198:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(a::b::Type<*const u8>::h[HASH]) - --> $DIR/types.rs:121:5 + --> $DIR/types.rs:198:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(a::b::Type<*const u8>) - --> $DIR/types.rs:121:5 + --> $DIR/types.rs:198:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: symbol-name(_ZN1a1b26Type$LT$$BP$mut$u20$u8$GT$17h[HASH]E) - --> $DIR/types.rs:127:5 + --> $DIR/types.rs:207:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(a::b::Type<*mut u8>::h[HASH]) - --> $DIR/types.rs:127:5 + --> $DIR/types.rs:207:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(a::b::Type<*mut u8>) - --> $DIR/types.rs:127:5 + --> $DIR/types.rs:207:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: symbol-name(_ZN1a1b19Type$LT$$RF$str$GT$17h[HASH]E) - --> $DIR/types.rs:133:5 + --> $DIR/types.rs:216:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(a::b::Type<&str>::h[HASH]) - --> $DIR/types.rs:133:5 + --> $DIR/types.rs:216:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(a::b::Type<&str>) - --> $DIR/types.rs:133:5 + --> $DIR/types.rs:216:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: symbol-name(_ZN1a1b27Type$LT$$RF$mut$u20$str$GT$17h[HASH]E) - --> $DIR/types.rs:139:5 + --> $DIR/types.rs:225:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(a::b::Type<&mut str>::h[HASH]) - --> $DIR/types.rs:139:5 + --> $DIR/types.rs:225:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(a::b::Type<&mut str>) - --> $DIR/types.rs:139:5 + --> $DIR/types.rs:225:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: symbol-name(_ZN1a1b35Type$LT$$u5b$u8$u3b$$u20$0$u5d$$GT$17h[HASH]E) - --> $DIR/types.rs:145:5 + --> $DIR/types.rs:234:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(a::b::Type<[u8; 0]>::h[HASH]) - --> $DIR/types.rs:145:5 + --> $DIR/types.rs:234:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(a::b::Type<[u8; 0]>) - --> $DIR/types.rs:145:5 + --> $DIR/types.rs:234:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: symbol-name(_ZN1a1b22Type$LT$fn$LP$$RP$$GT$17h[HASH]E) - --> $DIR/types.rs:151:5 + --> $DIR/types.rs:243:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(a::b::Type::h[HASH]) - --> $DIR/types.rs:151:5 + --> $DIR/types.rs:243:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(a::b::Type) - --> $DIR/types.rs:151:5 + --> $DIR/types.rs:243:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: symbol-name(_ZN1a1b60Type$LT$unsafe$u20$extern$u20$$u22$C$u22$$u20$fn$LP$$RP$$GT$17h[HASH]E) - --> $DIR/types.rs:157:5 + --> $DIR/types.rs:252:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(a::b::Type::h[HASH]) - --> $DIR/types.rs:157:5 + --> $DIR/types.rs:252:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(a::b::Type) - --> $DIR/types.rs:157:5 + --> $DIR/types.rs:252:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: symbol-name(_ZN1a1b34Type$LT$$u5b$T$u3b$$u20$N$u5d$$GT$17h[HASH]E) - --> $DIR/types.rs:163:5 + --> $DIR/types.rs:261:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(a::b::Type<[T; N]>::h[HASH]) - --> $DIR/types.rs:163:5 + --> $DIR/types.rs:261:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(a::b::Type<[T; N]>) - --> $DIR/types.rs:163:5 + --> $DIR/types.rs:261:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 78 previous errors +error: aborting due to 84 previous errors From 8dc6a5d145af86955402ec02907dda77dcb4a122 Mon Sep 17 00:00:00 2001 From: ardi Date: Tue, 14 May 2024 12:23:33 +0200 Subject: [PATCH 176/179] improve maybe_consume_incorrect_semicolon --- compiler/rustc_ast/src/ast.rs | 1 + compiler/rustc_parse/src/errors.rs | 2 +- .../rustc_parse/src/parser/diagnostics.rs | 43 +++++++++---------- compiler/rustc_parse/src/parser/item.rs | 4 +- src/librustdoc/doctest.rs | 4 +- ...ecover-from-semicolon-trailing-item.stderr | 4 ++ 6 files changed, 30 insertions(+), 28 deletions(-) diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 7951b7e7b75a0..56d4f53f9eea4 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -3250,6 +3250,7 @@ pub enum ItemKind { } impl ItemKind { + /// "a" or "an" pub fn article(&self) -> &'static str { use ItemKind::*; match self { diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs index 2f68a299f26b6..3f08a830b0c9d 100644 --- a/compiler/rustc_parse/src/errors.rs +++ b/compiler/rustc_parse/src/errors.rs @@ -83,7 +83,7 @@ pub(crate) struct IncorrectSemicolon<'a> { #[suggestion(style = "short", code = "", applicability = "machine-applicable")] pub span: Span, #[help] - pub opt_help: Option<()>, + pub show_help: bool, pub name: &'a str, } diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index 63762f64be993..46809847fdbf4 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -1817,34 +1817,31 @@ impl<'a> Parser<'a> { Ok(P(T::recovered(Some(P(QSelf { ty, path_span, position: 0 })), path))) } - pub fn maybe_consume_incorrect_semicolon(&mut self, items: &[P]) -> bool { - if self.token.kind == TokenKind::Semi { - self.bump(); - - let mut err = - IncorrectSemicolon { span: self.prev_token.span, opt_help: None, name: "" }; + /// This function gets called in places where a semicolon is NOT expected and if there's a + /// semicolon it emits the appropriate error and returns true. + pub fn maybe_consume_incorrect_semicolon(&mut self, previous_item: Option<&Item>) -> bool { + if self.token.kind != TokenKind::Semi { + return false; + } - if !items.is_empty() { - let previous_item = &items[items.len() - 1]; - let previous_item_kind_name = match previous_item.kind { + // Check previous item to add it to the diagnostic, for example to say + // `enum declarations are not followed by a semicolon` + let err = match previous_item { + Some(previous_item) => { + let name = match previous_item.kind { // Say "braced struct" because tuple-structs and // braceless-empty-struct declarations do take a semicolon. - ItemKind::Struct(..) => Some("braced struct"), - ItemKind::Enum(..) => Some("enum"), - ItemKind::Trait(..) => Some("trait"), - ItemKind::Union(..) => Some("union"), - _ => None, + ItemKind::Struct(..) => "braced struct", + _ => previous_item.kind.descr(), }; - if let Some(name) = previous_item_kind_name { - err.opt_help = Some(()); - err.name = name; - } + IncorrectSemicolon { span: self.token.span, name, show_help: true } } - self.dcx().emit_err(err); - true - } else { - false - } + None => IncorrectSemicolon { span: self.token.span, name: "", show_help: false }, + }; + self.dcx().emit_err(err); + + self.bump(); + true } /// Creates a `Diag` for an unexpected token `t` and tries to recover if it is a diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 29957bd2f71ea..2a82a95dd071e 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -59,13 +59,13 @@ impl<'a> Parser<'a> { let post_attr_lo = self.token.span; let mut items = ThinVec::new(); while let Some(item) = self.parse_item(ForceCollect::No)? { + self.maybe_consume_incorrect_semicolon(Some(&item)); items.push(item); - self.maybe_consume_incorrect_semicolon(&items); } if !self.eat(term) { let token_str = super::token_descr(&self.token); - if !self.maybe_consume_incorrect_semicolon(&items) { + if !self.maybe_consume_incorrect_semicolon(items.last().map(|x| &**x)) { let msg = format!("expected item, found {token_str}"); let mut err = self.dcx().struct_span_err(self.token.span, msg); let span = self.token.span; diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index 0ad4c9c234647..19aa5ef949e60 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -686,9 +686,9 @@ pub(crate) fn make_test( } } - // The supplied slice is only used for diagnostics, + // The supplied item is only used for diagnostics, // which are swallowed here anyway. - parser.maybe_consume_incorrect_semicolon(&[]); + parser.maybe_consume_incorrect_semicolon(None); } // Reset errors so that they won't be reported as compiler bugs when dropping the diff --git a/tests/ui/suggestions/recover-from-semicolon-trailing-item.stderr b/tests/ui/suggestions/recover-from-semicolon-trailing-item.stderr index fee83eb5c1815..e068fdb5abac1 100644 --- a/tests/ui/suggestions/recover-from-semicolon-trailing-item.stderr +++ b/tests/ui/suggestions/recover-from-semicolon-trailing-item.stderr @@ -3,6 +3,8 @@ error: expected item, found `;` | LL | mod M {}; | ^ help: remove this semicolon + | + = help: module declarations are not followed by a semicolon error: expected item, found `;` --> $DIR/recover-from-semicolon-trailing-item.rs:4:12 @@ -17,6 +19,8 @@ error: expected item, found `;` | LL | fn foo(a: usize) {}; | ^ help: remove this semicolon + | + = help: function declarations are not followed by a semicolon error[E0308]: mismatched types --> $DIR/recover-from-semicolon-trailing-item.rs:10:20 From 1f6d271527cd2ae25b586277d02ab71c1332f57c Mon Sep 17 00:00:00 2001 From: ardi Date: Wed, 8 May 2024 14:22:09 +0200 Subject: [PATCH 177/179] Clarify that the diff_marker is talking about version control system conflicts specifically and a few more improvements. --- compiler/rustc_parse/src/lexer/tokentrees.rs | 2 +- .../rustc_parse/src/parser/diagnostics.rs | 33 +++++++++----- compiler/rustc_parse/src/parser/expr.rs | 2 +- compiler/rustc_parse/src/parser/item.rs | 44 +++++++++---------- compiler/rustc_parse/src/parser/stmt.rs | 4 +- 5 files changed, 47 insertions(+), 38 deletions(-) diff --git a/compiler/rustc_parse/src/lexer/tokentrees.rs b/compiler/rustc_parse/src/lexer/tokentrees.rs index b5a5a2a90ee16..eabe0226b2fb9 100644 --- a/compiler/rustc_parse/src/lexer/tokentrees.rs +++ b/compiler/rustc_parse/src/lexer/tokentrees.rs @@ -241,7 +241,7 @@ impl<'psess, 'src> TokenTreesReader<'psess, 'src> { // we have no way of tracking this in the lexer itself, so we piggyback on the parser let mut in_cond = false; while parser.token != token::Eof { - if let Err(diff_err) = parser.err_diff_marker() { + if let Err(diff_err) = parser.err_vcs_conflict_marker() { diff_errs.push(diff_err); } else if parser.is_keyword_ahead(0, &[kw::If, kw::While]) { in_cond = true; diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index 46809847fdbf4..ac12787f2ef05 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -2954,13 +2954,23 @@ impl<'a> Parser<'a> { err } - pub fn is_diff_marker(&mut self, long_kind: &TokenKind, short_kind: &TokenKind) -> bool { + /// This checks if this is a conflict marker, depending of the parameter passed. + /// + /// * `>>>>>` + /// * `=====` + /// * `<<<<<` + /// + pub fn is_vcs_conflict_marker( + &mut self, + long_kind: &TokenKind, + short_kind: &TokenKind, + ) -> bool { (0..3).all(|i| self.look_ahead(i, |tok| tok == long_kind)) && self.look_ahead(3, |tok| tok == short_kind) } - fn diff_marker(&mut self, long_kind: &TokenKind, short_kind: &TokenKind) -> Option { - if self.is_diff_marker(long_kind, short_kind) { + fn conflict_marker(&mut self, long_kind: &TokenKind, short_kind: &TokenKind) -> Option { + if self.is_vcs_conflict_marker(long_kind, short_kind) { let lo = self.token.span; for _ in 0..4 { self.bump(); @@ -2970,15 +2980,16 @@ impl<'a> Parser<'a> { None } - pub fn recover_diff_marker(&mut self) { - if let Err(err) = self.err_diff_marker() { + pub fn recover_vcs_conflict_marker(&mut self) { + if let Err(err) = self.err_vcs_conflict_marker() { err.emit(); FatalError.raise(); } } - pub fn err_diff_marker(&mut self) -> PResult<'a, ()> { - let Some(start) = self.diff_marker(&TokenKind::BinOp(token::Shl), &TokenKind::Lt) else { + pub fn err_vcs_conflict_marker(&mut self) -> PResult<'a, ()> { + let Some(start) = self.conflict_marker(&TokenKind::BinOp(token::Shl), &TokenKind::Lt) + else { return Ok(()); }; let mut spans = Vec::with_capacity(3); @@ -2990,13 +3001,15 @@ impl<'a> Parser<'a> { if self.token.kind == TokenKind::Eof { break; } - if let Some(span) = self.diff_marker(&TokenKind::OrOr, &TokenKind::BinOp(token::Or)) { + if let Some(span) = self.conflict_marker(&TokenKind::OrOr, &TokenKind::BinOp(token::Or)) + { middlediff3 = Some(span); } - if let Some(span) = self.diff_marker(&TokenKind::EqEq, &TokenKind::Eq) { + if let Some(span) = self.conflict_marker(&TokenKind::EqEq, &TokenKind::Eq) { middle = Some(span); } - if let Some(span) = self.diff_marker(&TokenKind::BinOp(token::Shr), &TokenKind::Gt) { + if let Some(span) = self.conflict_marker(&TokenKind::BinOp(token::Shr), &TokenKind::Gt) + { spans.push(span); end = Some(span); break; diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index cbc7ce9ef7cfb..d2d21624150bf 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -3734,7 +3734,7 @@ impl<'a> Parser<'a> { /// Parses `ident (COLON expr)?`. fn parse_expr_field(&mut self) -> PResult<'a, ExprField> { let attrs = self.parse_outer_attributes()?; - self.recover_diff_marker(); + self.recover_vcs_conflict_marker(); self.collect_tokens_trailing_token(attrs, ForceCollect::No, |this, attrs| { let lo = this.token.span; diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 2a82a95dd071e..05b0e0fe52d22 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -49,6 +49,7 @@ impl<'a> Parser<'a> { } /// Parses the contents of a module (inner attributes followed by module items). + /// We exit once we hit `term` pub fn parse_mod( &mut self, term: &TokenKind, @@ -101,9 +102,9 @@ impl<'a> Parser<'a> { fn_parse_mode: FnParseMode, force_collect: ForceCollect, ) -> PResult<'a, Option> { - self.recover_diff_marker(); + self.recover_vcs_conflict_marker(); let attrs = self.parse_outer_attributes()?; - self.recover_diff_marker(); + self.recover_vcs_conflict_marker(); self.parse_item_common(attrs, true, false, fn_parse_mode, force_collect) } @@ -723,7 +724,7 @@ impl<'a> Parser<'a> { if self.recover_doc_comment_before_brace() { continue; } - self.recover_diff_marker(); + self.recover_vcs_conflict_marker(); match parse_item(self) { Ok(None) => { let mut is_unnecessary_semicolon = !items.is_empty() @@ -1070,7 +1071,7 @@ impl<'a> Parser<'a> { /// ``` fn parse_use_tree_list(&mut self) -> PResult<'a, ThinVec<(UseTree, ast::NodeId)>> { self.parse_delim_comma_seq(Delimiter::Brace, |p| { - p.recover_diff_marker(); + p.recover_vcs_conflict_marker(); Ok((p.parse_use_tree()?, DUMMY_NODE_ID)) }) .map(|(r, _)| r) @@ -1497,9 +1498,9 @@ impl<'a> Parser<'a> { } fn parse_enum_variant(&mut self, span: Span) -> PResult<'a, Option> { - self.recover_diff_marker(); + self.recover_vcs_conflict_marker(); let variant_attrs = self.parse_outer_attributes()?; - self.recover_diff_marker(); + self.recover_vcs_conflict_marker(); let help = "enum variants can be `Variant`, `Variant = `, \ `Variant(Type, ..., TypeN)` or `Variant { fields: Types }`"; self.collect_tokens_trailing_token( @@ -1688,6 +1689,10 @@ impl<'a> Parser<'a> { Ok((class_name, ItemKind::Union(vdata, generics))) } + /// This function parses the fields of record structs: + /// + /// - `struct S { ... }` + /// - `enum E { Variant { ... } }` pub(crate) fn parse_record_struct_body( &mut self, adt_ty: &str, @@ -1714,19 +1719,10 @@ impl<'a> Parser<'a> { self.eat(&token::CloseDelim(Delimiter::Brace)); } else { let token_str = super::token_descr(&self.token); - let msg = format!( - "expected {}`{{` after struct name, found {}", - if parsed_where { "" } else { "`where`, or " }, - token_str - ); + let where_str = if parsed_where { "" } else { "`where`, or " }; + let msg = format!("expected {where_str}`{{` after struct name, found {token_str}"); let mut err = self.dcx().struct_span_err(self.token.span, msg); - err.span_label( - self.token.span, - format!( - "expected {}`{{` after struct name", - if parsed_where { "" } else { "`where`, or " } - ), - ); + err.span_label(self.token.span, format!("expected {where_str}`{{` after struct name",)); return Err(err); } @@ -1740,7 +1736,7 @@ impl<'a> Parser<'a> { let attrs = p.parse_outer_attributes()?; p.collect_tokens_trailing_token(attrs, ForceCollect::No, |p, attrs| { let mut snapshot = None; - if p.is_diff_marker(&TokenKind::BinOp(token::Shl), &TokenKind::Lt) { + if p.is_vcs_conflict_marker(&TokenKind::BinOp(token::Shl), &TokenKind::Lt) { // Account for `<<<<<<<` diff markers. We can't proactively error here because // that can be a valid type start, so we snapshot and reparse only we've // encountered another parse error. @@ -1751,7 +1747,7 @@ impl<'a> Parser<'a> { Ok(vis) => vis, Err(err) => { if let Some(ref mut snapshot) = snapshot { - snapshot.recover_diff_marker(); + snapshot.recover_vcs_conflict_marker(); } return Err(err); } @@ -1760,7 +1756,7 @@ impl<'a> Parser<'a> { Ok(ty) => ty, Err(err) => { if let Some(ref mut snapshot) = snapshot { - snapshot.recover_diff_marker(); + snapshot.recover_vcs_conflict_marker(); } return Err(err); } @@ -1785,9 +1781,9 @@ impl<'a> Parser<'a> { /// Parses an element of a struct declaration. fn parse_field_def(&mut self, adt_ty: &str) -> PResult<'a, FieldDef> { - self.recover_diff_marker(); + self.recover_vcs_conflict_marker(); let attrs = self.parse_outer_attributes()?; - self.recover_diff_marker(); + self.recover_vcs_conflict_marker(); self.collect_tokens_trailing_token(attrs, ForceCollect::No, |this, attrs| { let lo = this.token.span; let vis = this.parse_visibility(FollowedByType::No)?; @@ -2647,7 +2643,7 @@ impl<'a> Parser<'a> { } let (mut params, _) = self.parse_paren_comma_seq(|p| { - p.recover_diff_marker(); + p.recover_vcs_conflict_marker(); let snapshot = p.create_snapshot_for_diagnostic(); let param = p.parse_param_general(req_name, first_param).or_else(|e| { let guar = e.emit(); diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs index d70afebf1b2da..7424fbea9b053 100644 --- a/compiler/rustc_parse/src/parser/stmt.rs +++ b/compiler/rustc_parse/src/parser/stmt.rs @@ -567,7 +567,7 @@ impl<'a> Parser<'a> { if self.token == token::Eof { break; } - if self.is_diff_marker(&TokenKind::BinOp(token::Shl), &TokenKind::Lt) { + if self.is_vcs_conflict_marker(&TokenKind::BinOp(token::Shl), &TokenKind::Lt) { // Account for `<<<<<<<` diff markers. We can't proactively error here because // that can be a valid path start, so we snapshot and reparse only we've // encountered another parse error. @@ -576,7 +576,7 @@ impl<'a> Parser<'a> { let stmt = match self.parse_full_stmt(recover) { Err(mut err) if recover.yes() => { if let Some(ref mut snapshot) = snapshot { - snapshot.recover_diff_marker(); + snapshot.recover_vcs_conflict_marker(); } if self.token == token::Colon { // if a previous and next token of the current one is From db5a616405df5956a76bf08ec3ad97258a2ccee8 Mon Sep 17 00:00:00 2001 From: ardi Date: Tue, 14 May 2024 16:35:00 +0200 Subject: [PATCH 178/179] s/(Ident, ItemKind)/ItemInfo/ --- compiler/rustc_parse/src/parser/item.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 05b0e0fe52d22..8e085f963cd77 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -311,7 +311,7 @@ impl<'a> Parser<'a> { Ok(Some(info)) } - fn recover_import_as_use(&mut self) -> PResult<'a, Option<(Ident, ItemKind)>> { + fn recover_import_as_use(&mut self) -> PResult<'a, Option> { let span = self.token.span; let token_name = super::token_descr(&self.token); let snapshot = self.create_snapshot_for_diagnostic(); @@ -329,7 +329,7 @@ impl<'a> Parser<'a> { } } - fn parse_use_item(&mut self) -> PResult<'a, (Ident, ItemKind)> { + fn parse_use_item(&mut self) -> PResult<'a, ItemInfo> { let tree = self.parse_use_tree()?; if let Err(mut e) = self.expect_semi() { match tree.kind { From f8433a82b4a4120e34de236a68d0cfeaea6e60c3 Mon Sep 17 00:00:00 2001 From: ardi Date: Tue, 14 May 2024 16:38:01 +0200 Subject: [PATCH 179/179] use signature name for arg --- compiler/rustc_parse/src/parser/item.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 8e085f963cd77..34cdf8a9b5f8a 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -195,12 +195,12 @@ impl<'a> Parser<'a> { fn_parse_mode: FnParseMode, case: Case, ) -> PResult<'a, Option> { - let def_final = def == &Defaultness::Final; + let check_pub = def == &Defaultness::Final; let mut def_ = || mem::replace(def, Defaultness::Final); let info = if self.eat_keyword_case(kw::Use, case) { self.parse_use_item()? - } else if self.check_fn_front_matter(def_final, case) { + } else if self.check_fn_front_matter(check_pub, case) { // FUNCTION ITEM let (ident, sig, generics, body) = self.parse_fn(attrs, fn_parse_mode, lo, vis, case)?;