From 6cfdd53da152d814c27a37a4336f413f05c31d6e Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Thu, 10 Apr 2025 20:16:55 -0700 Subject: Stabilize `slice_as_chunks` library feature --- src/tools/miri/tests/pass/slices.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src/tools') diff --git a/src/tools/miri/tests/pass/slices.rs b/src/tools/miri/tests/pass/slices.rs index dd18a061cdd..686683c3a25 100644 --- a/src/tools/miri/tests/pass/slices.rs +++ b/src/tools/miri/tests/pass/slices.rs @@ -1,7 +1,6 @@ //@revisions: stack tree //@[tree]compile-flags: -Zmiri-tree-borrows //@compile-flags: -Zmiri-strict-provenance -#![feature(slice_as_chunks)] #![feature(slice_partition_dedup)] #![feature(layout_for_ptr)] @@ -227,7 +226,7 @@ fn test_for_invalidated_pointers() { buffer.reverse(); - // Calls `fn as_chunks_unchecked_mut` internally (requires unstable `#![feature(slice_as_chunks)]`): + // Calls `fn as_chunks_unchecked_mut` internally: assert_eq!(2, buffer.as_chunks_mut::<32>().0.len()); for chunk in buffer.as_chunks_mut::<32>().0 { for elem in chunk { -- cgit 1.4.1-3-g733a5 From 37a34c042d945dd8198647ecbdd8638d5775a051 Mon Sep 17 00:00:00 2001 From: Rune Tynan Date: Wed, 9 Apr 2025 18:00:23 -0700 Subject: Implement DeleteFileW --- src/tools/miri/src/shims/windows/foreign_items.rs | 5 +++++ src/tools/miri/src/shims/windows/fs.rs | 19 +++++++++++++++++ src/tools/miri/tests/pass-dep/shims/windows-fs.rs | 25 +++++++++++++++++++---- src/tools/miri/tests/pass/shims/fs.rs | 2 +- 4 files changed, 46 insertions(+), 5 deletions(-) (limited to 'src/tools') diff --git a/src/tools/miri/src/shims/windows/foreign_items.rs b/src/tools/miri/src/shims/windows/foreign_items.rs index 8dcadbed130..c80858c6363 100644 --- a/src/tools/miri/src/shims/windows/foreign_items.rs +++ b/src/tools/miri/src/shims/windows/foreign_items.rs @@ -317,6 +317,11 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let res = this.GetFileInformationByHandle(handle, info)?; this.write_scalar(res, dest)?; } + "DeleteFileW" => { + let [file_name] = this.check_shim(abi, sys_conv, link_name, args)?; + let res = this.DeleteFileW(file_name)?; + this.write_scalar(res, dest)?; + } // Allocation "HeapAlloc" => { diff --git a/src/tools/miri/src/shims/windows/fs.rs b/src/tools/miri/src/shims/windows/fs.rs index 32bab548969..7561bf45219 100644 --- a/src/tools/miri/src/shims/windows/fs.rs +++ b/src/tools/miri/src/shims/windows/fs.rs @@ -371,6 +371,25 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { interp_ok(this.eval_windows("c", "TRUE")) } + + fn DeleteFileW( + &mut self, + file_name: &OpTy<'tcx>, // LPCWSTR + ) -> InterpResult<'tcx, Scalar> { + // ^ Returns BOOL (i32 on Windows) + let this = self.eval_context_mut(); + this.assert_target_os("windows", "DeleteFileW"); + this.check_no_isolation("`DeleteFileW`")?; + + let file_name = this.read_path_from_wide_str(this.read_pointer(file_name)?)?; + match std::fs::remove_file(file_name) { + Ok(_) => interp_ok(this.eval_windows("c", "TRUE")), + Err(e) => { + this.set_last_error(e)?; + interp_ok(this.eval_windows("c", "FALSE")) + } + } + } } /// Windows FILETIME is measured in 100-nanosecs since 1601 diff --git a/src/tools/miri/tests/pass-dep/shims/windows-fs.rs b/src/tools/miri/tests/pass-dep/shims/windows-fs.rs index a015464dbde..698ca4e0b4b 100644 --- a/src/tools/miri/tests/pass-dep/shims/windows-fs.rs +++ b/src/tools/miri/tests/pass-dep/shims/windows-fs.rs @@ -2,6 +2,7 @@ //@compile-flags: -Zmiri-disable-isolation #![allow(nonstandard_style)] +use std::io::ErrorKind; use std::os::windows::ffi::OsStrExt; use std::path::Path; use std::ptr; @@ -15,10 +16,10 @@ use windows_sys::Win32::Foundation::{ STATUS_IO_DEVICE_ERROR, }; use windows_sys::Win32::Storage::FileSystem::{ - BY_HANDLE_FILE_INFORMATION, CREATE_ALWAYS, CREATE_NEW, CreateFileW, FILE_ATTRIBUTE_DIRECTORY, - FILE_ATTRIBUTE_NORMAL, FILE_FLAG_BACKUP_SEMANTICS, FILE_FLAG_OPEN_REPARSE_POINT, - FILE_SHARE_DELETE, FILE_SHARE_READ, FILE_SHARE_WRITE, GetFileInformationByHandle, OPEN_ALWAYS, - OPEN_EXISTING, + BY_HANDLE_FILE_INFORMATION, CREATE_ALWAYS, CREATE_NEW, CreateFileW, DeleteFileW, + FILE_ATTRIBUTE_DIRECTORY, FILE_ATTRIBUTE_NORMAL, FILE_FLAG_BACKUP_SEMANTICS, + FILE_FLAG_OPEN_REPARSE_POINT, FILE_SHARE_DELETE, FILE_SHARE_READ, FILE_SHARE_WRITE, + GetFileInformationByHandle, OPEN_ALWAYS, OPEN_EXISTING, }; fn main() { @@ -28,6 +29,7 @@ fn main() { test_create_always_twice(); test_open_always_twice(); test_open_dir_reparse(); + test_delete_file(); test_ntstatus_to_dos(); } } @@ -194,6 +196,21 @@ unsafe fn test_open_dir_reparse() { }; } +unsafe fn test_delete_file() { + let temp = utils::tmp().join("test_delete_file.txt"); + let raw_path = to_wide_cstr(&temp); + let _ = std::fs::File::create(&temp).unwrap(); + + if DeleteFileW(raw_path.as_ptr()) == 0 { + panic!("Failed to delete file"); + } + + match std::fs::File::open(temp) { + Ok(_) => panic!("File not deleted"), + Err(e) => assert!(e.kind() == ErrorKind::NotFound, "File not deleted"), + } +} + unsafe fn test_ntstatus_to_dos() { // We won't test all combinations, just a couple common ones assert_eq!(RtlNtStatusToDosError(STATUS_IO_DEVICE_ERROR), ERROR_IO_DEVICE); diff --git a/src/tools/miri/tests/pass/shims/fs.rs b/src/tools/miri/tests/pass/shims/fs.rs index 6ad23055f30..d0a7f245ee0 100644 --- a/src/tools/miri/tests/pass/shims/fs.rs +++ b/src/tools/miri/tests/pass/shims/fs.rs @@ -17,10 +17,10 @@ mod utils; fn main() { test_path_conversion(); + test_file_create_new(); // Windows file handling is very incomplete. if cfg!(not(windows)) { test_file(); - test_file_create_new(); test_seek(); test_file_clone(); test_metadata(); -- cgit 1.4.1-3-g733a5 From 9f1e27b61e4610d11ba74bba33a6fb9207a6e5e0 Mon Sep 17 00:00:00 2001 From: Patrick-6 Date: Fri, 11 Apr 2025 13:32:38 +0200 Subject: Expose Pointer to/from AllocId conversion functions, make some arguments optional --- src/tools/miri/src/alloc_addresses/mod.rs | 111 +++++++++++++++++------------- 1 file changed, 62 insertions(+), 49 deletions(-) (limited to 'src/tools') diff --git a/src/tools/miri/src/alloc_addresses/mod.rs b/src/tools/miri/src/alloc_addresses/mod.rs index c263e86c082..335e8d76999 100644 --- a/src/tools/miri/src/alloc_addresses/mod.rs +++ b/src/tools/miri/src/alloc_addresses/mod.rs @@ -107,47 +107,6 @@ fn align_addr(addr: u64, align: u64) -> u64 { impl<'tcx> EvalContextExtPriv<'tcx> for crate::MiriInterpCx<'tcx> {} trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { - // Returns the exposed `AllocId` that corresponds to the specified addr, - // or `None` if the addr is out of bounds - fn alloc_id_from_addr(&self, addr: u64, size: i64) -> Option { - let this = self.eval_context_ref(); - let global_state = this.machine.alloc_addresses.borrow(); - assert!(global_state.provenance_mode != ProvenanceMode::Strict); - - // We always search the allocation to the right of this address. So if the size is structly - // negative, we have to search for `addr-1` instead. - let addr = if size >= 0 { addr } else { addr.saturating_sub(1) }; - let pos = global_state.int_to_ptr_map.binary_search_by_key(&addr, |(addr, _)| *addr); - - // Determine the in-bounds provenance for this pointer. - let alloc_id = match pos { - Ok(pos) => Some(global_state.int_to_ptr_map[pos].1), - Err(0) => None, - Err(pos) => { - // This is the largest of the addresses smaller than `int`, - // i.e. the greatest lower bound (glb) - let (glb, alloc_id) = global_state.int_to_ptr_map[pos - 1]; - // This never overflows because `addr >= glb` - let offset = addr - glb; - // We require this to be strict in-bounds of the allocation. This arm is only - // entered for addresses that are not the base address, so even zero-sized - // allocations will get recognized at their base address -- but all other - // allocations will *not* be recognized at their "end" address. - let size = this.get_alloc_info(alloc_id).size; - if offset < size.bytes() { Some(alloc_id) } else { None } - } - }?; - - // We only use this provenance if it has been exposed. - if global_state.exposed.contains(&alloc_id) { - // This must still be live, since we remove allocations from `int_to_ptr_map` when they get freed. - debug_assert!(this.is_alloc_live(alloc_id)); - Some(alloc_id) - } else { - None - } - } - fn addr_from_alloc_id_uncached( &self, global_state: &mut GlobalStateInner, @@ -242,11 +201,65 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { interp_ok(base_addr) } } +} +impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {} +pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { + // Returns the `AllocId` that corresponds to the specified addr, + // or `None` if the addr is out of bounds. + // Setting `only_exposed_allocations` selects whether only exposed allocations are considered. + fn alloc_id_from_addr( + &self, + addr: u64, + size: i64, + only_exposed_allocations: bool, + ) -> Option { + let this = self.eval_context_ref(); + let global_state = this.machine.alloc_addresses.borrow(); + assert!(global_state.provenance_mode != ProvenanceMode::Strict); + + // We always search the allocation to the right of this address. So if the size is strictly + // negative, we have to search for `addr-1` instead. + let addr = if size >= 0 { addr } else { addr.saturating_sub(1) }; + let pos = global_state.int_to_ptr_map.binary_search_by_key(&addr, |(addr, _)| *addr); + + // Determine the in-bounds provenance for this pointer. + let alloc_id = match pos { + Ok(pos) => Some(global_state.int_to_ptr_map[pos].1), + Err(0) => None, + Err(pos) => { + // This is the largest of the addresses smaller than `int`, + // i.e. the greatest lower bound (glb) + let (glb, alloc_id) = global_state.int_to_ptr_map[pos - 1]; + // This never overflows because `addr >= glb` + let offset = addr - glb; + // We require this to be strict in-bounds of the allocation. This arm is only + // entered for addresses that are not the base address, so even zero-sized + // allocations will get recognized at their base address -- but all other + // allocations will *not* be recognized at their "end" address. + let size = this.get_alloc_info(alloc_id).size; + if offset < size.bytes() { Some(alloc_id) } else { None } + } + }?; + + // We only use this provenance if it has been exposed, or if the caller requested also non-exposed allocations + if !only_exposed_allocations || global_state.exposed.contains(&alloc_id) { + // This must still be live, since we remove allocations from `int_to_ptr_map` when they get freed. + debug_assert!(this.is_alloc_live(alloc_id)); + Some(alloc_id) + } else { + None + } + } + + /// Returns the base address of an allocation, or an error if no base address could be found + /// + /// # Panics + /// If `memory_kind = None` and the `alloc_id` is not cached, meaning that the first call to this function per `alloc_id` must get the `memory_kind`. fn addr_from_alloc_id( &self, alloc_id: AllocId, - memory_kind: MemoryKind, + memory_kind: Option, ) -> InterpResult<'tcx, u64> { let this = self.eval_context_ref(); let mut global_state = this.machine.alloc_addresses.borrow_mut(); @@ -256,8 +269,10 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { Some(&addr) => interp_ok(addr), None => { // First time we're looking for the absolute address of this allocation. + let memory_kind = + memory_kind.expect("memory_kind is required since alloc_id is not cached"); let base_addr = - self.addr_from_alloc_id_uncached(global_state, alloc_id, memory_kind)?; + this.addr_from_alloc_id_uncached(global_state, alloc_id, memory_kind)?; trace!("Assigning base address {:#x} to allocation {:?}", base_addr, alloc_id); // Store address in cache. @@ -283,10 +298,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { } } } -} -impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {} -pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn expose_provenance(&self, provenance: Provenance) -> InterpResult<'tcx> { let this = self.eval_context_ref(); let mut global_state = this.machine.alloc_addresses.borrow_mut(); @@ -365,7 +377,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let alloc_id = prov.alloc_id(); // Get a pointer to the beginning of this allocation. - let base_addr = this.addr_from_alloc_id(alloc_id, kind)?; + let base_addr = this.addr_from_alloc_id(alloc_id, Some(kind))?; let base_ptr = interpret::Pointer::new( Provenance::Concrete { alloc_id, tag }, Size::from_bytes(base_addr), @@ -388,7 +400,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // In native lib mode, MiriAllocBytes for global allocations are handled via `prepared_alloc_bytes`. // This additional call ensures that some `MiriAllocBytes` are always prepared, just in case // this function gets called before the first time `addr_from_alloc_id` gets called. - this.addr_from_alloc_id(id, MiriMemoryKind::Global.into())?; + this.addr_from_alloc_id(id, Some(MiriMemoryKind::Global.into()))?; // The memory we need here will have already been allocated during an earlier call to // `addr_from_alloc_id` for this allocation. So don't create a new `MiriAllocBytes` here, instead // fetch the previously prepared bytes from `prepared_alloc_bytes`. @@ -423,7 +435,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { alloc_id } else { // A wildcard pointer. - this.alloc_id_from_addr(addr.bytes(), size)? + let only_exposed_allocations = true; + this.alloc_id_from_addr(addr.bytes(), size, only_exposed_allocations)? }; // This cannot fail: since we already have a pointer with that provenance, adjust_alloc_root_pointer -- cgit 1.4.1-3-g733a5 From 6db8e867d26814911994457874be066ed9c7639a Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 16 Apr 2025 14:34:09 +0200 Subject: use std-declared intrinsics rather than copying the declaration --- src/tools/miri/tests/fail/intrinsics/ctlz_nonzero.rs | 9 ++------- src/tools/miri/tests/fail/intrinsics/cttz_nonzero.rs | 9 ++------- src/tools/miri/tests/fail/intrinsics/float_to_int_32_inf1.rs | 6 ++---- src/tools/miri/tests/fail/intrinsics/float_to_int_32_infneg1.rs | 6 ++---- src/tools/miri/tests/fail/intrinsics/float_to_int_32_nan.rs | 6 ++---- src/tools/miri/tests/fail/intrinsics/float_to_int_32_nanneg.rs | 6 ++---- src/tools/miri/tests/fail/intrinsics/float_to_int_32_neg.rs | 6 ++---- src/tools/miri/tests/fail/intrinsics/float_to_int_32_too_big1.rs | 6 ++---- src/tools/miri/tests/fail/intrinsics/float_to_int_32_too_big2.rs | 6 ++---- .../miri/tests/fail/intrinsics/float_to_int_32_too_small1.rs | 6 ++---- src/tools/miri/tests/fail/intrinsics/float_to_int_64_inf1.rs | 6 ++---- src/tools/miri/tests/fail/intrinsics/float_to_int_64_infneg1.rs | 6 ++---- src/tools/miri/tests/fail/intrinsics/float_to_int_64_infneg2.rs | 6 ++---- src/tools/miri/tests/fail/intrinsics/float_to_int_64_nan.rs | 6 ++---- src/tools/miri/tests/fail/intrinsics/float_to_int_64_neg.rs | 6 ++---- src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big1.rs | 6 ++---- src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big2.rs | 6 ++---- src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big3.rs | 6 ++---- src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big4.rs | 6 ++---- src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big5.rs | 6 ++---- src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big6.rs | 6 ++---- src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big7.rs | 6 ++---- .../miri/tests/fail/intrinsics/float_to_int_64_too_small1.rs | 6 ++---- .../miri/tests/fail/intrinsics/float_to_int_64_too_small2.rs | 6 ++---- .../miri/tests/fail/intrinsics/float_to_int_64_too_small3.rs | 6 ++---- 25 files changed, 50 insertions(+), 106 deletions(-) (limited to 'src/tools') diff --git a/src/tools/miri/tests/fail/intrinsics/ctlz_nonzero.rs b/src/tools/miri/tests/fail/intrinsics/ctlz_nonzero.rs index f73c1b6acb7..3da54b91882 100644 --- a/src/tools/miri/tests/fail/intrinsics/ctlz_nonzero.rs +++ b/src/tools/miri/tests/fail/intrinsics/ctlz_nonzero.rs @@ -1,13 +1,8 @@ -#![feature(intrinsics)] - -mod rusti { - #[rustc_intrinsic] - pub unsafe fn ctlz_nonzero(x: T) -> u32; -} +#![feature(core_intrinsics)] pub fn main() { unsafe { - use crate::rusti::*; + use std::intrinsics::*; ctlz_nonzero(0u8); //~ ERROR: `ctlz_nonzero` called on 0 } diff --git a/src/tools/miri/tests/fail/intrinsics/cttz_nonzero.rs b/src/tools/miri/tests/fail/intrinsics/cttz_nonzero.rs index a41cb8b1553..2b68f6713d8 100644 --- a/src/tools/miri/tests/fail/intrinsics/cttz_nonzero.rs +++ b/src/tools/miri/tests/fail/intrinsics/cttz_nonzero.rs @@ -1,13 +1,8 @@ -#![feature(intrinsics)] - -mod rusti { - #[rustc_intrinsic] - pub unsafe fn cttz_nonzero(x: T) -> u32; -} +#![feature(core_intrinsics)] pub fn main() { unsafe { - use crate::rusti::*; + use std::intrinsics::*; cttz_nonzero(0u8); //~ ERROR: `cttz_nonzero` called on 0 } diff --git a/src/tools/miri/tests/fail/intrinsics/float_to_int_32_inf1.rs b/src/tools/miri/tests/fail/intrinsics/float_to_int_32_inf1.rs index 7ee0117ffb3..831a65966ce 100644 --- a/src/tools/miri/tests/fail/intrinsics/float_to_int_32_inf1.rs +++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_32_inf1.rs @@ -1,8 +1,6 @@ -#![feature(intrinsics)] - +#![feature(core_intrinsics)] // Directly call intrinsic to avoid debug assertions in libstd -#[rustc_intrinsic] -unsafe fn float_to_int_unchecked(value: Float) -> Int; +use std::intrinsics::float_to_int_unchecked; fn main() { unsafe { diff --git a/src/tools/miri/tests/fail/intrinsics/float_to_int_32_infneg1.rs b/src/tools/miri/tests/fail/intrinsics/float_to_int_32_infneg1.rs index 22bf881cef0..a7032e97430 100644 --- a/src/tools/miri/tests/fail/intrinsics/float_to_int_32_infneg1.rs +++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_32_infneg1.rs @@ -1,8 +1,6 @@ -#![feature(intrinsics)] - +#![feature(core_intrinsics)] // Directly call intrinsic to avoid debug assertions in libstd -#[rustc_intrinsic] -unsafe fn float_to_int_unchecked(value: Float) -> Int; +use std::intrinsics::float_to_int_unchecked; fn main() { unsafe { diff --git a/src/tools/miri/tests/fail/intrinsics/float_to_int_32_nan.rs b/src/tools/miri/tests/fail/intrinsics/float_to_int_32_nan.rs index 571121f4019..e8c98761956 100644 --- a/src/tools/miri/tests/fail/intrinsics/float_to_int_32_nan.rs +++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_32_nan.rs @@ -1,8 +1,6 @@ -#![feature(intrinsics)] - +#![feature(core_intrinsics)] // Directly call intrinsic to avoid debug assertions in libstd -#[rustc_intrinsic] -unsafe fn float_to_int_unchecked(value: Float) -> Int; +use std::intrinsics::float_to_int_unchecked; fn main() { unsafe { diff --git a/src/tools/miri/tests/fail/intrinsics/float_to_int_32_nanneg.rs b/src/tools/miri/tests/fail/intrinsics/float_to_int_32_nanneg.rs index 12600ef6125..c8b29cbcfe9 100644 --- a/src/tools/miri/tests/fail/intrinsics/float_to_int_32_nanneg.rs +++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_32_nanneg.rs @@ -1,8 +1,6 @@ -#![feature(intrinsics)] - +#![feature(core_intrinsics)] // Directly call intrinsic to avoid debug assertions in libstd -#[rustc_intrinsic] -unsafe fn float_to_int_unchecked(value: Float) -> Int; +use std::intrinsics::float_to_int_unchecked; fn main() { unsafe { diff --git a/src/tools/miri/tests/fail/intrinsics/float_to_int_32_neg.rs b/src/tools/miri/tests/fail/intrinsics/float_to_int_32_neg.rs index f848a137c27..0996d0244e8 100644 --- a/src/tools/miri/tests/fail/intrinsics/float_to_int_32_neg.rs +++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_32_neg.rs @@ -1,8 +1,6 @@ -#![feature(intrinsics)] - +#![feature(core_intrinsics)] // Directly call intrinsic to avoid debug assertions in libstd -#[rustc_intrinsic] -unsafe fn float_to_int_unchecked(value: Float) -> Int; +use std::intrinsics::float_to_int_unchecked; fn main() { unsafe { diff --git a/src/tools/miri/tests/fail/intrinsics/float_to_int_32_too_big1.rs b/src/tools/miri/tests/fail/intrinsics/float_to_int_32_too_big1.rs index 43ef4a95738..f28227134d8 100644 --- a/src/tools/miri/tests/fail/intrinsics/float_to_int_32_too_big1.rs +++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_32_too_big1.rs @@ -1,8 +1,6 @@ -#![feature(intrinsics)] - +#![feature(core_intrinsics)] // Directly call intrinsic to avoid debug assertions in libstd -#[rustc_intrinsic] -unsafe fn float_to_int_unchecked(value: Float) -> Int; +use std::intrinsics::float_to_int_unchecked; fn main() { unsafe { diff --git a/src/tools/miri/tests/fail/intrinsics/float_to_int_32_too_big2.rs b/src/tools/miri/tests/fail/intrinsics/float_to_int_32_too_big2.rs index 83432c2b77c..9e400b4ad40 100644 --- a/src/tools/miri/tests/fail/intrinsics/float_to_int_32_too_big2.rs +++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_32_too_big2.rs @@ -1,8 +1,6 @@ -#![feature(intrinsics)] - +#![feature(core_intrinsics)] // Directly call intrinsic to avoid debug assertions in libstd -#[rustc_intrinsic] -unsafe fn float_to_int_unchecked(value: Float) -> Int; +use std::intrinsics::float_to_int_unchecked; fn main() { unsafe { diff --git a/src/tools/miri/tests/fail/intrinsics/float_to_int_32_too_small1.rs b/src/tools/miri/tests/fail/intrinsics/float_to_int_32_too_small1.rs index 609443e6d4e..9aca349b918 100644 --- a/src/tools/miri/tests/fail/intrinsics/float_to_int_32_too_small1.rs +++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_32_too_small1.rs @@ -1,8 +1,6 @@ -#![feature(intrinsics)] - +#![feature(core_intrinsics)] // Directly call intrinsic to avoid debug assertions in libstd -#[rustc_intrinsic] -unsafe fn float_to_int_unchecked(value: Float) -> Int; +use std::intrinsics::float_to_int_unchecked; fn main() { unsafe { diff --git a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_inf1.rs b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_inf1.rs index fb3eb11c0bb..54361f6c32c 100644 --- a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_inf1.rs +++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_inf1.rs @@ -1,8 +1,6 @@ -#![feature(intrinsics)] - +#![feature(core_intrinsics)] // Directly call intrinsic to avoid debug assertions in libstd -#[rustc_intrinsic] -unsafe fn float_to_int_unchecked(value: Float) -> Int; +use std::intrinsics::float_to_int_unchecked; fn main() { unsafe { diff --git a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_infneg1.rs b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_infneg1.rs index b46c4777ba7..75f52296367 100644 --- a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_infneg1.rs +++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_infneg1.rs @@ -1,8 +1,6 @@ -#![feature(intrinsics)] - +#![feature(core_intrinsics)] // Directly call intrinsic to avoid debug assertions in libstd -#[rustc_intrinsic] -unsafe fn float_to_int_unchecked(value: Float) -> Int; +use std::intrinsics::float_to_int_unchecked; fn main() { unsafe { diff --git a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_infneg2.rs b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_infneg2.rs index 8a3b9dbdc71..20d8fa1ae80 100644 --- a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_infneg2.rs +++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_infneg2.rs @@ -1,8 +1,6 @@ -#![feature(intrinsics)] - +#![feature(core_intrinsics)] // Directly call intrinsic to avoid debug assertions in libstd -#[rustc_intrinsic] -unsafe fn float_to_int_unchecked(value: Float) -> Int; +use std::intrinsics::float_to_int_unchecked; fn main() { unsafe { diff --git a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_nan.rs b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_nan.rs index e0c826cb046..611a0ade0a5 100644 --- a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_nan.rs +++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_nan.rs @@ -1,8 +1,6 @@ -#![feature(intrinsics)] - +#![feature(core_intrinsics)] // Directly call intrinsic to avoid debug assertions in libstd -#[rustc_intrinsic] -unsafe fn float_to_int_unchecked(value: Float) -> Int; +use std::intrinsics::float_to_int_unchecked; fn main() { unsafe { diff --git a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_neg.rs b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_neg.rs index c7c5bf40226..8ff8c3bee00 100644 --- a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_neg.rs +++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_neg.rs @@ -1,8 +1,6 @@ -#![feature(intrinsics)] - +#![feature(core_intrinsics)] // Directly call intrinsic to avoid debug assertions in libstd -#[rustc_intrinsic] -unsafe fn float_to_int_unchecked(value: Float) -> Int; +use std::intrinsics::float_to_int_unchecked; fn main() { unsafe { diff --git a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big1.rs b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big1.rs index fb3d7bda4e4..1f662e6c32a 100644 --- a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big1.rs +++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big1.rs @@ -1,8 +1,6 @@ -#![feature(intrinsics)] - +#![feature(core_intrinsics)] // Directly call intrinsic to avoid debug assertions in libstd -#[rustc_intrinsic] -unsafe fn float_to_int_unchecked(value: Float) -> Int; +use std::intrinsics::float_to_int_unchecked; fn main() { unsafe { diff --git a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big2.rs b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big2.rs index 2cf27b33553..fad172801ea 100644 --- a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big2.rs +++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big2.rs @@ -1,8 +1,6 @@ -#![feature(intrinsics)] - +#![feature(core_intrinsics)] // Directly call intrinsic to avoid debug assertions in libstd -#[rustc_intrinsic] -unsafe fn float_to_int_unchecked(value: Float) -> Int; +use std::intrinsics::float_to_int_unchecked; fn main() { unsafe { diff --git a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big3.rs b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big3.rs index 22dca505e64..7eb3559527a 100644 --- a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big3.rs +++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big3.rs @@ -1,8 +1,6 @@ -#![feature(intrinsics)] - +#![feature(core_intrinsics)] // Directly call intrinsic to avoid debug assertions in libstd -#[rustc_intrinsic] -unsafe fn float_to_int_unchecked(value: Float) -> Int; +use std::intrinsics::float_to_int_unchecked; fn main() { unsafe { diff --git a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big4.rs b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big4.rs index b59c8fa8e0c..351fc6c6f1c 100644 --- a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big4.rs +++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big4.rs @@ -1,8 +1,6 @@ -#![feature(intrinsics)] - +#![feature(core_intrinsics)] // Directly call intrinsic to avoid debug assertions in libstd -#[rustc_intrinsic] -unsafe fn float_to_int_unchecked(value: Float) -> Int; +use std::intrinsics::float_to_int_unchecked; fn main() { unsafe { diff --git a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big5.rs b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big5.rs index 4ad0cd343a4..a6f73c79710 100644 --- a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big5.rs +++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big5.rs @@ -1,8 +1,6 @@ -#![feature(intrinsics)] - +#![feature(core_intrinsics)] // Directly call intrinsic to avoid debug assertions in libstd -#[rustc_intrinsic] -unsafe fn float_to_int_unchecked(value: Float) -> Int; +use std::intrinsics::float_to_int_unchecked; fn main() { unsafe { diff --git a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big6.rs b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big6.rs index fd47dfc03d7..b01ff3aafc0 100644 --- a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big6.rs +++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big6.rs @@ -1,8 +1,6 @@ -#![feature(intrinsics)] - +#![feature(core_intrinsics)] // Directly call intrinsic to avoid debug assertions in libstd -#[rustc_intrinsic] -unsafe fn float_to_int_unchecked(value: Float) -> Int; +use std::intrinsics::float_to_int_unchecked; fn main() { unsafe { diff --git a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big7.rs b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big7.rs index 680ebda1c96..a573e4e852c 100644 --- a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big7.rs +++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big7.rs @@ -1,8 +1,6 @@ -#![feature(intrinsics)] - +#![feature(core_intrinsics)] // Directly call intrinsic to avoid debug assertions in libstd -#[rustc_intrinsic] -unsafe fn float_to_int_unchecked(value: Float) -> Int; +use std::intrinsics::float_to_int_unchecked; fn main() { unsafe { diff --git a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_small1.rs b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_small1.rs index e4cb36c5d2e..4fb38c9bc2e 100644 --- a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_small1.rs +++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_small1.rs @@ -1,8 +1,6 @@ -#![feature(intrinsics)] - +#![feature(core_intrinsics)] // Directly call intrinsic to avoid debug assertions in libstd -#[rustc_intrinsic] -unsafe fn float_to_int_unchecked(value: Float) -> Int; +use std::intrinsics::float_to_int_unchecked; fn main() { unsafe { diff --git a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_small2.rs b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_small2.rs index fe4bac92bd3..c4c0d3c17f0 100644 --- a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_small2.rs +++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_small2.rs @@ -1,8 +1,6 @@ -#![feature(intrinsics)] - +#![feature(core_intrinsics)] // Directly call intrinsic to avoid debug assertions in libstd -#[rustc_intrinsic] -unsafe fn float_to_int_unchecked(value: Float) -> Int; +use std::intrinsics::float_to_int_unchecked; fn main() { unsafe { diff --git a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_small3.rs b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_small3.rs index 219efd80316..de7d2215fd6 100644 --- a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_small3.rs +++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_small3.rs @@ -1,8 +1,6 @@ -#![feature(intrinsics)] - +#![feature(core_intrinsics)] // Directly call intrinsic to avoid debug assertions in libstd -#[rustc_intrinsic] -unsafe fn float_to_int_unchecked(value: Float) -> Int; +use std::intrinsics::float_to_int_unchecked; fn main() { unsafe { -- cgit 1.4.1-3-g733a5 From f3ae022ed667bff30e0a64cdf7ca843bf1756f69 Mon Sep 17 00:00:00 2001 From: geetanshjuneja Date: Thu, 10 Apr 2025 13:32:04 +0530 Subject: replaced check_shim with check_shim_abi for env, file, sockets and time related shims Making type consistent in shims pread return type fix make clock_gettime shim type consistent --- src/tools/miri/src/helpers.rs | 2 +- src/tools/miri/src/shims/time.rs | 29 +- src/tools/miri/src/shims/unix/foreign_items.rs | 433 ++++++++++++++++++--- src/tools/miri/src/shims/unix/fs.rs | 17 +- .../fail/shims/vararg_caller_signature_mismatch.rs | 2 +- .../shims/vararg_caller_signature_mismatch.stderr | 4 +- 6 files changed, 405 insertions(+), 82 deletions(-) (limited to 'src/tools') diff --git a/src/tools/miri/src/helpers.rs b/src/tools/miri/src/helpers.rs index b4098ca0750..0932f2a3910 100644 --- a/src/tools/miri/src/helpers.rs +++ b/src/tools/miri/src/helpers.rs @@ -1017,7 +1017,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } /// Check that the given `caller_fn_abi` matches the expected ABI described by - /// `callee_abi`, `callee_input_tys`, `callee_output_ty`, and the return the list of + /// `callee_abi`, `callee_input_tys`, `callee_output_ty`, and then returns the list of /// arguments. fn check_shim_abi<'a, const N: usize>( &mut self, diff --git a/src/tools/miri/src/shims/time.rs b/src/tools/miri/src/shims/time.rs index fb80a36af9f..c98d6e2b408 100644 --- a/src/tools/miri/src/shims/time.rs +++ b/src/tools/miri/src/shims/time.rs @@ -21,7 +21,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { &mut self, clk_id_op: &OpTy<'tcx>, tp_op: &OpTy<'tcx>, - ) -> InterpResult<'tcx, Scalar> { + dest: &MPlaceTy<'tcx>, + ) -> InterpResult<'tcx> { // This clock support is deliberately minimal because a lot of clock types have fiddly // properties (is it possible for Miri to be suspended independently of the host?). If you // have a use for another clock type, please open an issue. @@ -29,8 +30,9 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let this = self.eval_context_mut(); this.assert_target_os_is_unix("clock_gettime"); + let clockid_t_size = this.libc_ty_layout("clockid_t").size; - let clk_id = this.read_scalar(clk_id_op)?.to_i32()?; + let clk_id = this.read_scalar(clk_id_op)?.to_int(clockid_t_size)?; let tp = this.deref_pointer_as(tp_op, this.libc_ty_layout("timespec"))?; let absolute_clocks; @@ -43,34 +45,34 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Linux further distinguishes regular and "coarse" clocks, but the "coarse" version // is just specified to be "faster and less precise", so we implement both the same way. absolute_clocks = vec![ - this.eval_libc_i32("CLOCK_REALTIME"), - this.eval_libc_i32("CLOCK_REALTIME_COARSE"), + this.eval_libc("CLOCK_REALTIME").to_int(clockid_t_size)?, + this.eval_libc("CLOCK_REALTIME_COARSE").to_int(clockid_t_size)?, ]; // The second kind is MONOTONIC clocks for which 0 is an arbitrary time point, but they are // never allowed to go backwards. We don't need to do any additional monotonicity // enforcement because std::time::Instant already guarantees that it is monotonic. relative_clocks = vec![ - this.eval_libc_i32("CLOCK_MONOTONIC"), - this.eval_libc_i32("CLOCK_MONOTONIC_COARSE"), + this.eval_libc("CLOCK_MONOTONIC").to_int(clockid_t_size)?, + this.eval_libc("CLOCK_MONOTONIC_COARSE").to_int(clockid_t_size)?, ]; } "macos" => { - absolute_clocks = vec![this.eval_libc_i32("CLOCK_REALTIME")]; - relative_clocks = vec![this.eval_libc_i32("CLOCK_MONOTONIC")]; + absolute_clocks = vec![this.eval_libc("CLOCK_REALTIME").to_int(clockid_t_size)?]; + relative_clocks = vec![this.eval_libc("CLOCK_MONOTONIC").to_int(clockid_t_size)?]; // `CLOCK_UPTIME_RAW` supposed to not increment while the system is asleep... but // that's not really something a program running inside Miri can tell, anyway. // We need to support it because std uses it. - relative_clocks.push(this.eval_libc_i32("CLOCK_UPTIME_RAW")); + relative_clocks.push(this.eval_libc("CLOCK_UPTIME_RAW").to_int(clockid_t_size)?); } "solaris" | "illumos" => { // The REALTIME clock returns the actual time since the Unix epoch. - absolute_clocks = vec![this.eval_libc_i32("CLOCK_REALTIME")]; + absolute_clocks = vec![this.eval_libc("CLOCK_REALTIME").to_int(clockid_t_size)?]; // MONOTONIC, in the other hand, is the high resolution, non-adjustable // clock from an arbitrary time in the past. // Note that the man page mentions HIGHRES but it is just // an alias of MONOTONIC and the libc crate does not expose it anyway. // https://docs.oracle.com/cd/E23824_01/html/821-1465/clock-gettime-3c.html - relative_clocks = vec![this.eval_libc_i32("CLOCK_MONOTONIC")]; + relative_clocks = vec![this.eval_libc("CLOCK_MONOTONIC").to_int(clockid_t_size)?]; } target => throw_unsup_format!("`clock_gettime` is not supported on target OS {target}"), } @@ -81,15 +83,16 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } else if relative_clocks.contains(&clk_id) { this.machine.monotonic_clock.now().duration_since(this.machine.monotonic_clock.epoch()) } else { - return this.set_last_error_and_return_i32(LibcError("EINVAL")); + return this.set_last_error_and_return(LibcError("EINVAL"), dest); }; let tv_sec = duration.as_secs(); let tv_nsec = duration.subsec_nanos(); this.write_int_fields(&[tv_sec.into(), tv_nsec.into()], &tp)?; + this.write_int(0, dest)?; - interp_ok(Scalar::from_i32(0)) + interp_ok(()) } fn gettimeofday( diff --git a/src/tools/miri/src/shims/unix/foreign_items.rs b/src/tools/miri/src/shims/unix/foreign_items.rs index 5e6259c3574..026aa1f9503 100644 --- a/src/tools/miri/src/shims/unix/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/foreign_items.rs @@ -112,51 +112,122 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { match link_name.as_str() { // Environment related shims "getenv" => { - let [name] = this.check_shim(abi, Conv::C, link_name, args)?; + let [name] = this.check_shim_abi( + link_name, + abi, + ExternAbi::C { unwind: false }, + [this.machine.layouts.const_raw_ptr.ty], + this.machine.layouts.mut_raw_ptr.ty, + args, + )?; let result = this.getenv(name)?; this.write_pointer(result, dest)?; } "unsetenv" => { - let [name] = this.check_shim(abi, Conv::C, link_name, args)?; + let [name] = this.check_shim_abi( + link_name, + abi, + ExternAbi::C { unwind: false }, + [this.machine.layouts.const_raw_ptr.ty], + this.tcx.types.i32, + args, + )?; let result = this.unsetenv(name)?; this.write_scalar(result, dest)?; } "setenv" => { - let [name, value, overwrite] = this.check_shim(abi, Conv::C, link_name, args)?; + let [name, value, overwrite] = this.check_shim_abi( + link_name, + abi, + ExternAbi::C { unwind: false }, + [ + this.machine.layouts.const_raw_ptr.ty, + this.machine.layouts.const_raw_ptr.ty, + this.tcx.types.i32, + ], + this.tcx.types.i32, + args, + )?; this.read_scalar(overwrite)?.to_i32()?; let result = this.setenv(name, value)?; this.write_scalar(result, dest)?; } "getcwd" => { - let [buf, size] = this.check_shim(abi, Conv::C, link_name, args)?; + let [buf, size] = this.check_shim_abi( + link_name, + abi, + ExternAbi::C { unwind: false }, + [this.machine.layouts.mut_raw_ptr.ty, this.tcx.types.usize], + this.machine.layouts.mut_raw_ptr.ty, + args, + )?; let result = this.getcwd(buf, size)?; this.write_pointer(result, dest)?; } "chdir" => { - let [path] = this.check_shim(abi, Conv::C, link_name, args)?; + let [path] = this.check_shim_abi( + link_name, + abi, + ExternAbi::C { unwind: false }, + [this.machine.layouts.const_raw_ptr.ty], + this.tcx.types.i32, + args, + )?; let result = this.chdir(path)?; this.write_scalar(result, dest)?; } "getpid" => { - let [] = this.check_shim(abi, Conv::C, link_name, args)?; + let [] = this.check_shim_abi( + link_name, + abi, + ExternAbi::C { unwind: false }, + [], + this.libc_ty_layout("pid_t").ty, + args, + )?; let result = this.getpid()?; this.write_scalar(result, dest)?; } "sysconf" => { - let [val] = this.check_shim(abi, Conv::C, link_name, args)?; + let [val] = this.check_shim_abi( + link_name, + abi, + ExternAbi::C { unwind: false }, + [this.tcx.types.i32], + this.tcx.types.isize, + args, + )?; let result = this.sysconf(val)?; this.write_scalar(result, dest)?; } // File descriptors "read" => { - let [fd, buf, count] = this.check_shim(abi, Conv::C, link_name, args)?; + let [fd, buf, count] = this.check_shim_abi( + link_name, + abi, + ExternAbi::C { unwind: false }, + [this.tcx.types.i32, this.machine.layouts.mut_raw_ptr.ty, this.tcx.types.usize], + this.tcx.types.isize, + args, + )?; let fd = this.read_scalar(fd)?.to_i32()?; let buf = this.read_pointer(buf)?; let count = this.read_target_usize(count)?; this.read(fd, buf, count, None, dest)?; } "write" => { - let [fd, buf, n] = this.check_shim(abi, Conv::C, link_name, args)?; + let [fd, buf, n] = this.check_shim_abi( + link_name, + abi, + ExternAbi::C { unwind: false }, + [ + this.tcx.types.i32, + this.machine.layouts.const_raw_ptr.ty, + this.tcx.types.usize, + ], + this.tcx.types.isize, + args, + )?; let fd = this.read_scalar(fd)?.to_i32()?; let buf = this.read_pointer(buf)?; let count = this.read_target_usize(n)?; @@ -164,38 +235,88 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write(fd, buf, count, None, dest)?; } "pread" => { - let [fd, buf, count, offset] = this.check_shim(abi, Conv::C, link_name, args)?; + let off_t = this.libc_ty_layout("off_t"); + let [fd, buf, count, offset] = this.check_shim_abi( + link_name, + abi, + ExternAbi::C { unwind: false }, + [ + this.tcx.types.i32, + this.machine.layouts.mut_raw_ptr.ty, + this.tcx.types.usize, + off_t.ty, + ], + this.tcx.types.isize, + args, + )?; let fd = this.read_scalar(fd)?.to_i32()?; let buf = this.read_pointer(buf)?; let count = this.read_target_usize(count)?; - let offset = this.read_scalar(offset)?.to_int(this.libc_ty_layout("off_t").size)?; + let offset = this.read_scalar(offset)?.to_int(off_t.size)?; this.read(fd, buf, count, Some(offset), dest)?; } "pwrite" => { - let [fd, buf, n, offset] = this.check_shim(abi, Conv::C, link_name, args)?; + let off_t = this.libc_ty_layout("off_t"); + let [fd, buf, n, offset] = this.check_shim_abi( + link_name, + abi, + ExternAbi::C { unwind: false }, + [ + this.tcx.types.i32, + this.machine.layouts.const_raw_ptr.ty, + this.tcx.types.usize, + off_t.ty, + ], + this.tcx.types.isize, + args, + )?; let fd = this.read_scalar(fd)?.to_i32()?; let buf = this.read_pointer(buf)?; let count = this.read_target_usize(n)?; - let offset = this.read_scalar(offset)?.to_int(this.libc_ty_layout("off_t").size)?; + let offset = this.read_scalar(offset)?.to_int(off_t.size)?; trace!("Called pwrite({:?}, {:?}, {:?}, {:?})", fd, buf, count, offset); this.write(fd, buf, count, Some(offset), dest)?; } "pread64" => { - let [fd, buf, count, offset] = this.check_shim(abi, Conv::C, link_name, args)?; + let off64_t = this.libc_ty_layout("off64_t"); + let [fd, buf, count, offset] = this.check_shim_abi( + link_name, + abi, + ExternAbi::C { unwind: false }, + [ + this.tcx.types.i32, + this.machine.layouts.mut_raw_ptr.ty, + this.tcx.types.usize, + off64_t.ty, + ], + this.tcx.types.isize, + args, + )?; let fd = this.read_scalar(fd)?.to_i32()?; let buf = this.read_pointer(buf)?; let count = this.read_target_usize(count)?; - let offset = - this.read_scalar(offset)?.to_int(this.libc_ty_layout("off64_t").size)?; + let offset = this.read_scalar(offset)?.to_int(off64_t.size)?; this.read(fd, buf, count, Some(offset), dest)?; } "pwrite64" => { - let [fd, buf, n, offset] = this.check_shim(abi, Conv::C, link_name, args)?; + let off64_t = this.libc_ty_layout("off64_t"); + let [fd, buf, n, offset] = this.check_shim_abi( + link_name, + abi, + ExternAbi::C { unwind: false }, + [ + this.tcx.types.i32, + this.machine.layouts.const_raw_ptr.ty, + this.tcx.types.usize, + off64_t.ty, + ], + this.tcx.types.isize, + args, + )?; let fd = this.read_scalar(fd)?.to_i32()?; let buf = this.read_pointer(buf)?; let count = this.read_target_usize(n)?; - let offset = - this.read_scalar(offset)?.to_int(this.libc_ty_layout("off64_t").size)?; + let offset = this.read_scalar(offset)?.to_int(off64_t.size)?; trace!("Called pwrite64({:?}, {:?}, {:?}, {:?})", fd, buf, count, offset); this.write(fd, buf, count, Some(offset), dest)?; } @@ -218,13 +339,27 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_scalar(result, dest)?; } "dup" => { - let [old_fd] = this.check_shim(abi, Conv::C, link_name, args)?; + let [old_fd] = this.check_shim_abi( + link_name, + abi, + ExternAbi::C { unwind: false }, + [this.tcx.types.i32], + this.tcx.types.i32, + args, + )?; let old_fd = this.read_scalar(old_fd)?.to_i32()?; let new_fd = this.dup(old_fd)?; this.write_scalar(new_fd, dest)?; } "dup2" => { - let [old_fd, new_fd] = this.check_shim(abi, Conv::C, link_name, args)?; + let [old_fd, new_fd] = this.check_shim_abi( + link_name, + abi, + ExternAbi::C { unwind: false }, + [this.tcx.types.i32, this.tcx.types.i32], + this.tcx.types.i32, + args, + )?; let old_fd = this.read_scalar(old_fd)?.to_i32()?; let new_fd = this.read_scalar(new_fd)?.to_i32()?; let result = this.dup2(old_fd, new_fd)?; @@ -233,7 +368,14 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "flock" => { // Currently this function does not exist on all Unixes, e.g. on Solaris. this.check_target_os(&["linux", "freebsd", "macos", "illumos"], link_name)?; - let [fd, op] = this.check_shim(abi, Conv::C, link_name, args)?; + let [fd, op] = this.check_shim_abi( + link_name, + abi, + ExternAbi::C { unwind: false }, + [this.tcx.types.i32, this.tcx.types.i32], + this.tcx.types.i32, + args, + )?; let fd = this.read_scalar(fd)?.to_i32()?; let op = this.read_scalar(op)?.to_i32()?; let result = this.flock(fd, op)?; @@ -250,140 +392,311 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_scalar(result, dest)?; } "unlink" => { - let [path] = this.check_shim(abi, Conv::C, link_name, args)?; + let [path] = this.check_shim_abi( + link_name, + abi, + ExternAbi::C { unwind: false }, + [this.machine.layouts.const_raw_ptr.ty], + this.tcx.types.i32, + args, + )?; let result = this.unlink(path)?; this.write_scalar(result, dest)?; } "symlink" => { - let [target, linkpath] = this.check_shim(abi, Conv::C, link_name, args)?; + let [target, linkpath] = this.check_shim_abi( + link_name, + abi, + ExternAbi::C { unwind: false }, + [this.machine.layouts.const_raw_ptr.ty, this.machine.layouts.const_raw_ptr.ty], + this.tcx.types.i32, + args, + )?; let result = this.symlink(target, linkpath)?; this.write_scalar(result, dest)?; } "rename" => { - let [oldpath, newpath] = this.check_shim(abi, Conv::C, link_name, args)?; + let [oldpath, newpath] = this.check_shim_abi( + link_name, + abi, + ExternAbi::C { unwind: false }, + [this.machine.layouts.const_raw_ptr.ty, this.machine.layouts.const_raw_ptr.ty], + this.tcx.types.i32, + args, + )?; let result = this.rename(oldpath, newpath)?; this.write_scalar(result, dest)?; } "mkdir" => { - let [path, mode] = this.check_shim(abi, Conv::C, link_name, args)?; + let [path, mode] = this.check_shim_abi( + link_name, + abi, + ExternAbi::C { unwind: false }, + [this.machine.layouts.const_raw_ptr.ty, this.libc_ty_layout("mode_t").ty], + this.tcx.types.i32, + args, + )?; let result = this.mkdir(path, mode)?; this.write_scalar(result, dest)?; } "rmdir" => { - let [path] = this.check_shim(abi, Conv::C, link_name, args)?; + let [path] = this.check_shim_abi( + link_name, + abi, + ExternAbi::C { unwind: false }, + [this.machine.layouts.const_raw_ptr.ty], + this.tcx.types.i32, + args, + )?; let result = this.rmdir(path)?; this.write_scalar(result, dest)?; } "opendir" => { - let [name] = this.check_shim(abi, Conv::C, link_name, args)?; + let [name] = this.check_shim_abi( + link_name, + abi, + ExternAbi::C { unwind: false }, + [this.machine.layouts.const_raw_ptr.ty], + this.machine.layouts.mut_raw_ptr.ty, + args, + )?; let result = this.opendir(name)?; this.write_scalar(result, dest)?; } "closedir" => { - let [dirp] = this.check_shim(abi, Conv::C, link_name, args)?; + let [dirp] = this.check_shim_abi( + link_name, + abi, + ExternAbi::C { unwind: false }, + [this.machine.layouts.mut_raw_ptr.ty], + this.tcx.types.i32, + args, + )?; let result = this.closedir(dirp)?; this.write_scalar(result, dest)?; } "lseek64" => { - let [fd, offset, whence] = this.check_shim(abi, Conv::C, link_name, args)?; + let off64_t = this.libc_ty_layout("off64_t"); + let [fd, offset, whence] = this.check_shim_abi( + link_name, + abi, + ExternAbi::C { unwind: false }, + [this.tcx.types.i32, off64_t.ty, this.tcx.types.i32], + off64_t.ty, + args, + )?; let fd = this.read_scalar(fd)?.to_i32()?; - let offset = this.read_scalar(offset)?.to_i64()?; + let offset = this.read_scalar(offset)?.to_int(off64_t.size)?; let whence = this.read_scalar(whence)?.to_i32()?; - let result = this.lseek64(fd, offset.into(), whence)?; - this.write_scalar(result, dest)?; + this.lseek64(fd, offset, whence, dest)?; } "lseek" => { - let [fd, offset, whence] = this.check_shim(abi, Conv::C, link_name, args)?; + let off_t = this.libc_ty_layout("off_t"); + let [fd, offset, whence] = this.check_shim_abi( + link_name, + abi, + ExternAbi::C { unwind: false }, + [this.tcx.types.i32, off_t.ty, this.tcx.types.i32], + off_t.ty, + args, + )?; let fd = this.read_scalar(fd)?.to_i32()?; - let offset = this.read_scalar(offset)?.to_int(this.libc_ty_layout("off_t").size)?; + let offset = this.read_scalar(offset)?.to_int(off_t.size)?; let whence = this.read_scalar(whence)?.to_i32()?; - let result = this.lseek64(fd, offset, whence)?; - this.write_scalar(result, dest)?; + this.lseek64(fd, offset, whence, dest)?; } "ftruncate64" => { - let [fd, length] = this.check_shim(abi, Conv::C, link_name, args)?; + let off64_t = this.libc_ty_layout("off64_t"); + let [fd, length] = this.check_shim_abi( + link_name, + abi, + ExternAbi::C { unwind: false }, + [this.tcx.types.i32, off64_t.ty], + this.tcx.types.i32, + args, + )?; let fd = this.read_scalar(fd)?.to_i32()?; - let length = this.read_scalar(length)?.to_i64()?; - let result = this.ftruncate64(fd, length.into())?; + let length = this.read_scalar(length)?.to_int(off64_t.size)?; + let result = this.ftruncate64(fd, length)?; this.write_scalar(result, dest)?; } "ftruncate" => { - let [fd, length] = this.check_shim(abi, Conv::C, link_name, args)?; + let off_t = this.libc_ty_layout("off_t"); + let [fd, length] = this.check_shim_abi( + link_name, + abi, + ExternAbi::C { unwind: false }, + [this.tcx.types.i32, off_t.ty], + this.tcx.types.i32, + args, + )?; let fd = this.read_scalar(fd)?.to_i32()?; - let length = this.read_scalar(length)?.to_int(this.libc_ty_layout("off_t").size)?; + let length = this.read_scalar(length)?.to_int(off_t.size)?; let result = this.ftruncate64(fd, length)?; this.write_scalar(result, dest)?; } "fsync" => { - let [fd] = this.check_shim(abi, Conv::C, link_name, args)?; + let [fd] = this.check_shim_abi( + link_name, + abi, + ExternAbi::C { unwind: false }, + [this.tcx.types.i32], + this.tcx.types.i32, + args, + )?; let result = this.fsync(fd)?; this.write_scalar(result, dest)?; } "fdatasync" => { - let [fd] = this.check_shim(abi, Conv::C, link_name, args)?; + let [fd] = this.check_shim_abi( + link_name, + abi, + ExternAbi::C { unwind: false }, + [this.tcx.types.i32], + this.tcx.types.i32, + args, + )?; let result = this.fdatasync(fd)?; this.write_scalar(result, dest)?; } "readlink" => { - let [pathname, buf, bufsize] = this.check_shim(abi, Conv::C, link_name, args)?; + let [pathname, buf, bufsize] = this.check_shim_abi( + link_name, + abi, + ExternAbi::C { unwind: false }, + [ + this.machine.layouts.const_raw_ptr.ty, + this.machine.layouts.mut_raw_ptr.ty, + this.tcx.types.usize, + ], + this.tcx.types.isize, + args, + )?; let result = this.readlink(pathname, buf, bufsize)?; this.write_scalar(Scalar::from_target_isize(result, this), dest)?; } "posix_fadvise" => { - let [fd, offset, len, advice] = this.check_shim(abi, Conv::C, link_name, args)?; + let off_t = this.libc_ty_layout("off_t"); + let [fd, offset, len, advice] = this.check_shim_abi( + link_name, + abi, + ExternAbi::C { unwind: false }, + [this.tcx.types.i32, off_t.ty, off_t.ty, this.tcx.types.i32], + this.tcx.types.i32, + args, + )?; this.read_scalar(fd)?.to_i32()?; - this.read_target_isize(offset)?; - this.read_target_isize(len)?; + this.read_scalar(offset)?.to_int(off_t.size)?; + this.read_scalar(len)?.to_int(off_t.size)?; this.read_scalar(advice)?.to_i32()?; // fadvise is only informational, we can ignore it. this.write_null(dest)?; } "realpath" => { - let [path, resolved_path] = this.check_shim(abi, Conv::C, link_name, args)?; + let [path, resolved_path] = this.check_shim_abi( + link_name, + abi, + ExternAbi::C { unwind: false }, + [this.machine.layouts.const_raw_ptr.ty, this.machine.layouts.mut_raw_ptr.ty], + this.machine.layouts.mut_raw_ptr.ty, + args, + )?; let result = this.realpath(path, resolved_path)?; this.write_scalar(result, dest)?; } "mkstemp" => { - let [template] = this.check_shim(abi, Conv::C, link_name, args)?; + let [template] = this.check_shim_abi( + link_name, + abi, + ExternAbi::C { unwind: false }, + [this.machine.layouts.mut_raw_ptr.ty], + this.tcx.types.i32, + args, + )?; let result = this.mkstemp(template)?; this.write_scalar(result, dest)?; } // Unnamed sockets and pipes "socketpair" => { - let [domain, type_, protocol, sv] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [domain, type_, protocol, sv] = this.check_shim_abi( + link_name, + abi, + ExternAbi::C { unwind: false }, + [ + this.tcx.types.i32, + this.tcx.types.i32, + this.tcx.types.i32, + this.machine.layouts.mut_raw_ptr.ty, + ], + this.tcx.types.i32, + args, + )?; let result = this.socketpair(domain, type_, protocol, sv)?; this.write_scalar(result, dest)?; } "pipe" => { - let [pipefd] = this.check_shim(abi, Conv::C, link_name, args)?; + let [pipefd] = this.check_shim_abi( + link_name, + abi, + ExternAbi::C { unwind: false }, + [this.machine.layouts.mut_raw_ptr.ty], + this.tcx.types.i32, + args, + )?; let result = this.pipe2(pipefd, /*flags*/ None)?; this.write_scalar(result, dest)?; } "pipe2" => { // Currently this function does not exist on all Unixes, e.g. on macOS. this.check_target_os(&["linux", "freebsd", "solaris", "illumos"], link_name)?; - let [pipefd, flags] = this.check_shim(abi, Conv::C, link_name, args)?; + let [pipefd, flags] = this.check_shim_abi( + link_name, + abi, + ExternAbi::C { unwind: false }, + [this.machine.layouts.mut_raw_ptr.ty, this.tcx.types.i32], + this.tcx.types.i32, + args, + )?; let result = this.pipe2(pipefd, Some(flags))?; this.write_scalar(result, dest)?; } // Time "gettimeofday" => { - let [tv, tz] = this.check_shim(abi, Conv::C, link_name, args)?; + let [tv, tz] = this.check_shim_abi( + link_name, + abi, + ExternAbi::C { unwind: false }, + [this.machine.layouts.mut_raw_ptr.ty, this.machine.layouts.mut_raw_ptr.ty], + this.tcx.types.i32, + args, + )?; let result = this.gettimeofday(tv, tz)?; this.write_scalar(result, dest)?; } "localtime_r" => { - let [timep, result_op] = this.check_shim(abi, Conv::C, link_name, args)?; + let [timep, result_op] = this.check_shim_abi( + link_name, + abi, + ExternAbi::C { unwind: false }, + [this.machine.layouts.const_raw_ptr.ty, this.machine.layouts.mut_raw_ptr.ty], + this.machine.layouts.mut_raw_ptr.ty, + args, + )?; let result = this.localtime_r(timep, result_op)?; this.write_pointer(result, dest)?; } "clock_gettime" => { - let [clk_id, tp] = this.check_shim(abi, Conv::C, link_name, args)?; - let result = this.clock_gettime(clk_id, tp)?; - this.write_scalar(result, dest)?; + let [clk_id, tp] = this.check_shim_abi( + link_name, + abi, + ExternAbi::C { unwind: false }, + [this.libc_ty_layout("clockid_t").ty, this.machine.layouts.mut_raw_ptr.ty], + this.tcx.types.i32, + args, + )?; + this.clock_gettime(clk_id, tp, dest)?; } // Allocation @@ -834,7 +1147,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // These shims are enabled only when the caller is in the standard library. "pthread_attr_getguardsize" if this.frame_in_std() => { let [_attr, guard_size] = this.check_shim(abi, Conv::C, link_name, args)?; - let guard_size_layout = this.libc_ty_layout("size_t"); + let guard_size_layout = this.machine.layouts.usize; let guard_size = this.deref_pointer_as(guard_size, guard_size_layout)?; this.write_scalar( Scalar::from_uint(this.machine.page_size, guard_size_layout.size), diff --git a/src/tools/miri/src/shims/unix/fs.rs b/src/tools/miri/src/shims/unix/fs.rs index fc0f57694a7..1f6acff0787 100644 --- a/src/tools/miri/src/shims/unix/fs.rs +++ b/src/tools/miri/src/shims/unix/fs.rs @@ -502,7 +502,13 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { interp_ok(Scalar::from_i32(this.try_unwrap_io_result(fd)?)) } - fn lseek64(&mut self, fd_num: i32, offset: i128, whence: i32) -> InterpResult<'tcx, Scalar> { + fn lseek64( + &mut self, + fd_num: i32, + offset: i128, + whence: i32, + dest: &MPlaceTy<'tcx>, + ) -> InterpResult<'tcx> { let this = self.eval_context_mut(); // Isolation check is done via `FileDescription` trait. @@ -510,7 +516,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let seek_from = if whence == this.eval_libc_i32("SEEK_SET") { if offset < 0 { // Negative offsets return `EINVAL`. - return this.set_last_error_and_return_i64(LibcError("EINVAL")); + return this.set_last_error_and_return(LibcError("EINVAL"), dest); } else { SeekFrom::Start(u64::try_from(offset).unwrap()) } @@ -519,19 +525,20 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } else if whence == this.eval_libc_i32("SEEK_END") { SeekFrom::End(i64::try_from(offset).unwrap()) } else { - return this.set_last_error_and_return_i64(LibcError("EINVAL")); + return this.set_last_error_and_return(LibcError("EINVAL"), dest); }; let communicate = this.machine.communicate(); let Some(fd) = this.machine.fds.get(fd_num) else { - return this.set_last_error_and_return_i64(LibcError("EBADF")); + return this.set_last_error_and_return(LibcError("EBADF"), dest); }; let result = fd.seek(communicate, seek_from)?.map(|offset| i64::try_from(offset).unwrap()); drop(fd); let result = this.try_unwrap_io_result(result)?; - interp_ok(Scalar::from_i64(result)) + this.write_int(result, dest)?; + interp_ok(()) } fn unlink(&mut self, path_op: &OpTy<'tcx>) -> InterpResult<'tcx, Scalar> { diff --git a/src/tools/miri/tests/fail/shims/vararg_caller_signature_mismatch.rs b/src/tools/miri/tests/fail/shims/vararg_caller_signature_mismatch.rs index 515e467fb54..ac6e221fcd8 100644 --- a/src/tools/miri/tests/fail/shims/vararg_caller_signature_mismatch.rs +++ b/src/tools/miri/tests/fail/shims/vararg_caller_signature_mismatch.rs @@ -9,6 +9,6 @@ extern "C" { fn main() { let mut fds = [-1, -1]; let res = unsafe { pipe(fds.as_mut_ptr()) }; - //~^ ERROR: calling a non-variadic function with a variadic caller-side signature + //~^ ERROR: ABI mismatch: calling a non-variadic function with a variadic caller-side signature assert_eq!(res, 0); } diff --git a/src/tools/miri/tests/fail/shims/vararg_caller_signature_mismatch.stderr b/src/tools/miri/tests/fail/shims/vararg_caller_signature_mismatch.stderr index 2782f3b3269..0f642aca322 100644 --- a/src/tools/miri/tests/fail/shims/vararg_caller_signature_mismatch.stderr +++ b/src/tools/miri/tests/fail/shims/vararg_caller_signature_mismatch.stderr @@ -1,8 +1,8 @@ -error: Undefined Behavior: calling a non-variadic function with a variadic caller-side signature +error: Undefined Behavior: ABI mismatch: calling a non-variadic function with a variadic caller-side signature --> tests/fail/shims/vararg_caller_signature_mismatch.rs:LL:CC | LL | let res = unsafe { pipe(fds.as_mut_ptr()) }; - | ^^^^^^^^^^^^^^^^^^^^^^ calling a non-variadic function with a variadic caller-side signature + | ^^^^^^^^^^^^^^^^^^^^^^ ABI mismatch: calling a non-variadic function with a variadic caller-side signature | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information -- cgit 1.4.1-3-g733a5 From 9cd4757f5983c50bbd2191850c4fbc542c42a103 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 17 Apr 2025 16:11:37 +0200 Subject: ci.yml: always create sync PR when there's any difference --- src/tools/miri/.github/workflows/ci.yml | 72 +++++++++++++++++---------------- 1 file changed, 37 insertions(+), 35 deletions(-) (limited to 'src/tools') diff --git a/src/tools/miri/.github/workflows/ci.yml b/src/tools/miri/.github/workflows/ci.yml index 59bae513a58..bd6d51530a9 100644 --- a/src/tools/miri/.github/workflows/ci.yml +++ b/src/tools/miri/.github/workflows/ci.yml @@ -89,41 +89,16 @@ jobs: # Check if all jobs that we depend on (in the needs array) were successful. jq --exit-status 'all(.result == "success")' <<< '${{ toJson(needs) }}' - cron-fail-notify: - name: cronjob failure notification + cron-rustc-pull: + name: automatic pull from rustc runs-on: ubuntu-latest permissions: # The cronjob needs to be able to push to the repo... contents: write # ... and create a PR. pull-requests: write - needs: [build, style, coverage] - if: ${{ github.event_name == 'schedule' && failure() }} + if: ${{ github.event_name == 'schedule' }} steps: - # Send a Zulip notification - - name: Install zulip-send - run: pip3 install zulip - - name: Send Zulip notification - env: - ZULIP_BOT_EMAIL: ${{ secrets.ZULIP_BOT_EMAIL }} - ZULIP_API_TOKEN: ${{ secrets.ZULIP_API_TOKEN }} - run: | - ~/.local/bin/zulip-send --user $ZULIP_BOT_EMAIL --api-key $ZULIP_API_TOKEN --site https://rust-lang.zulipchat.com \ - --stream miri --subject "Miri Build Failure ($(date -u +%Y-%m))" \ - --message 'Dear @*T-miri*, - - It would appear that the [Miri cron job build]('"https://github.com/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID"') failed. - - This likely means that rustc changed the miri directory and - we now need to do a [`./miri rustc-pull`](https://github.com/rust-lang/miri/blob/master/CONTRIBUTING.md#importing-changes-from-the-rustc-repo). - - Would you mind investigating this issue? - - Thanks in advance! - Sincerely, - The Miri Cronjobs Bot' - - # Attempt to auto-sync with rustc - uses: actions/checkout@v4 with: fetch-depth: 256 # get a bit more of the history @@ -143,18 +118,45 @@ jobs: run: | ./miri toolchain ./miri fmt --check || (./miri fmt && git commit -am "fmt") - - name: Push changes to a branch + - name: Push changes to a branch and create PR run: | + # `git diff --exit-code` "succeeds" if the diff is empty. + if git diff --exit-code HEAD^; then exit 0; fi + # The diff is non-empty, create a PR. BRANCH="rustup-$(date -u +%Y-%m-%d)" git switch -c $BRANCH git push -u origin $BRANCH - - name: Create Pull Request - run: | - PR=$(gh pr create -B master --title 'Automatic Rustup' --body 'Please close and re-open this PR to trigger CI, then enable auto-merge.') - ~/.local/bin/zulip-send --user $ZULIP_BOT_EMAIL --api-key $ZULIP_API_TOKEN --site https://rust-lang.zulipchat.com \ - --stream miri --subject "Miri Build Failure ($(date -u +%Y-%m))" \ - --message "A PR doing a rustc-pull [has been automatically created]($PR) for your convenience." + gh pr create -B master --title 'Automatic Rustup' --body 'Please close and re-open this PR to trigger CI, then enable auto-merge.' env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} ZULIP_BOT_EMAIL: ${{ secrets.ZULIP_BOT_EMAIL }} ZULIP_API_TOKEN: ${{ secrets.ZULIP_API_TOKEN }} + + cron-fail-notify: + name: cronjob failure notification + runs-on: ubuntu-latest + needs: [build, style, coverage] + if: ${{ github.event_name == 'schedule' && failure() }} + steps: + # Send a Zulip notification + - name: Install zulip-send + run: pip3 install zulip + - name: Send Zulip notification + env: + ZULIP_BOT_EMAIL: ${{ secrets.ZULIP_BOT_EMAIL }} + ZULIP_API_TOKEN: ${{ secrets.ZULIP_API_TOKEN }} + run: | + ~/.local/bin/zulip-send --user $ZULIP_BOT_EMAIL --api-key $ZULIP_API_TOKEN --site https://rust-lang.zulipchat.com \ + --stream miri --subject "Miri Build Failure ($(date -u +%Y-%m))" \ + --message 'Dear @*T-miri*, + + It would appear that the [Miri cron job build]('"https://github.com/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID"') failed. + + This likely means that rustc changed the miri directory and + we now need to do a [`./miri rustc-pull`](https://github.com/rust-lang/miri/blob/master/CONTRIBUTING.md#importing-changes-from-the-rustc-repo). + + Would you mind investigating this issue? + + Thanks in advance! + Sincerely, + The Miri Cronjobs Bot' -- cgit 1.4.1-3-g733a5 From 8c9a9a77164ae3621a4bc7710670a8a49b0a9e66 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 17 Apr 2025 16:12:42 +0200 Subject: for testing, run the CI job an extra time today --- src/tools/miri/.github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/tools') diff --git a/src/tools/miri/.github/workflows/ci.yml b/src/tools/miri/.github/workflows/ci.yml index bd6d51530a9..86815fc60fb 100644 --- a/src/tools/miri/.github/workflows/ci.yml +++ b/src/tools/miri/.github/workflows/ci.yml @@ -6,7 +6,7 @@ on: branches: - 'master' schedule: - - cron: '44 4 * * *' # At 4:44 UTC every day. + - cron: '44 4,17 * * *' # At 4:44 UTC every day. defaults: run: -- cgit 1.4.1-3-g733a5 From edb3aaf655f1a7a766c5d37eacbf7931c087130b Mon Sep 17 00:00:00 2001 From: The Miri Cronjob Bot Date: Thu, 17 Apr 2025 17:50:48 +0000 Subject: Preparing for merge from rustc --- src/tools/miri/rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/tools') diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version index d1107e51509..ed2e4474add 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -1bc56185ee257ed829a0aea7abdc3b03c5fed887 +883f9f72e87ccb6838d528d8158ea6323baacc65 -- cgit 1.4.1-3-g733a5 From e3b01c774953b8174c556b8a96383fe3132db931 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 17 Apr 2025 20:16:53 +0200 Subject: remove test trigger fron cron job --- src/tools/miri/.github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/tools') diff --git a/src/tools/miri/.github/workflows/ci.yml b/src/tools/miri/.github/workflows/ci.yml index 86815fc60fb..bd6d51530a9 100644 --- a/src/tools/miri/.github/workflows/ci.yml +++ b/src/tools/miri/.github/workflows/ci.yml @@ -6,7 +6,7 @@ on: branches: - 'master' schedule: - - cron: '44 4,17 * * *' # At 4:44 UTC every day. + - cron: '44 4 * * *' # At 4:44 UTC every day. defaults: run: -- cgit 1.4.1-3-g733a5 From 378886f77239c4661945c877f50c17512bbbd6a2 Mon Sep 17 00:00:00 2001 From: The Miri Cronjob Bot Date: Fri, 18 Apr 2025 04:54:04 +0000 Subject: Preparing for merge from rustc --- src/tools/miri/rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/tools') diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version index ed2e4474add..45b3546a09b 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -883f9f72e87ccb6838d528d8158ea6323baacc65 +1f76d219c906f0112bb1872f33aa977164c53fa6 -- cgit 1.4.1-3-g733a5 From 4b995e72b66e510f678484400c33f838cbf0361b Mon Sep 17 00:00:00 2001 From: The Miri Cronjob Bot Date: Sat, 19 Apr 2025 04:52:37 +0000 Subject: Preparing for merge from rustc --- src/tools/miri/rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/tools') diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version index 45b3546a09b..2d7b6a650ae 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -1f76d219c906f0112bb1872f33aa977164c53fa6 +2ef78586529b5f68cc42bcbe9b10b4afe56a942a -- cgit 1.4.1-3-g733a5 From 32fe60bc57ccdc234eb51bd22f74f3b55f2941e8 Mon Sep 17 00:00:00 2001 From: The Miri Cronjob Bot Date: Sun, 20 Apr 2025 04:52:36 +0000 Subject: Preparing for merge from rustc --- src/tools/miri/rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/tools') diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version index 2d7b6a650ae..ce1b8fabac7 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -2ef78586529b5f68cc42bcbe9b10b4afe56a942a +90fd16eb5be9255006c95e8af12a0d43854dc1a9 -- cgit 1.4.1-3-g733a5 From e8a6c175c51fbc347ea0b4479cc1b2de0932ddab Mon Sep 17 00:00:00 2001 From: Urgau Date: Sat, 30 Mar 2024 16:40:24 +0100 Subject: Allow `dangerous_implicit_autorefs` lint in some tests --- library/core/src/pin.rs | 2 +- src/tools/miri/tests/pass/dst-raw.rs | 2 ++ src/tools/miri/tests/pass/stacked-borrows/interior_mutability.rs | 2 ++ tests/ui/dynamically-sized-types/dst-raw.rs | 2 ++ 4 files changed, 7 insertions(+), 1 deletion(-) (limited to 'src/tools') diff --git a/library/core/src/pin.rs b/library/core/src/pin.rs index 48ed5ae451e..39c11572e47 100644 --- a/library/core/src/pin.rs +++ b/library/core/src/pin.rs @@ -676,7 +676,7 @@ //! let data_ptr = unpinned_src.data.as_ptr() as *const u8; //! let slice_ptr = unpinned_src.slice.as_ptr() as *const u8; //! let offset = slice_ptr.offset_from(data_ptr) as usize; -//! let len = (*unpinned_src.slice.as_ptr()).len(); +//! let len = unpinned_src.slice.as_ptr().len(); //! //! unpinned_self.slice = NonNull::from(&mut unpinned_self.data[offset..offset+len]); //! } diff --git a/src/tools/miri/tests/pass/dst-raw.rs b/src/tools/miri/tests/pass/dst-raw.rs index f26191a1d59..3d0b843b3da 100644 --- a/src/tools/miri/tests/pass/dst-raw.rs +++ b/src/tools/miri/tests/pass/dst-raw.rs @@ -1,5 +1,7 @@ // Test DST raw pointers +#![allow(dangerous_implicit_autorefs)] + trait Trait { fn foo(&self) -> isize; } diff --git a/src/tools/miri/tests/pass/stacked-borrows/interior_mutability.rs b/src/tools/miri/tests/pass/stacked-borrows/interior_mutability.rs index 830e9c33847..e86cb3711ac 100644 --- a/src/tools/miri/tests/pass/stacked-borrows/interior_mutability.rs +++ b/src/tools/miri/tests/pass/stacked-borrows/interior_mutability.rs @@ -1,3 +1,5 @@ +#![allow(dangerous_implicit_autorefs)] + use std::cell::{Cell, Ref, RefCell, RefMut, UnsafeCell}; use std::mem::{self, MaybeUninit}; diff --git a/tests/ui/dynamically-sized-types/dst-raw.rs b/tests/ui/dynamically-sized-types/dst-raw.rs index 111848c5a7f..935f0f11ca6 100644 --- a/tests/ui/dynamically-sized-types/dst-raw.rs +++ b/tests/ui/dynamically-sized-types/dst-raw.rs @@ -1,6 +1,8 @@ //@ run-pass // Test DST raw pointers +#![allow(dangerous_implicit_autorefs)] + trait Trait { fn foo(&self) -> isize; } -- cgit 1.4.1-3-g733a5 From 9d16f6666dd92990cf36e40f9043b7c962a9d627 Mon Sep 17 00:00:00 2001 From: The Miri Cronjob Bot Date: Tue, 22 Apr 2025 04:53:59 +0000 Subject: Preparing for merge from rustc --- src/tools/miri/rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/tools') diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version index ce1b8fabac7..b9d35019e1f 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -90fd16eb5be9255006c95e8af12a0d43854dc1a9 +fae7785b60ea7fe1ad293352c057a5b7be73d245 -- cgit 1.4.1-3-g733a5 From ae3adaec6d2c23d6e31078486f0ac29b534c4638 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 22 Apr 2025 11:19:57 +0200 Subject: TB: add missing interior_mutability test file --- .../tests/pass/tree_borrows/interior_mutability.rs | 177 +++++++++++++++++++++ 1 file changed, 177 insertions(+) create mode 100644 src/tools/miri/tests/pass/tree_borrows/interior_mutability.rs (limited to 'src/tools') diff --git a/src/tools/miri/tests/pass/tree_borrows/interior_mutability.rs b/src/tools/miri/tests/pass/tree_borrows/interior_mutability.rs new file mode 100644 index 00000000000..752ae4b20c5 --- /dev/null +++ b/src/tools/miri/tests/pass/tree_borrows/interior_mutability.rs @@ -0,0 +1,177 @@ +//@revisions: default uniq +//@compile-flags: -Zmiri-tree-borrows +//@[uniq]compile-flags: -Zmiri-unique-is-unique +use std::cell::{Cell, Ref, RefCell, RefMut, UnsafeCell}; +use std::mem::{self, MaybeUninit}; + +fn main() { + aliasing_mut_and_shr(); + aliasing_frz_and_shr(); + into_interior_mutability(); + unsafe_cell_2phase(); + unsafe_cell_deallocate(); + unsafe_cell_invalidate(); + refcell_basic(); + ref_protector(); + ref_mut_protector(); + rust_issue_68303(); +} + +fn aliasing_mut_and_shr() { + fn inner(rc: &RefCell, aliasing: &mut i32) { + *aliasing += 4; + let _escape_to_raw = rc as *const _; + *aliasing += 4; + let _shr = &*rc; + *aliasing += 4; + // also turning this into a frozen ref now must work + let aliasing = &*aliasing; + let _val = *aliasing; + let _escape_to_raw = rc as *const _; // this must NOT unfreeze + let _val = *aliasing; + let _shr = &*rc; // this must NOT unfreeze + let _val = *aliasing; + } + + let rc = RefCell::new(23); + let mut bmut = rc.borrow_mut(); + inner(&rc, &mut *bmut); + drop(bmut); + assert_eq!(*rc.borrow(), 23 + 12); +} + +fn aliasing_frz_and_shr() { + fn inner(rc: &RefCell, aliasing: &i32) { + let _val = *aliasing; + let _escape_to_raw = rc as *const _; // this must NOT unfreeze + let _val = *aliasing; + let _shr = &*rc; // this must NOT unfreeze + let _val = *aliasing; + } + + let rc = RefCell::new(23); + let bshr = rc.borrow(); + inner(&rc, &*bshr); + assert_eq!(*rc.borrow(), 23); +} + +// Getting a pointer into a union with interior mutability used to be tricky +// business (https://github.com/rust-lang/miri/issues/615), but it should work +// now. +fn into_interior_mutability() { + let mut x: MaybeUninit<(Cell, u32)> = MaybeUninit::uninit(); + x.as_ptr(); + x.write((Cell::new(0), 1)); + let ptr = unsafe { x.assume_init_ref() }; + assert_eq!(ptr.1, 1); +} + +// Two-phase borrows of the pointer returned by UnsafeCell::get() should not +// invalidate aliases. +fn unsafe_cell_2phase() { + unsafe { + let x = &UnsafeCell::new(vec![]); + let x2 = &*x; + (*x.get()).push(0); + let _val = (*x2.get()).get(0); + } +} + +/// Make sure we can deallocate an UnsafeCell that was passed to an active fn call. +/// (This is the fix for https://github.com/rust-lang/rust/issues/55005.) +fn unsafe_cell_deallocate() { + fn f(x: &UnsafeCell) { + let b: Box = unsafe { Box::from_raw(x as *const _ as *mut i32) }; + drop(b) + } + + let b = Box::new(0i32); + f(unsafe { mem::transmute(Box::into_raw(b)) }); +} + +/// As a side-effect of the above, we also allow this -- at least for now. +fn unsafe_cell_invalidate() { + fn f(_x: &UnsafeCell, y: *mut i32) { + // Writing to y invalidates x, but that is okay. + unsafe { + *y += 1; + } + } + + let mut x = 0i32; + let raw1 = &mut x as *mut _; + let ref1 = unsafe { &mut *raw1 }; + let raw2 = ref1 as *mut _; + // Now the borrow stack is: raw1, ref2, raw2. + // So using raw1 invalidates raw2. + f(unsafe { mem::transmute(raw2) }, raw1); +} + +fn refcell_basic() { + let c = RefCell::new(42); + { + let s1 = c.borrow(); + let _x: i32 = *s1; + let s2 = c.borrow(); + let _x: i32 = *s1; + let _y: i32 = *s2; + let _x: i32 = *s1; + let _y: i32 = *s2; + } + { + let mut m = c.borrow_mut(); + let _z: i32 = *m; + { + let s: &i32 = &*m; + let _x = *s; + } + *m = 23; + let _z: i32 = *m; + } + { + let s1 = c.borrow(); + let _x: i32 = *s1; + let s2 = c.borrow(); + let _x: i32 = *s1; + let _y: i32 = *s2; + let _x: i32 = *s1; + let _y: i32 = *s2; + } +} + +// Adding a Stacked Borrows protector for `Ref` would break this +fn ref_protector() { + fn break_it(rc: &RefCell, r: Ref<'_, i32>) { + // `r` has a shared reference, it is passed in as argument and hence + // a protector is added that marks this memory as read-only for the entire + // duration of this function. + drop(r); + // *oops* here we can mutate that memory. + *rc.borrow_mut() = 2; + } + + let rc = RefCell::new(0); + break_it(&rc, rc.borrow()) +} + +fn ref_mut_protector() { + fn break_it(rc: &RefCell, r: RefMut<'_, i32>) { + // `r` has a shared reference, it is passed in as argument and hence + // a protector is added that marks this memory as inaccessible for the entire + // duration of this function + drop(r); + // *oops* here we can mutate that memory. + *rc.borrow_mut() = 2; + } + + let rc = RefCell::new(0); + break_it(&rc, rc.borrow_mut()) +} + +/// Make sure we do not have bad enum layout optimizations. +fn rust_issue_68303() { + let optional = Some(RefCell::new(false)); + let mut handle = optional.as_ref().unwrap().borrow_mut(); + assert!(optional.is_some()); + *handle = true; +} -- cgit 1.4.1-3-g733a5 From 39ddb4262716c7f7a145b653bc637a8c8af45cc7 Mon Sep 17 00:00:00 2001 From: The Miri Cronjob Bot Date: Wed, 23 Apr 2025 04:54:12 +0000 Subject: Preparing for merge from rustc --- src/tools/miri/rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/tools') diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version index b9d35019e1f..f6e6b1ca741 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -fae7785b60ea7fe1ad293352c057a5b7be73d245 +1a5bf12f6586d724ed5ff40e58e06c0233560c0e -- cgit 1.4.1-3-g733a5 From 9b491c0b3be8c2cd90e1f05db744f9881fac87ff Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 24 Apr 2025 10:57:42 +0200 Subject: Preparing for merge from rustc --- src/tools/miri/rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/tools') diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version index f6e6b1ca741..5be53f47668 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -1a5bf12f6586d724ed5ff40e58e06c0233560c0e +7f695232a80fa1833e2282f2577c5e1ff066bf39 -- cgit 1.4.1-3-g733a5 From f1b6b85f0840a4c14a3d955ea0b5c0164289f94a Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 24 Apr 2025 10:59:04 +0200 Subject: CI: print message when skipping PR --- src/tools/miri/.github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/tools') diff --git a/src/tools/miri/.github/workflows/ci.yml b/src/tools/miri/.github/workflows/ci.yml index bd6d51530a9..9dbf51e9796 100644 --- a/src/tools/miri/.github/workflows/ci.yml +++ b/src/tools/miri/.github/workflows/ci.yml @@ -121,7 +121,7 @@ jobs: - name: Push changes to a branch and create PR run: | # `git diff --exit-code` "succeeds" if the diff is empty. - if git diff --exit-code HEAD^; then exit 0; fi + if git diff --exit-code HEAD^; then echo "Nothing changed in rustc, skipping PR"; exit 0; fi # The diff is non-empty, create a PR. BRANCH="rustup-$(date -u +%Y-%m-%d)" git switch -c $BRANCH -- cgit 1.4.1-3-g733a5 From f2bbc1bf06ef905cf2f5ea9a54f5b3390f534b49 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 24 Apr 2025 11:02:55 +0200 Subject: clippy --- .../miri/src/borrow_tracker/tree_borrows/tree/tests.rs | 15 +++++++-------- src/tools/miri/src/concurrency/data_race.rs | 2 +- src/tools/miri/src/machine.rs | 5 ++--- src/tools/miri/src/shims/time.rs | 4 ++-- 4 files changed, 12 insertions(+), 14 deletions(-) (limited to 'src/tools') diff --git a/src/tools/miri/src/borrow_tracker/tree_borrows/tree/tests.rs b/src/tools/miri/src/borrow_tracker/tree_borrows/tree/tests.rs index a429940748c..dbfa9807e3b 100644 --- a/src/tools/miri/src/borrow_tracker/tree_borrows/tree/tests.rs +++ b/src/tools/miri/src/borrow_tracker/tree_borrows/tree/tests.rs @@ -61,8 +61,7 @@ fn all_read_accesses_commute() { // ... and produce the same final result. assert_eq!( loc12, loc21, - "Read accesses {:?} followed by {:?} do not commute !", - rel1, rel2 + "Read accesses {rel1:?} followed by {rel2:?} do not commute !" ); } } @@ -674,8 +673,8 @@ mod spurious_read { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let (x, y) = self.retag_permissions(); write!(f, "{}; ", self.xy_rel)?; - write!(f, "y: ({}); ", y,)?; - write!(f, "retag x ({}); ", x)?; + write!(f, "y: ({y}); ")?; + write!(f, "retag x ({x}); ")?; write!(f, "; ;")?; Ok(()) @@ -730,17 +729,17 @@ mod spurious_read { // protector. final_source .distinguishable::(&final_target) - .then_some(format!("{}", final_target)) + .then_some(format!("{final_target}")) } else { Some(format!("UB")) } }; if let Some(final_target) = distinguishable { eprintln!( - "For pattern '{}', inserting a spurious read through x makes the final state '{}' instead of '{}' which is observable", - pat, final_target, final_source + "For pattern '{pat}', inserting a spurious read through x makes the final state '{final_target}' \ + instead of '{final_source}' which is observable" ); - eprintln!(" (arbitrary code instanciated with '{}')", opaque); + eprintln!(" (arbitrary code instanciated with '{opaque}')"); err += 1; // We found an instanciation of the opaque code that makes this Pattern // fail, we don't really need to check the rest. diff --git a/src/tools/miri/src/concurrency/data_race.rs b/src/tools/miri/src/concurrency/data_race.rs index 923031dbbd1..847c6823475 100644 --- a/src/tools/miri/src/concurrency/data_race.rs +++ b/src/tools/miri/src/concurrency/data_race.rs @@ -381,7 +381,7 @@ impl AccessType { }); if let Some(ty) = ty { - msg.push_str(&format!(" of type `{}`", ty)); + msg.push_str(&format!(" of type `{ty}`")); } msg diff --git a/src/tools/miri/src/machine.rs b/src/tools/miri/src/machine.rs index ea59d327be8..c3d841353a8 100644 --- a/src/tools/miri/src/machine.rs +++ b/src/tools/miri/src/machine.rs @@ -721,9 +721,8 @@ impl<'tcx> MiriMachine<'tcx> { // Check if host target == the session target. if host_triple != target_triple { panic!( - "calling external C functions in linked .so file requires host and target to be the same: host={}, target={}", - host_triple, - target_triple, + "calling native C functions in linked .so file requires host and target to be the same: \ + host={host_triple}, target={target_triple}", ); } // Note: it is the user's responsibility to provide a correct SO file. diff --git a/src/tools/miri/src/shims/time.rs b/src/tools/miri/src/shims/time.rs index c98d6e2b408..28f4ca5bb1b 100644 --- a/src/tools/miri/src/shims/time.rs +++ b/src/tools/miri/src/shims/time.rs @@ -191,10 +191,10 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { tm_zone.push('+'); } let offset_hour = offset_in_seconds.abs() / 3600; - write!(tm_zone, "{:02}", offset_hour).unwrap(); + write!(tm_zone, "{offset_hour:02}").unwrap(); let offset_min = (offset_in_seconds.abs() % 3600) / 60; if offset_min != 0 { - write!(tm_zone, "{:02}", offset_min).unwrap(); + write!(tm_zone, "{offset_min:02}").unwrap(); } // Add null terminator for C string compatibility. -- cgit 1.4.1-3-g733a5 From bdfeb8f36bb2716eb8f5aca32ba4f81563a6818b Mon Sep 17 00:00:00 2001 From: Boxy Date: Thu, 24 Apr 2025 11:31:33 +0100 Subject: Remove `weak` alias terminology --- compiler/rustc_const_eval/src/util/type_name.rs | 2 +- compiler/rustc_hir_analysis/src/check/wfcheck.rs | 4 +-- .../src/coherence/inherent_impls.rs | 4 +-- .../rustc_hir_analysis/src/coherence/orphan.rs | 2 +- .../src/constrained_generic_params.rs | 8 ++--- .../rustc_hir_analysis/src/hir_ty_lowering/mod.rs | 2 +- .../src/outlives/implicit_infer.rs | 4 +-- .../rustc_hir_analysis/src/variance/constraints.rs | 4 +-- compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs | 4 +-- .../rustc_infer/src/infer/relate/generalize.rs | 2 +- compiler/rustc_lint/src/types.rs | 2 +- compiler/rustc_middle/src/query/mod.rs | 6 ++-- compiler/rustc_middle/src/traits/mod.rs | 2 +- compiler/rustc_middle/src/traits/query.rs | 2 +- compiler/rustc_middle/src/ty/context.rs | 4 +-- compiler/rustc_middle/src/ty/error.rs | 2 +- compiler/rustc_middle/src/ty/inhabitedness/mod.rs | 2 +- compiler/rustc_middle/src/ty/print/pretty.rs | 4 +-- compiler/rustc_middle/src/ty/sty.rs | 2 +- compiler/rustc_middle/src/ty/util.rs | 42 +++++++++++----------- compiler/rustc_middle/src/ty/visit.rs | 6 ++-- .../src/solve/assembly/mod.rs | 2 +- .../src/solve/assembly/structural_traits.rs | 2 +- .../src/solve/normalizes_to/free_alias.rs | 37 +++++++++++++++++++ .../src/solve/normalizes_to/mod.rs | 4 +-- .../src/solve/normalizes_to/weak_types.rs | 37 ------------------- .../src/solve/trait_goals.rs | 2 +- compiler/rustc_privacy/src/lib.rs | 4 +-- compiler/rustc_smir/src/rustc_smir/convert/ty.rs | 2 +- compiler/rustc_smir/src/stable_mir/ty.rs | 2 +- .../src/error_reporting/infer/region.rs | 2 +- .../error_reporting/traits/fulfillment_errors.rs | 2 +- .../rustc_trait_selection/src/traits/normalize.rs | 2 +- .../rustc_trait_selection/src/traits/project.rs | 2 +- .../src/traits/query/normalize.rs | 8 ++--- .../src/traits/select/candidate_assembly.rs | 2 +- .../rustc_trait_selection/src/traits/select/mod.rs | 2 +- compiler/rustc_trait_selection/src/traits/wf.rs | 2 +- .../rustc_traits/src/normalize_projection_ty.rs | 6 ++-- compiler/rustc_ty_utils/src/opaque_types.rs | 2 +- compiler/rustc_type_ir/src/flags.rs | 8 ++--- compiler/rustc_type_ir/src/predicate.rs | 14 ++++---- compiler/rustc_type_ir/src/relate.rs | 2 +- compiler/rustc_type_ir/src/ty_kind.rs | 6 ++-- src/librustdoc/clean/mod.rs | 4 +-- src/tools/clippy/clippy_lints/src/dereference.rs | 2 +- .../clippy_lints/src/missing_const_for_fn.rs | 2 +- .../extern-crate-has-eager-type-aliases.rs | 4 +-- 48 files changed, 137 insertions(+), 137 deletions(-) create mode 100644 compiler/rustc_next_trait_solver/src/solve/normalizes_to/free_alias.rs delete mode 100644 compiler/rustc_next_trait_solver/src/solve/normalizes_to/weak_types.rs (limited to 'src/tools') diff --git a/compiler/rustc_const_eval/src/util/type_name.rs b/compiler/rustc_const_eval/src/util/type_name.rs index e14cd603c58..30e96ae4143 100644 --- a/compiler/rustc_const_eval/src/util/type_name.rs +++ b/compiler/rustc_const_eval/src/util/type_name.rs @@ -56,7 +56,7 @@ impl<'tcx> Printer<'tcx> for AbsolutePathPrinter<'tcx> { | ty::Coroutine(def_id, args) => self.print_def_path(def_id, args), ty::Foreign(def_id) => self.print_def_path(def_id, &[]), - ty::Alias(ty::Weak, _) => bug!("type_name: unexpected weak projection"), + ty::Alias(ty::Free, _) => bug!("type_name: unexpected free alias"), ty::Alias(ty::Inherent, _) => bug!("type_name: unexpected inherent projection"), ty::CoroutineWitness(..) => bug!("type_name: unexpected `CoroutineWitness`"), } diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 33d5a86beb3..425edc0e773 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -1991,7 +1991,7 @@ fn check_variances_for_type_defn<'tcx>( ItemKind::TyAlias(..) => { assert!( tcx.type_alias_is_lazy(item.owner_id), - "should not be computing variance of non-weak type alias" + "should not be computing variance of non-free type alias" ); } kind => span_bug!(item.span, "cannot compute the variances of {kind:?}"), @@ -2223,7 +2223,7 @@ impl<'tcx> TypeVisitor> for IsProbablyCyclical<'tcx> { fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow<(), ()> { let def_id = match ty.kind() { ty::Adt(adt_def, _) => Some(adt_def.did()), - ty::Alias(ty::Weak, alias_ty) => Some(alias_ty.def_id), + ty::Alias(ty::Free, alias_ty) => Some(alias_ty.def_id), _ => None, }; if let Some(def_id) = def_id { diff --git a/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs b/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs index c9a9180c5c9..bd25b4a3260 100644 --- a/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs +++ b/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs @@ -150,7 +150,7 @@ impl<'tcx> InherentCollect<'tcx> { let id = id.owner_id.def_id; let item_span = self.tcx.def_span(id); let self_ty = self.tcx.type_of(id).instantiate_identity(); - let mut self_ty = self.tcx.peel_off_weak_alias_tys(self_ty); + let mut self_ty = self.tcx.peel_off_free_alias_tys(self_ty); // We allow impls on pattern types exactly when we allow impls on the base type. // FIXME(pattern_types): Figure out the exact coherence rules we want here. while let ty::Pat(base, _) = *self_ty.kind() { @@ -188,7 +188,7 @@ impl<'tcx> InherentCollect<'tcx> { | ty::CoroutineClosure(..) | ty::Coroutine(..) | ty::CoroutineWitness(..) - | ty::Alias(ty::Weak, _) + | ty::Alias(ty::Free, _) | ty::Bound(..) | ty::Placeholder(_) | ty::Infer(_) => { diff --git a/compiler/rustc_hir_analysis/src/coherence/orphan.rs b/compiler/rustc_hir_analysis/src/coherence/orphan.rs index 74ba4ffe25e..c75fef9f716 100644 --- a/compiler/rustc_hir_analysis/src/coherence/orphan.rs +++ b/compiler/rustc_hir_analysis/src/coherence/orphan.rs @@ -189,7 +189,7 @@ pub(crate) fn orphan_check_impl( ty::Projection => "associated type", // type Foo = (impl Sized, bool) // impl AutoTrait for Foo {} - ty::Weak => "type alias", + ty::Free => "type alias", // type Opaque = impl Trait; // impl AutoTrait for Opaque {} ty::Opaque => "opaque type", diff --git a/compiler/rustc_hir_analysis/src/constrained_generic_params.rs b/compiler/rustc_hir_analysis/src/constrained_generic_params.rs index 951eda72ffe..366b3943a05 100644 --- a/compiler/rustc_hir_analysis/src/constrained_generic_params.rs +++ b/compiler/rustc_hir_analysis/src/constrained_generic_params.rs @@ -49,7 +49,7 @@ pub(crate) fn parameters_for<'tcx>( include_nonconstraining: bool, ) -> Vec { let mut collector = ParameterCollector { parameters: vec![], include_nonconstraining }; - let value = if !include_nonconstraining { tcx.expand_weak_alias_tys(value) } else { value }; + let value = if !include_nonconstraining { tcx.expand_free_alias_tys(value) } else { value }; value.visit_with(&mut collector); collector.parameters } @@ -68,9 +68,9 @@ impl<'tcx> TypeVisitor> for ParameterCollector { { return; } - // All weak alias types should've been expanded beforehand. - ty::Alias(ty::Weak, _) if !self.include_nonconstraining => { - bug!("unexpected weak alias type") + // All free alias types should've been expanded beforehand. + ty::Alias(ty::Free, _) if !self.include_nonconstraining => { + bug!("unexpected free alias type") } ty::Param(param) => self.parameters.push(Parameter::from(param)), _ => {} 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 22162b8b364..8153e6f87f8 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -958,7 +958,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { // feature `lazy_type_alias` enabled get encoded as a type alias that normalization will // then actually instantiate the where bounds of. let alias_ty = ty::AliasTy::new_from_args(tcx, did, args); - Ty::new_alias(tcx, ty::Weak, alias_ty) + Ty::new_alias(tcx, ty::Free, alias_ty) } else { tcx.at(span).type_of(did).instantiate(tcx, args) } diff --git a/compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs b/compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs index 780c27d4595..c99eb12efcc 100644 --- a/compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs +++ b/compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs @@ -157,10 +157,10 @@ fn insert_required_predicates_to_be_wf<'tcx>( ); } - ty::Alias(ty::Weak, alias) => { + ty::Alias(ty::Free, alias) => { // This corresponds to a type like `Type<'a, T>`. // We check inferred and explicit predicates. - debug!("Weak"); + debug!("Free"); check_inferred_predicates( tcx, alias.def_id, diff --git a/compiler/rustc_hir_analysis/src/variance/constraints.rs b/compiler/rustc_hir_analysis/src/variance/constraints.rs index 23223de918c..dc3ce1dd76c 100644 --- a/compiler/rustc_hir_analysis/src/variance/constraints.rs +++ b/compiler/rustc_hir_analysis/src/variance/constraints.rs @@ -107,7 +107,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { let current_item = &CurrentItem { inferred_start }; let ty = tcx.type_of(def_id).instantiate_identity(); - // The type as returned by `type_of` is the underlying type and generally not a weak projection. + // The type as returned by `type_of` is the underlying type and generally not a free alias. // Therefore we need to check the `DefKind` first. if let DefKind::TyAlias = tcx.def_kind(def_id) && tcx.type_alias_is_lazy(def_id) @@ -282,7 +282,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { self.add_constraints_from_invariant_args(current, data.args, variance); } - ty::Alias(ty::Weak, ref data) => { + ty::Alias(ty::Free, ref data) => { self.add_constraints_from_args(current, data.def_id, data.args, variance); } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs index 934820eb4da..de189b30109 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs @@ -337,7 +337,7 @@ impl<'tcx> HirTyLowerer<'tcx> for FnCtxt<'_, 'tcx> { match ty.kind() { ty::Adt(adt_def, _) => Some(*adt_def), // FIXME(#104767): Should we handle bound regions here? - ty::Alias(ty::Projection | ty::Inherent | ty::Weak, _) + ty::Alias(ty::Projection | ty::Inherent | ty::Free, _) if !ty.has_escaping_bound_vars() => { if self.next_trait_solver() { @@ -357,7 +357,7 @@ impl<'tcx> HirTyLowerer<'tcx> for FnCtxt<'_, 'tcx> { // WF obligations that are registered elsewhere, but they have a // better cause code assigned to them in `add_required_obligations_for_hir`. // This means that they should shadow obligations with worse spans. - if let ty::Alias(ty::Projection | ty::Weak, ty::AliasTy { args, def_id, .. }) = + if let ty::Alias(ty::Projection | ty::Free, ty::AliasTy { args, def_id, .. }) = ty.kind() { self.add_required_obligations_for_hir(span, *def_id, args, hir_id); diff --git a/compiler/rustc_infer/src/infer/relate/generalize.rs b/compiler/rustc_infer/src/infer/relate/generalize.rs index b0ccd35e8f0..210b8f37d88 100644 --- a/compiler/rustc_infer/src/infer/relate/generalize.rs +++ b/compiler/rustc_infer/src/infer/relate/generalize.rs @@ -113,7 +113,7 @@ impl<'tcx> InferCtxt<'tcx> { }]); } // The old solver only accepts projection predicates for associated types. - ty::Alias(ty::Inherent | ty::Weak | ty::Opaque, _) => { + ty::Alias(ty::Inherent | ty::Free | ty::Opaque, _) => { return Err(TypeError::CyclicTy(source_ty)); } _ => bug!("generalized `{source_ty:?} to infer, not an alias"), diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs index a084dacfb5b..3b7c23a1fa3 100644 --- a/compiler/rustc_lint/src/types.rs +++ b/compiler/rustc_lint/src/types.rs @@ -1371,7 +1371,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { ty::UnsafeBinder(_) => todo!("FIXME(unsafe_binder)"), ty::Param(..) - | ty::Alias(ty::Projection | ty::Inherent | ty::Weak, ..) + | ty::Alias(ty::Projection | ty::Inherent | ty::Free, ..) | ty::Infer(..) | ty::Bound(..) | ty::Error(_) diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 3432648feab..19a15041b41 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -289,7 +289,7 @@ rustc_queries! { /// Returns whether the type alias given by `DefId` is lazy. /// - /// I.e., if the type alias expands / ought to expand to a [weak] [alias type] + /// I.e., if the type alias expands / ought to expand to a [free] [alias type] /// instead of the underyling aliased type. /// /// Relevant for features `lazy_type_alias` and `type_alias_impl_trait`. @@ -298,7 +298,7 @@ rustc_queries! { /// /// This query *may* panic if the given definition is not a type alias. /// - /// [weak]: rustc_middle::ty::Weak + /// [free]: rustc_middle::ty::Free /// [alias type]: rustc_middle::ty::AliasTy query type_alias_is_lazy(key: DefId) -> bool { desc { |tcx| @@ -2280,7 +2280,7 @@ rustc_queries! { /// Do not call this query directly: Invoke `normalize` instead. /// /// - query normalize_canonicalized_weak_ty( + query normalize_canonicalized_free_alias( goal: CanonicalAliasGoal<'tcx> ) -> Result< &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, NormalizationResult<'tcx>>>, diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs index 7e6151745e2..27079af06fc 100644 --- a/compiler/rustc_middle/src/traits/mod.rs +++ b/compiler/rustc_middle/src/traits/mod.rs @@ -404,7 +404,7 @@ pub enum ObligationCauseCode<'tcx> { /// Requirement for a `const N: Ty` to implement `Ty: ConstParamTy` ConstParam(Ty<'tcx>), - /// Obligations emitted during the normalization of a weak type alias. + /// Obligations emitted during the normalization of a free type alias. TypeAlias(ObligationCauseCodeHandle<'tcx>, Span, DefId), } diff --git a/compiler/rustc_middle/src/traits/query.rs b/compiler/rustc_middle/src/traits/query.rs index 76f3d2bab9c..3f6faa1a572 100644 --- a/compiler/rustc_middle/src/traits/query.rs +++ b/compiler/rustc_middle/src/traits/query.rs @@ -181,7 +181,7 @@ pub struct MethodAutoderefBadTy<'tcx> { pub ty: Canonical<'tcx, QueryResponse<'tcx, Ty<'tcx>>>, } -/// Result of the `normalize_canonicalized_{{,inherent_}projection,weak}_ty` queries. +/// Result of the `normalize_canonicalized_{{,inherent_}projection,free}_ty` queries. #[derive(Clone, Debug, HashStable, TypeFoldable, TypeVisitable)] pub struct NormalizationResult<'tcx> { /// Result of the normalization. diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 98057a25f04..26096de669f 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -226,7 +226,7 @@ impl<'tcx> Interner for TyCtxt<'tcx> { } } DefKind::OpaqueTy => ty::Opaque, - DefKind::TyAlias => ty::Weak, + DefKind::TyAlias => ty::Free, kind => bug!("unexpected DefKind in AliasTy: {kind:?}"), } } @@ -242,7 +242,7 @@ impl<'tcx> Interner for TyCtxt<'tcx> { } } DefKind::OpaqueTy => ty::AliasTermKind::OpaqueTy, - DefKind::TyAlias => ty::AliasTermKind::WeakTy, + DefKind::TyAlias => ty::AliasTermKind::FreeTy, DefKind::AssocConst => ty::AliasTermKind::ProjectionConst, DefKind::AnonConst | DefKind::Const | DefKind::Ctor(_, CtorKind::Const) => { ty::AliasTermKind::UnevaluatedConst diff --git a/compiler/rustc_middle/src/ty/error.rs b/compiler/rustc_middle/src/ty/error.rs index 5ecf1174def..13723874ad3 100644 --- a/compiler/rustc_middle/src/ty/error.rs +++ b/compiler/rustc_middle/src/ty/error.rs @@ -205,7 +205,7 @@ impl<'tcx> Ty<'tcx> { ty::Placeholder(..) => "higher-ranked type".into(), ty::Bound(..) => "bound type variable".into(), ty::Alias(ty::Projection | ty::Inherent, _) => "associated type".into(), - ty::Alias(ty::Weak, _) => "type alias".into(), + ty::Alias(ty::Free, _) => "type alias".into(), ty::Param(_) => "type parameter".into(), ty::Alias(ty::Opaque, ..) => "opaque type".into(), } diff --git a/compiler/rustc_middle/src/ty/inhabitedness/mod.rs b/compiler/rustc_middle/src/ty/inhabitedness/mod.rs index 32988965a35..d8bab58545f 100644 --- a/compiler/rustc_middle/src/ty/inhabitedness/mod.rs +++ b/compiler/rustc_middle/src/ty/inhabitedness/mod.rs @@ -127,7 +127,7 @@ impl<'tcx> Ty<'tcx> { InhabitedPredicate::True } Never => InhabitedPredicate::False, - Param(_) | Alias(ty::Projection | ty::Weak, _) => InhabitedPredicate::GenericType(self), + Param(_) | Alias(ty::Projection | ty::Free, _) => InhabitedPredicate::GenericType(self), Alias(ty::Opaque, alias_ty) => { match alias_ty.def_id.as_local() { // Foreign opaque is considered inhabited. diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index d739218af5e..42315b613f0 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -820,7 +820,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { ty::Foreign(def_id) => { p!(print_def_path(def_id, &[])); } - ty::Alias(ty::Projection | ty::Inherent | ty::Weak, ref data) => { + ty::Alias(ty::Projection | ty::Inherent | ty::Free, ref data) => { p!(print(data)) } ty::Placeholder(placeholder) => match placeholder.bound.kind { @@ -3205,7 +3205,7 @@ define_print! { p!(print_def_path(self.def_id, self.args)); } } - | ty::AliasTermKind::WeakTy + | ty::AliasTermKind::FreeTy | ty::AliasTermKind::OpaqueTy | ty::AliasTermKind::UnevaluatedConst | ty::AliasTermKind::ProjectionConst => { diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index affb7b31ae1..ddce400e5b1 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -489,7 +489,7 @@ impl<'tcx> Ty<'tcx> { (kind, tcx.def_kind(alias_ty.def_id)), (ty::Opaque, DefKind::OpaqueTy) | (ty::Projection | ty::Inherent, DefKind::AssocTy) - | (ty::Weak, DefKind::TyAlias) + | (ty::Free, DefKind::TyAlias) ); Ty::new(tcx, Alias(kind, alias_ty)) } diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index 08cee1101d0..269425d67f3 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -911,7 +911,7 @@ impl<'tcx> TyCtxt<'tcx> { || self.extern_crate(key).is_some_and(|e| e.is_direct()) } - /// Expand any [weak alias types][weak] contained within the given `value`. + /// Expand any [free alias types][free] contained within the given `value`. /// /// This should be used over other normalization routines in situations where /// it's important not to normalize other alias types and where the predicates @@ -926,19 +926,19 @@ impl<'tcx> TyCtxt<'tcx> { ///
/// This delays a bug on overflow! Therefore you need to be certain that the /// contained types get fully normalized at a later stage. Note that even on - /// overflow all well-behaved weak alias types get expanded correctly, so the + /// overflow all well-behaved free alias types get expanded correctly, so the /// result is still useful. ///
/// - /// [weak]: ty::Weak - pub fn expand_weak_alias_tys>>(self, value: T) -> T { - value.fold_with(&mut WeakAliasTypeExpander { tcx: self, depth: 0 }) + /// [free]: ty::Free + pub fn expand_free_alias_tys>>(self, value: T) -> T { + value.fold_with(&mut FreeAliasTypeExpander { tcx: self, depth: 0 }) } - /// Peel off all [weak alias types] in this type until there are none left. + /// Peel off all [free alias types] in this type until there are none left. /// - /// This only expands weak alias types in “head” / outermost positions. It can - /// be used over [expand_weak_alias_tys] as an optimization in situations where + /// This only expands free alias types in “head” / outermost positions. It can + /// be used over [expand_free_alias_tys] as an optimization in situations where /// one only really cares about the *kind* of the final aliased type but not /// the types the other constituent types alias. /// @@ -947,17 +947,17 @@ impl<'tcx> TyCtxt<'tcx> { /// type gets fully normalized at a later stage. /// /// - /// [weak]: ty::Weak - /// [expand_weak_alias_tys]: Self::expand_weak_alias_tys - pub fn peel_off_weak_alias_tys(self, mut ty: Ty<'tcx>) -> Ty<'tcx> { - let ty::Alias(ty::Weak, _) = ty.kind() else { return ty }; + /// [free]: ty::Free + /// [expand_free_alias_tys]: Self::expand_free_alias_tys + pub fn peel_off_free_alias_tys(self, mut ty: Ty<'tcx>) -> Ty<'tcx> { + let ty::Alias(ty::Free, _) = ty.kind() else { return ty }; let limit = self.recursion_limit(); let mut depth = 0; - while let ty::Alias(ty::Weak, alias) = ty.kind() { + while let ty::Alias(ty::Free, alias) = ty.kind() { if !limit.value_within_limit(depth) { - let guar = self.dcx().delayed_bug("overflow expanding weak alias type"); + let guar = self.dcx().delayed_bug("overflow expanding free alias type"); return Ty::new_error(self, guar); } @@ -985,7 +985,7 @@ impl<'tcx> TyCtxt<'tcx> { } ty::AliasTermKind::OpaqueTy => Some(self.variances_of(def_id)), ty::AliasTermKind::InherentTy - | ty::AliasTermKind::WeakTy + | ty::AliasTermKind::FreeTy | ty::AliasTermKind::UnevaluatedConst | ty::AliasTermKind::ProjectionConst => None, } @@ -1078,25 +1078,25 @@ impl<'tcx> TypeFolder> for OpaqueTypeExpander<'tcx> { } } -struct WeakAliasTypeExpander<'tcx> { +struct FreeAliasTypeExpander<'tcx> { tcx: TyCtxt<'tcx>, depth: usize, } -impl<'tcx> TypeFolder> for WeakAliasTypeExpander<'tcx> { +impl<'tcx> TypeFolder> for FreeAliasTypeExpander<'tcx> { fn cx(&self) -> TyCtxt<'tcx> { self.tcx } fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { - if !ty.has_type_flags(ty::TypeFlags::HAS_TY_WEAK) { + if !ty.has_type_flags(ty::TypeFlags::HAS_TY_FREE_ALIAS) { return ty; } - let ty::Alias(ty::Weak, alias) = ty.kind() else { + let ty::Alias(ty::Free, alias) = ty.kind() else { return ty.super_fold_with(self); }; if !self.tcx.recursion_limit().value_within_limit(self.depth) { - let guar = self.tcx.dcx().delayed_bug("overflow expanding weak alias type"); + let guar = self.tcx.dcx().delayed_bug("overflow expanding free alias type"); return Ty::new_error(self.tcx, guar); } @@ -1107,7 +1107,7 @@ impl<'tcx> TypeFolder> for WeakAliasTypeExpander<'tcx> { } fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> { - if !ct.has_type_flags(ty::TypeFlags::HAS_TY_WEAK) { + if !ct.has_type_flags(ty::TypeFlags::HAS_TY_FREE_ALIAS) { return ct; } ct.super_fold_with(self) diff --git a/compiler/rustc_middle/src/ty/visit.rs b/compiler/rustc_middle/src/ty/visit.rs index 44c7b6a7c9e..3853a804a92 100644 --- a/compiler/rustc_middle/src/ty/visit.rs +++ b/compiler/rustc_middle/src/ty/visit.rs @@ -139,7 +139,7 @@ impl<'tcx> TyCtxt<'tcx> { { let mut collector = LateBoundRegionsCollector::new(just_constrained); let value = value.skip_binder(); - let value = if just_constrained { self.expand_weak_alias_tys(value) } else { value }; + let value = if just_constrained { self.expand_free_alias_tys(value) } else { value }; value.visit_with(&mut collector); collector.regions } @@ -182,8 +182,8 @@ impl<'tcx> TypeVisitor> for LateBoundRegionsCollector { ty::Alias(ty::Projection | ty::Inherent | ty::Opaque, _) => { return; } - // All weak alias types should've been expanded beforehand. - ty::Alias(ty::Weak, _) => bug!("unexpected weak alias type"), + // All free alias types should've been expanded beforehand. + ty::Alias(ty::Free, _) => bug!("unexpected free alias type"), _ => {} } } diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs index ecb57cc0ad7..6a817c37737 100644 --- a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs @@ -595,7 +595,7 @@ where } ty::Alias(kind @ (ty::Projection | ty::Opaque), alias_ty) => (kind, alias_ty), - ty::Alias(ty::Inherent | ty::Weak, _) => { + ty::Alias(ty::Inherent | ty::Free, _) => { self.cx().delay_bug(format!("could not normalize {self_ty:?}, it is not WF")); return; } diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs index 1526049719e..035bfff89b5 100644 --- a/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs +++ b/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs @@ -48,7 +48,7 @@ where ty::Dynamic(..) | ty::Param(..) - | ty::Alias(ty::Projection | ty::Inherent | ty::Weak, ..) + | ty::Alias(ty::Projection | ty::Inherent | ty::Free, ..) | ty::Placeholder(..) | ty::Bound(..) | ty::Infer(_) => { diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/free_alias.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/free_alias.rs new file mode 100644 index 00000000000..d077f8a9be8 --- /dev/null +++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/free_alias.rs @@ -0,0 +1,37 @@ +//! Computes a normalizes-to (projection) goal for inherent associated types, +//! `#![feature(lazy_type_alias)]` and `#![feature(type_alias_impl_trait)]`. +//! +//! Since a free alias is never ambiguous, this just computes the `type_of` of +//! the alias and registers the where-clauses of the type alias. + +use rustc_type_ir::{self as ty, Interner}; + +use crate::delegate::SolverDelegate; +use crate::solve::{Certainty, EvalCtxt, Goal, GoalSource, QueryResult}; + +impl EvalCtxt<'_, D> +where + D: SolverDelegate, + I: Interner, +{ + pub(super) fn normalize_free_alias( + &mut self, + goal: Goal>, + ) -> QueryResult { + let cx = self.cx(); + let free_ty = goal.predicate.alias; + + // Check where clauses + self.add_goals( + GoalSource::Misc, + cx.predicates_of(free_ty.def_id) + .iter_instantiated(cx, free_ty.args) + .map(|pred| goal.with(cx, pred)), + ); + + let actual = cx.type_of(free_ty.def_id).instantiate(cx, free_ty.args); + self.instantiate_normalizes_to_term(goal, actual.into()); + + self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) + } +} diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs index 9466901683e..9c24d4336e2 100644 --- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs @@ -1,7 +1,7 @@ mod anon_const; +mod free_alias; mod inherent; mod opaque_types; -mod weak_types; use rustc_type_ir::fast_reject::DeepRejectCtxt; use rustc_type_ir::inherent::*; @@ -50,7 +50,7 @@ where } ty::AliasTermKind::InherentTy => self.normalize_inherent_associated_type(goal), ty::AliasTermKind::OpaqueTy => self.normalize_opaque_type(goal), - ty::AliasTermKind::WeakTy => self.normalize_weak_type(goal), + ty::AliasTermKind::FreeTy => self.normalize_free_alias(goal), ty::AliasTermKind::UnevaluatedConst => self.normalize_anon_const(goal), } } diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/weak_types.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/weak_types.rs deleted file mode 100644 index 14e68dd52b6..00000000000 --- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/weak_types.rs +++ /dev/null @@ -1,37 +0,0 @@ -//! Computes a normalizes-to (projection) goal for inherent associated types, -//! `#![feature(lazy_type_alias)]` and `#![feature(type_alias_impl_trait)]`. -//! -//! Since a weak alias is never ambiguous, this just computes the `type_of` of -//! the alias and registers the where-clauses of the type alias. - -use rustc_type_ir::{self as ty, Interner}; - -use crate::delegate::SolverDelegate; -use crate::solve::{Certainty, EvalCtxt, Goal, GoalSource, QueryResult}; - -impl EvalCtxt<'_, D> -where - D: SolverDelegate, - I: Interner, -{ - pub(super) fn normalize_weak_type( - &mut self, - goal: Goal>, - ) -> QueryResult { - let cx = self.cx(); - let weak_ty = goal.predicate.alias; - - // Check where clauses - self.add_goals( - GoalSource::Misc, - cx.predicates_of(weak_ty.def_id) - .iter_instantiated(cx, weak_ty.args) - .map(|pred| goal.with(cx, pred)), - ); - - let actual = cx.type_of(weak_ty.def_id).instantiate(cx, weak_ty.args); - self.instantiate_normalizes_to_term(goal, actual.into()); - - self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) - } -} diff --git a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs index 827853be280..788e23ba82a 100644 --- a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs +++ b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs @@ -1153,7 +1153,7 @@ where ty::Dynamic(..) | ty::Param(..) | ty::Foreign(..) - | ty::Alias(ty::Projection | ty::Weak | ty::Inherent, ..) + | ty::Alias(ty::Projection | ty::Free | ty::Inherent, ..) | ty::Placeholder(..) => Some(Err(NoSolution)), ty::Infer(_) | ty::Bound(_, _) => panic!("unexpected type `{self_ty:?}`"), diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index c7bab828659..48e29c823a2 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -213,7 +213,7 @@ where } } } - ty::Alias(kind @ (ty::Inherent | ty::Weak | ty::Projection), data) => { + ty::Alias(kind @ (ty::Inherent | ty::Free | ty::Projection), data) => { if self.def_id_visitor.skip_assoc_tys() { // Visitors searching for minimal visibility/reachability want to // conservatively approximate associated types like `Type::Alias` @@ -227,7 +227,7 @@ where data.def_id, match kind { ty::Inherent | ty::Projection => "associated type", - ty::Weak => "type alias", + ty::Free => "type alias", ty::Opaque => unreachable!(), }, &LazyDefPathStr { def_id: data.def_id, tcx }, diff --git a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs index a757329bcf2..cc88df78470 100644 --- a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs +++ b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs @@ -16,7 +16,7 @@ impl<'tcx> Stable<'tcx> for ty::AliasTyKind { ty::Projection => stable_mir::ty::AliasKind::Projection, ty::Inherent => stable_mir::ty::AliasKind::Inherent, ty::Opaque => stable_mir::ty::AliasKind::Opaque, - ty::Weak => stable_mir::ty::AliasKind::Weak, + ty::Free => stable_mir::ty::AliasKind::Free, } } } diff --git a/compiler/rustc_smir/src/stable_mir/ty.rs b/compiler/rustc_smir/src/stable_mir/ty.rs index 4b153007bd8..215519fa7fc 100644 --- a/compiler/rustc_smir/src/stable_mir/ty.rs +++ b/compiler/rustc_smir/src/stable_mir/ty.rs @@ -1026,7 +1026,7 @@ pub enum AliasKind { Projection, Inherent, Opaque, - Weak, + Free, } #[derive(Clone, Debug, Eq, PartialEq, Serialize)] diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs index 1cf1ac5403f..242469a225a 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs @@ -707,7 +707,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { ty::Projection | ty::Inherent => { format!("the associated type `{p}`") } - ty::Weak => format!("the type alias `{p}`"), + ty::Free => format!("the type alias `{p}`"), ty::Opaque => format!("the opaque type `{p}`"), }, }; diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs index df6e8fc4503..54544a90226 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs @@ -1682,7 +1682,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { ty::Alias(ty::Projection, ..) => Some(12), ty::Alias(ty::Inherent, ..) => Some(13), ty::Alias(ty::Opaque, ..) => Some(14), - ty::Alias(ty::Weak, ..) => Some(15), + ty::Alias(ty::Free, ..) => Some(15), ty::Never => Some(16), ty::Adt(..) => Some(17), ty::Coroutine(..) => Some(18), diff --git a/compiler/rustc_trait_selection/src/traits/normalize.rs b/compiler/rustc_trait_selection/src/traits/normalize.rs index 7551ac5aa97..d38ddbc825c 100644 --- a/compiler/rustc_trait_selection/src/traits/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/normalize.rs @@ -333,7 +333,7 @@ impl<'a, 'b, 'tcx> TypeFolder> for AssocTypeNormalizer<'a, 'b, 'tcx ); normalized_ty } - ty::Weak => { + ty::Free => { let recursion_limit = self.cx().recursion_limit(); if !recursion_limit.value_within_limit(self.depth) { self.selcx.infcx.err_ctxt().report_overflow_error( diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index 99fa791b375..de4979cc1ff 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -468,7 +468,7 @@ fn normalize_to_error<'a, 'tcx>( ty::AliasTermKind::ProjectionTy | ty::AliasTermKind::InherentTy | ty::AliasTermKind::OpaqueTy - | ty::AliasTermKind::WeakTy => selcx.infcx.next_ty_var(cause.span).into(), + | ty::AliasTermKind::FreeTy => selcx.infcx.next_ty_var(cause.span).into(), ty::AliasTermKind::UnevaluatedConst | ty::AliasTermKind::ProjectionConst => { selcx.infcx.next_const_var(cause.span).into() } diff --git a/compiler/rustc_trait_selection/src/traits/query/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/normalize.rs index 507932699c7..a54eb80fedc 100644 --- a/compiler/rustc_trait_selection/src/traits/query/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/query/normalize.rs @@ -253,7 +253,7 @@ impl<'a, 'tcx> FallibleTypeFolder> for QueryNormalizer<'a, 'tcx> { } } - ty::Projection | ty::Inherent | ty::Weak => { + ty::Projection | ty::Inherent | ty::Free => { // See note in `rustc_trait_selection::traits::project` let infcx = self.infcx; @@ -275,7 +275,7 @@ impl<'a, 'tcx> FallibleTypeFolder> for QueryNormalizer<'a, 'tcx> { debug!("QueryNormalizer: orig_values = {:#?}", orig_values); let result = match kind { ty::Projection => tcx.normalize_canonicalized_projection_ty(c_data), - ty::Weak => tcx.normalize_canonicalized_weak_ty(c_data), + ty::Free => tcx.normalize_canonicalized_free_alias(c_data), ty::Inherent => tcx.normalize_canonicalized_inherent_projection_ty(c_data), kind => unreachable!("did not expect {kind:?} due to match arm above"), }?; @@ -313,10 +313,10 @@ impl<'a, 'tcx> FallibleTypeFolder> for QueryNormalizer<'a, 'tcx> { }; // `tcx.normalize_canonicalized_projection_ty` may normalize to a type that // still has unevaluated consts, so keep normalizing here if that's the case. - // Similarly, `tcx.normalize_canonicalized_weak_ty` will only unwrap one layer + // Similarly, `tcx.normalize_canonicalized_free_alias` will only unwrap one layer // of type and we need to continue folding it to reveal the TAIT behind it. if res != ty - && (res.has_type_flags(ty::TypeFlags::HAS_CT_PROJECTION) || kind == ty::Weak) + && (res.has_type_flags(ty::TypeFlags::HAS_CT_PROJECTION) || kind == ty::Free) { res.try_fold_with(self)? } else { 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 cf6d2bc151f..7a106796e2d 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -730,7 +730,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } } ty::Param(..) - | ty::Alias(ty::Projection | ty::Inherent | ty::Weak, ..) + | ty::Alias(ty::Projection | ty::Inherent | ty::Free, ..) | ty::Placeholder(..) | ty::Bound(..) => { // In these cases, we don't know what the actual diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index c7ce13c8014..5309c05e73d 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -2323,7 +2323,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> { ty::Placeholder(..) | ty::Dynamic(..) | ty::Param(..) - | ty::Alias(ty::Projection | ty::Inherent | ty::Weak, ..) + | ty::Alias(ty::Projection | ty::Inherent | ty::Free, ..) | ty::Bound(..) | ty::Infer(ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => { bug!("asked to assemble constituent types of unexpected type: {:?}", t); diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index 54b6c22b2d8..8315564b556 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -756,7 +756,7 @@ impl<'a, 'tcx> TypeVisitor> for WfPredicates<'a, 'tcx> { // Simple cases that are WF if their type args are WF. } - ty::Alias(ty::Projection | ty::Opaque | ty::Weak, data) => { + ty::Alias(ty::Projection | ty::Opaque | ty::Free, data) => { let obligations = self.nominal_obligations(data.def_id, data.args); self.out.extend(obligations); } diff --git a/compiler/rustc_traits/src/normalize_projection_ty.rs b/compiler/rustc_traits/src/normalize_projection_ty.rs index 4c2b7e4769a..14a92ebb9f9 100644 --- a/compiler/rustc_traits/src/normalize_projection_ty.rs +++ b/compiler/rustc_traits/src/normalize_projection_ty.rs @@ -13,7 +13,7 @@ use tracing::debug; pub(crate) fn provide(p: &mut Providers) { *p = Providers { normalize_canonicalized_projection_ty, - normalize_canonicalized_weak_ty, + normalize_canonicalized_free_alias, normalize_canonicalized_inherent_projection_ty, ..*p }; @@ -63,11 +63,11 @@ fn normalize_canonicalized_projection_ty<'tcx>( ) } -fn normalize_canonicalized_weak_ty<'tcx>( +fn normalize_canonicalized_free_alias<'tcx>( tcx: TyCtxt<'tcx>, goal: CanonicalAliasGoal<'tcx>, ) -> Result<&'tcx Canonical<'tcx, QueryResponse<'tcx, NormalizationResult<'tcx>>>, NoSolution> { - debug!("normalize_canonicalized_weak_ty(goal={:#?})", goal); + debug!("normalize_canonicalized_free_alias(goal={:#?})", goal); tcx.infer_ctxt().enter_canonical_trait_query( &goal, diff --git a/compiler/rustc_ty_utils/src/opaque_types.rs b/compiler/rustc_ty_utils/src/opaque_types.rs index cd730aeeea9..841f602d985 100644 --- a/compiler/rustc_ty_utils/src/opaque_types.rs +++ b/compiler/rustc_ty_utils/src/opaque_types.rs @@ -223,7 +223,7 @@ impl<'tcx> TypeVisitor> for OpaqueTypeCollector<'tcx> { } // Skips type aliases, as they are meant to be transparent. // FIXME(type_alias_impl_trait): can we require mentioning nested type aliases explicitly? - ty::Alias(ty::Weak, alias_ty) if alias_ty.def_id.is_local() => { + ty::Alias(ty::Free, alias_ty) if alias_ty.def_id.is_local() => { self.tcx .type_of(alias_ty.def_id) .instantiate(self.tcx, alias_ty.args) diff --git a/compiler/rustc_type_ir/src/flags.rs b/compiler/rustc_type_ir/src/flags.rs index e9d3a149a73..4eead83c113 100644 --- a/compiler/rustc_type_ir/src/flags.rs +++ b/compiler/rustc_type_ir/src/flags.rs @@ -75,8 +75,8 @@ bitflags::bitflags! { /// Does this have `Projection`? const HAS_TY_PROJECTION = 1 << 10; - /// Does this have `Weak`? - const HAS_TY_WEAK = 1 << 11; + /// Does this have `Free` aliases? + const HAS_TY_FREE_ALIAS = 1 << 11; /// Does this have `Opaque`? const HAS_TY_OPAQUE = 1 << 12; /// Does this have `Inherent`? @@ -88,7 +88,7 @@ bitflags::bitflags! { /// /// Rephrased, could this term be normalized further? const HAS_ALIAS = TypeFlags::HAS_TY_PROJECTION.bits() - | TypeFlags::HAS_TY_WEAK.bits() + | TypeFlags::HAS_TY_FREE_ALIAS.bits() | TypeFlags::HAS_TY_OPAQUE.bits() | TypeFlags::HAS_TY_INHERENT.bits() | TypeFlags::HAS_CT_PROJECTION.bits(); @@ -275,7 +275,7 @@ impl FlagComputation { ty::Alias(kind, data) => { self.add_flags(match kind { ty::Projection => TypeFlags::HAS_TY_PROJECTION, - ty::Weak => TypeFlags::HAS_TY_WEAK, + ty::Free => TypeFlags::HAS_TY_FREE_ALIAS, ty::Opaque => TypeFlags::HAS_TY_OPAQUE, ty::Inherent => TypeFlags::HAS_TY_INHERENT, }); diff --git a/compiler/rustc_type_ir/src/predicate.rs b/compiler/rustc_type_ir/src/predicate.rs index 8e10636ff65..0411c5c2325 100644 --- a/compiler/rustc_type_ir/src/predicate.rs +++ b/compiler/rustc_type_ir/src/predicate.rs @@ -470,10 +470,10 @@ pub enum AliasTermKind { /// An opaque type (usually from `impl Trait` in type aliases or function return types) /// Can only be normalized away in PostAnalysis mode or its defining scope. OpaqueTy, - /// A type alias that actually checks its trait bounds. + /// A free type alias that actually checks its trait bounds. /// Currently only used if the type alias references opaque types. /// Can always be normalized away. - WeakTy, + FreeTy, /// An unevaluated const coming from a generic const expression. UnevaluatedConst, /// An unevaluated const coming from an associated const. @@ -487,7 +487,7 @@ impl AliasTermKind { AliasTermKind::ProjectionConst => "associated const", AliasTermKind::InherentTy => "inherent associated type", AliasTermKind::OpaqueTy => "opaque type", - AliasTermKind::WeakTy => "type alias", + AliasTermKind::FreeTy => "type alias", AliasTermKind::UnevaluatedConst => "unevaluated constant", } } @@ -498,7 +498,7 @@ impl From for AliasTermKind { match value { ty::Projection => AliasTermKind::ProjectionTy, ty::Opaque => AliasTermKind::OpaqueTy, - ty::Weak => AliasTermKind::WeakTy, + ty::Free => AliasTermKind::FreeTy, ty::Inherent => AliasTermKind::InherentTy, } } @@ -565,7 +565,7 @@ impl AliasTerm { AliasTermKind::ProjectionTy | AliasTermKind::InherentTy | AliasTermKind::OpaqueTy - | AliasTermKind::WeakTy => {} + | AliasTermKind::FreeTy => {} AliasTermKind::UnevaluatedConst | AliasTermKind::ProjectionConst => { panic!("Cannot turn `UnevaluatedConst` into `AliasTy`") } @@ -597,9 +597,9 @@ impl AliasTerm { ty::AliasTy { def_id: self.def_id, args: self.args, _use_alias_ty_new_instead: () }, ) .into(), - AliasTermKind::WeakTy => Ty::new_alias( + AliasTermKind::FreeTy => Ty::new_alias( interner, - ty::AliasTyKind::Weak, + ty::AliasTyKind::Free, ty::AliasTy { def_id: self.def_id, args: self.args, _use_alias_ty_new_instead: () }, ) .into(), diff --git a/compiler/rustc_type_ir/src/relate.rs b/compiler/rustc_type_ir/src/relate.rs index d065384b58e..c80a567117c 100644 --- a/compiler/rustc_type_ir/src/relate.rs +++ b/compiler/rustc_type_ir/src/relate.rs @@ -273,7 +273,7 @@ impl Relate for ty::AliasTerm { false, // do not fetch `type_of(a_def_id)`, as it will cause a cycle )?, ty::AliasTermKind::ProjectionTy - | ty::AliasTermKind::WeakTy + | ty::AliasTermKind::FreeTy | ty::AliasTermKind::InherentTy | ty::AliasTermKind::UnevaluatedConst | ty::AliasTermKind::ProjectionConst => { diff --git a/compiler/rustc_type_ir/src/ty_kind.rs b/compiler/rustc_type_ir/src/ty_kind.rs index 753a72a051a..21adbffc027 100644 --- a/compiler/rustc_type_ir/src/ty_kind.rs +++ b/compiler/rustc_type_ir/src/ty_kind.rs @@ -54,7 +54,7 @@ pub enum AliasTyKind { /// A type alias that actually checks its trait bounds. /// Currently only used if the type alias references opaque types. /// Can always be normalized away. - Weak, + Free, } impl AliasTyKind { @@ -63,7 +63,7 @@ impl AliasTyKind { AliasTyKind::Projection => "associated type", AliasTyKind::Inherent => "inherent associated type", AliasTyKind::Opaque => "opaque type", - AliasTyKind::Weak => "type alias", + AliasTyKind::Free => "type alias", } } } @@ -223,7 +223,7 @@ pub enum TyKind { /// A tuple type. For example, `(i32, bool)`. Tuple(I::Tys), - /// A projection, opaque type, weak type alias, or inherent associated type. + /// A projection, opaque type, free 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(AliasTyKind, AliasTy), diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 6ecb67c776c..622a410837b 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -2213,9 +2213,9 @@ pub(crate) fn clean_middle_ty<'tcx>( })) } - ty::Alias(ty::Weak, data) => { + ty::Alias(ty::Free, data) => { if cx.tcx.features().lazy_type_alias() { - // Weak type alias `data` represents the `type X` in `type X = Y`. If we need `Y`, + // Free type alias `data` represents the `type X` in `type X = Y`. If we need `Y`, // we need to use `type_of`. let path = clean_middle_path( cx, diff --git a/src/tools/clippy/clippy_lints/src/dereference.rs b/src/tools/clippy/clippy_lints/src/dereference.rs index 7da5a530eaa..5edb5c23570 100644 --- a/src/tools/clippy/clippy_lints/src/dereference.rs +++ b/src/tools/clippy/clippy_lints/src/dereference.rs @@ -853,7 +853,7 @@ impl TyCoercionStability { continue; }, ty::Param(_) if for_return => Self::Deref, - ty::Alias(ty::Weak | ty::Inherent, _) => unreachable!("should have been normalized away above"), + ty::Alias(ty::Free | ty::Inherent, _) => unreachable!("should have been normalized away above"), ty::Alias(ty::Projection, _) if !for_return && ty.has_non_region_param() => Self::Reborrow, ty::Infer(_) | ty::Error(_) diff --git a/src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs b/src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs index 67537a251da..1f142bc3ba6 100644 --- a/src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs +++ b/src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs @@ -197,7 +197,7 @@ fn fn_inputs_has_impl_trait_ty(cx: &LateContext<'_>, def_id: LocalDefId) -> bool inputs.iter().any(|input| { matches!( input.kind(), - ty::Alias(ty::AliasTyKind::Weak, alias_ty) if cx.tcx.type_of(alias_ty.def_id).skip_binder().is_impl_trait() + ty::Alias(ty::AliasTyKind::Free, alias_ty) if cx.tcx.type_of(alias_ty.def_id).skip_binder().is_impl_trait() ) }) } diff --git a/tests/ui/lazy-type-alias/extern-crate-has-eager-type-aliases.rs b/tests/ui/lazy-type-alias/extern-crate-has-eager-type-aliases.rs index efd77639198..33846987760 100644 --- a/tests/ui/lazy-type-alias/extern-crate-has-eager-type-aliases.rs +++ b/tests/ui/lazy-type-alias/extern-crate-has-eager-type-aliases.rs @@ -9,9 +9,9 @@ #![allow(incomplete_features)] // This used to crash when we were computing the variances of `Struct` since we would convert -// `eager::Alias` to a weak projection due to the presence of `#![feature(lazy_type_alias)]` in +// `eager::Alias` to a weak alias due to the presence of `#![feature(lazy_type_alias)]` in // this (!) crate and subsequently attempt to obtain the variances of the type alias associated with -// the weak projection which would panic because we don't compute this information for eager type +// the weak alias which would panic because we don't compute this information for eager type // aliases at all. struct Struct(eager::Alias); -- cgit 1.4.1-3-g733a5 From 37049558e43e72fa3890aa3f7c23e5f00414444c Mon Sep 17 00:00:00 2001 From: The Miri Cronjob Bot Date: Fri, 25 Apr 2025 04:54:29 +0000 Subject: Preparing for merge from rustc --- src/tools/miri/rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/tools') diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version index 5be53f47668..46e045ac769 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -7f695232a80fa1833e2282f2577c5e1ff066bf39 +847e3ee6b0e614937eee4e6d8f61094411eadcc0 -- cgit 1.4.1-3-g733a5 From 673c879abb7f3b05e25f0da5654e2a484abc17c0 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 25 Apr 2025 12:18:27 +0200 Subject: avoid an unnecessary transmute --- src/tools/miri/bench-cargo-miri/mse/src/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/tools') diff --git a/src/tools/miri/bench-cargo-miri/mse/src/main.rs b/src/tools/miri/bench-cargo-miri/mse/src/main.rs index 06d5487d1d4..69c7c39cdd7 100644 --- a/src/tools/miri/bench-cargo-miri/mse/src/main.rs +++ b/src/tools/miri/bench-cargo-miri/mse/src/main.rs @@ -13,7 +13,7 @@ fn read_i16(buffer: &[u8], index: usize) -> i16 { const SIZE: usize = size_of::(); let mut bytes: [u8; SIZE] = [0u8; SIZE]; bytes.copy_from_slice(&buffer[(index * SIZE)..(index * SIZE + SIZE)]); - unsafe { std::mem::transmute(bytes) } + i16::from_ne_bytes(bytes) } fn mse(samples: usize, frame_buf: &[i16], buf_ref: &[u8]) -> f64 { -- cgit 1.4.1-3-g733a5 From 5980c8ca18aaa976af672825a8bf172abfd782a3 Mon Sep 17 00:00:00 2001 From: The Miri Cronjob Bot Date: Sat, 26 Apr 2025 04:52:46 +0000 Subject: Preparing for merge from rustc --- src/tools/miri/rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/tools') diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version index 46e045ac769..1ecaf8675c2 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -847e3ee6b0e614937eee4e6d8f61094411eadcc0 +555e1d0386f024a8359645c3217f4b3eae9be042 -- cgit 1.4.1-3-g733a5 From bffb7608ce727d61cb1d9d3bb58d5461375f59a5 Mon Sep 17 00:00:00 2001 From: yuk1ty Date: Sun, 20 Apr 2025 10:51:19 +0900 Subject: Fix error message for static references or mutable references --- compiler/rustc_lint/messages.ftl | 2 +- compiler/rustc_lint/src/static_mut_refs.rs | 2 +- .../ui/checked_unwrap/simple_conditionals.stderr | 2 +- .../borrowck-unsafe-static-mutable-borrows.rs | 2 +- .../borrowck-unsafe-static-mutable-borrows.stderr | 2 +- tests/ui/consts/const_let_assign2.rs | 2 +- tests/ui/consts/const_let_assign2.stderr | 2 +- tests/ui/issues/issue-39367.rs | 2 +- tests/ui/issues/issue-39367.stderr | 2 +- tests/ui/lint/static-mut-refs.e2021.stderr | 24 +++++------ tests/ui/lint/static-mut-refs.e2024.stderr | 24 +++++------ tests/ui/lint/static-mut-refs.rs | 48 +++++++++++----------- ...k-thread-local-static-mut-borrow-outlives-fn.rs | 2 +- ...read-local-static-mut-borrow-outlives-fn.stderr | 2 +- tests/ui/statics/issue-15261.rs | 3 +- tests/ui/statics/issue-15261.stderr | 4 +- tests/ui/statics/static-mut-shared-parens.rs | 7 ++-- tests/ui/statics/static-mut-shared-parens.stderr | 16 ++++---- tests/ui/statics/static-mut-xc.rs | 14 +++---- tests/ui/statics/static-mut-xc.stderr | 14 +++---- tests/ui/statics/static-recursive.rs | 4 +- tests/ui/statics/static-recursive.stderr | 4 +- 22 files changed, 91 insertions(+), 93 deletions(-) (limited to 'src/tools') diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl index 60c183bd56b..9025c41240b 100644 --- a/compiler/rustc_lint/messages.ftl +++ b/compiler/rustc_lint/messages.ftl @@ -757,7 +757,7 @@ lint_single_use_lifetime = lifetime parameter `{$ident}` only used once lint_span_use_eq_ctxt = use `.eq_ctxt()` instead of `.ctxt() == .ctxt()` -lint_static_mut_refs_lint = creating a {$shared_label}reference to mutable static is discouraged +lint_static_mut_refs_lint = creating a {$shared_label}reference to mutable static .label = {$shared_label}reference to mutable static .suggestion = use `&raw const` instead to create a raw pointer .suggestion_mut = use `&raw mut` instead to create a raw pointer diff --git a/compiler/rustc_lint/src/static_mut_refs.rs b/compiler/rustc_lint/src/static_mut_refs.rs index 50021157dda..4dda3c7951b 100644 --- a/compiler/rustc_lint/src/static_mut_refs.rs +++ b/compiler/rustc_lint/src/static_mut_refs.rs @@ -51,7 +51,7 @@ declare_lint! { /// This lint is "warn" by default on editions up to 2021, in 2024 is "deny". pub STATIC_MUT_REFS, Warn, - "shared references or mutable references of mutable static is discouraged", + "creating a shared reference to mutable static", @future_incompatible = FutureIncompatibleInfo { reason: FutureIncompatibilityReason::EditionError(Edition::Edition2024), reference: "", diff --git a/src/tools/clippy/tests/ui/checked_unwrap/simple_conditionals.stderr b/src/tools/clippy/tests/ui/checked_unwrap/simple_conditionals.stderr index bdac1e42309..ad3c420270c 100644 --- a/src/tools/clippy/tests/ui/checked_unwrap/simple_conditionals.stderr +++ b/src/tools/clippy/tests/ui/checked_unwrap/simple_conditionals.stderr @@ -236,7 +236,7 @@ LL | if result.is_ok() { LL | result.as_mut().unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^ -error: creating a shared reference to mutable static is discouraged +error: creating a shared reference to mutable static --> tests/ui/checked_unwrap/simple_conditionals.rs:183:12 | LL | if X.is_some() { diff --git a/tests/ui/borrowck/borrowck-unsafe-static-mutable-borrows.rs b/tests/ui/borrowck/borrowck-unsafe-static-mutable-borrows.rs index b09c96ada8a..5106ba6c86c 100644 --- a/tests/ui/borrowck/borrowck-unsafe-static-mutable-borrows.rs +++ b/tests/ui/borrowck/borrowck-unsafe-static-mutable-borrows.rs @@ -17,7 +17,7 @@ impl Foo { fn main() { unsafe { let sfoo: *mut Foo = &mut SFOO; - //~^ WARN mutable reference to mutable static is discouraged [static_mut_refs] + //~^ WARN mutable reference to mutable static [static_mut_refs] let x = (*sfoo).x(); (*sfoo).x[1] += 1; *x += 1; diff --git a/tests/ui/borrowck/borrowck-unsafe-static-mutable-borrows.stderr b/tests/ui/borrowck/borrowck-unsafe-static-mutable-borrows.stderr index a392177ffe2..4e19fd81735 100644 --- a/tests/ui/borrowck/borrowck-unsafe-static-mutable-borrows.stderr +++ b/tests/ui/borrowck/borrowck-unsafe-static-mutable-borrows.stderr @@ -1,4 +1,4 @@ -warning: creating a mutable reference to mutable static is discouraged +warning: creating a mutable reference to mutable static --> $DIR/borrowck-unsafe-static-mutable-borrows.rs:19:30 | LL | let sfoo: *mut Foo = &mut SFOO; diff --git a/tests/ui/consts/const_let_assign2.rs b/tests/ui/consts/const_let_assign2.rs index e8ebba7b208..5349ae31bb4 100644 --- a/tests/ui/consts/const_let_assign2.rs +++ b/tests/ui/consts/const_let_assign2.rs @@ -16,7 +16,7 @@ static mut BB: AA = AA::new(); fn main() { let ptr = unsafe { &mut BB }; - //~^ WARN mutable reference to mutable static is discouraged [static_mut_refs] + //~^ WARN mutable reference to mutable static [static_mut_refs] for a in ptr.data.iter() { println!("{}", a); } diff --git a/tests/ui/consts/const_let_assign2.stderr b/tests/ui/consts/const_let_assign2.stderr index 0d76f142d17..1bb560437b6 100644 --- a/tests/ui/consts/const_let_assign2.stderr +++ b/tests/ui/consts/const_let_assign2.stderr @@ -1,4 +1,4 @@ -warning: creating a mutable reference to mutable static is discouraged +warning: creating a mutable reference to mutable static --> $DIR/const_let_assign2.rs:18:24 | LL | let ptr = unsafe { &mut BB }; diff --git a/tests/ui/issues/issue-39367.rs b/tests/ui/issues/issue-39367.rs index 937d6c4b9e0..68b4d28aae3 100644 --- a/tests/ui/issues/issue-39367.rs +++ b/tests/ui/issues/issue-39367.rs @@ -20,7 +20,7 @@ fn arena() -> &'static ArenaSet> { static mut ONCE: Once = Once::new(); ONCE.call_once(|| { - //~^ WARN creating a shared reference to mutable static is discouraged [static_mut_refs] + //~^ WARN creating a shared reference to mutable static [static_mut_refs] DATA = transmute ::>>, *const ArenaSet>> (Box::new(__static_ref_initialize())); diff --git a/tests/ui/issues/issue-39367.stderr b/tests/ui/issues/issue-39367.stderr index 333c9f9634a..df21c09983e 100644 --- a/tests/ui/issues/issue-39367.stderr +++ b/tests/ui/issues/issue-39367.stderr @@ -1,4 +1,4 @@ -warning: creating a shared reference to mutable static is discouraged +warning: creating a shared reference to mutable static --> $DIR/issue-39367.rs:22:13 | LL | / ONCE.call_once(|| { diff --git a/tests/ui/lint/static-mut-refs.e2021.stderr b/tests/ui/lint/static-mut-refs.e2021.stderr index 00a2ca99f24..320e0cee8e8 100644 --- a/tests/ui/lint/static-mut-refs.e2021.stderr +++ b/tests/ui/lint/static-mut-refs.e2021.stderr @@ -1,4 +1,4 @@ -warning: creating a shared reference to mutable static is discouraged +warning: creating a shared reference to mutable static --> $DIR/static-mut-refs.rs:38:18 | LL | let _y = &X; @@ -12,7 +12,7 @@ help: use `&raw const` instead to create a raw pointer LL | let _y = &raw const X; | +++++++++ -warning: creating a mutable reference to mutable static is discouraged +warning: creating a mutable reference to mutable static --> $DIR/static-mut-refs.rs:42:18 | LL | let _y = &mut X; @@ -25,7 +25,7 @@ help: use `&raw mut` instead to create a raw pointer LL | let _y = &raw mut X; | +++ -warning: creating a shared reference to mutable static is discouraged +warning: creating a shared reference to mutable static --> $DIR/static-mut-refs.rs:50:22 | LL | let ref _a = X; @@ -34,7 +34,7 @@ LL | let ref _a = X; = note: for more information, see = note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives -warning: creating a shared reference to mutable static is discouraged +warning: creating a shared reference to mutable static --> $DIR/static-mut-refs.rs:54:25 | LL | let (_b, _c) = (&X, &Y); @@ -47,7 +47,7 @@ help: use `&raw const` instead to create a raw pointer LL | let (_b, _c) = (&raw const X, &Y); | +++++++++ -warning: creating a shared reference to mutable static is discouraged +warning: creating a shared reference to mutable static --> $DIR/static-mut-refs.rs:54:29 | LL | let (_b, _c) = (&X, &Y); @@ -60,7 +60,7 @@ help: use `&raw const` instead to create a raw pointer LL | let (_b, _c) = (&X, &raw const Y); | +++++++++ -warning: creating a shared reference to mutable static is discouraged +warning: creating a shared reference to mutable static --> $DIR/static-mut-refs.rs:60:13 | LL | foo(&X); @@ -73,7 +73,7 @@ help: use `&raw const` instead to create a raw pointer LL | foo(&raw const X); | +++++++++ -warning: creating a shared reference to mutable static is discouraged +warning: creating a shared reference to mutable static --> $DIR/static-mut-refs.rs:66:17 | LL | let _ = Z.len(); @@ -82,7 +82,7 @@ LL | let _ = Z.len(); = note: for more information, see = note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives -warning: creating a shared reference to mutable static is discouraged +warning: creating a shared reference to mutable static --> $DIR/static-mut-refs.rs:72:33 | LL | let _ = format!("{:?}", Z); @@ -91,7 +91,7 @@ LL | let _ = format!("{:?}", Z); = note: for more information, see = note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives -warning: creating a shared reference to mutable static is discouraged +warning: creating a shared reference to mutable static --> $DIR/static-mut-refs.rs:76:18 | LL | let _v = &A.value; @@ -104,7 +104,7 @@ help: use `&raw const` instead to create a raw pointer LL | let _v = &raw const A.value; | +++++++++ -warning: creating a shared reference to mutable static is discouraged +warning: creating a shared reference to mutable static --> $DIR/static-mut-refs.rs:80:18 | LL | let _s = &A.s.value; @@ -117,7 +117,7 @@ help: use `&raw const` instead to create a raw pointer LL | let _s = &raw const A.s.value; | +++++++++ -warning: creating a shared reference to mutable static is discouraged +warning: creating a shared reference to mutable static --> $DIR/static-mut-refs.rs:84:22 | LL | let ref _v = A.value; @@ -126,7 +126,7 @@ LL | let ref _v = A.value; = note: for more information, see = note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives -warning: creating a mutable reference to mutable static is discouraged +warning: creating a mutable reference to mutable static --> $DIR/static-mut-refs.rs:14:14 | LL | &mut ($x.0) diff --git a/tests/ui/lint/static-mut-refs.e2024.stderr b/tests/ui/lint/static-mut-refs.e2024.stderr index ff41f316250..bf7ffc62ce1 100644 --- a/tests/ui/lint/static-mut-refs.e2024.stderr +++ b/tests/ui/lint/static-mut-refs.e2024.stderr @@ -1,4 +1,4 @@ -error: creating a shared reference to mutable static is discouraged +error: creating a shared reference to mutable static --> $DIR/static-mut-refs.rs:38:18 | LL | let _y = &X; @@ -12,7 +12,7 @@ help: use `&raw const` instead to create a raw pointer LL | let _y = &raw const X; | +++++++++ -error: creating a mutable reference to mutable static is discouraged +error: creating a mutable reference to mutable static --> $DIR/static-mut-refs.rs:42:18 | LL | let _y = &mut X; @@ -25,7 +25,7 @@ help: use `&raw mut` instead to create a raw pointer LL | let _y = &raw mut X; | +++ -error: creating a shared reference to mutable static is discouraged +error: creating a shared reference to mutable static --> $DIR/static-mut-refs.rs:50:22 | LL | let ref _a = X; @@ -34,7 +34,7 @@ LL | let ref _a = X; = note: for more information, see = note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives -error: creating a shared reference to mutable static is discouraged +error: creating a shared reference to mutable static --> $DIR/static-mut-refs.rs:54:25 | LL | let (_b, _c) = (&X, &Y); @@ -47,7 +47,7 @@ help: use `&raw const` instead to create a raw pointer LL | let (_b, _c) = (&raw const X, &Y); | +++++++++ -error: creating a shared reference to mutable static is discouraged +error: creating a shared reference to mutable static --> $DIR/static-mut-refs.rs:54:29 | LL | let (_b, _c) = (&X, &Y); @@ -60,7 +60,7 @@ help: use `&raw const` instead to create a raw pointer LL | let (_b, _c) = (&X, &raw const Y); | +++++++++ -error: creating a shared reference to mutable static is discouraged +error: creating a shared reference to mutable static --> $DIR/static-mut-refs.rs:60:13 | LL | foo(&X); @@ -73,7 +73,7 @@ help: use `&raw const` instead to create a raw pointer LL | foo(&raw const X); | +++++++++ -error: creating a shared reference to mutable static is discouraged +error: creating a shared reference to mutable static --> $DIR/static-mut-refs.rs:66:17 | LL | let _ = Z.len(); @@ -82,7 +82,7 @@ LL | let _ = Z.len(); = note: for more information, see = note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives -error: creating a shared reference to mutable static is discouraged +error: creating a shared reference to mutable static --> $DIR/static-mut-refs.rs:72:33 | LL | let _ = format!("{:?}", Z); @@ -91,7 +91,7 @@ LL | let _ = format!("{:?}", Z); = note: for more information, see = note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives -error: creating a shared reference to mutable static is discouraged +error: creating a shared reference to mutable static --> $DIR/static-mut-refs.rs:76:18 | LL | let _v = &A.value; @@ -104,7 +104,7 @@ help: use `&raw const` instead to create a raw pointer LL | let _v = &raw const A.value; | +++++++++ -error: creating a shared reference to mutable static is discouraged +error: creating a shared reference to mutable static --> $DIR/static-mut-refs.rs:80:18 | LL | let _s = &A.s.value; @@ -117,7 +117,7 @@ help: use `&raw const` instead to create a raw pointer LL | let _s = &raw const A.s.value; | +++++++++ -error: creating a shared reference to mutable static is discouraged +error: creating a shared reference to mutable static --> $DIR/static-mut-refs.rs:84:22 | LL | let ref _v = A.value; @@ -126,7 +126,7 @@ LL | let ref _v = A.value; = note: for more information, see = note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives -error: creating a mutable reference to mutable static is discouraged +error: creating a mutable reference to mutable static --> $DIR/static-mut-refs.rs:14:14 | LL | &mut ($x.0) diff --git a/tests/ui/lint/static-mut-refs.rs b/tests/ui/lint/static-mut-refs.rs index 1040dfcae7a..d2511fb5b12 100644 --- a/tests/ui/lint/static-mut-refs.rs +++ b/tests/ui/lint/static-mut-refs.rs @@ -12,8 +12,8 @@ static mut FOO: (u32, u32) = (1, 2); macro_rules! bar { ($x:expr) => { &mut ($x.0) - //[e2021]~^ WARN creating a mutable reference to mutable static is discouraged [static_mut_refs] - //[e2024]~^^ ERROR creating a mutable reference to mutable static is discouraged [static_mut_refs] + //[e2021]~^ WARN creating a mutable reference to mutable static [static_mut_refs] + //[e2024]~^^ ERROR creating a mutable reference to mutable static [static_mut_refs] }; } @@ -36,54 +36,54 @@ fn main() { unsafe { let _y = &X; - //[e2021]~^ WARN shared reference to mutable static is discouraged [static_mut_refs] - //[e2024]~^^ ERROR shared reference to mutable static is discouraged [static_mut_refs] + //[e2021]~^ WARN shared reference to mutable static [static_mut_refs] + //[e2024]~^^ ERROR shared reference to mutable static [static_mut_refs] let _y = &mut X; - //[e2021]~^ WARN mutable reference to mutable static is discouraged [static_mut_refs] - //[e2024]~^^ ERROR mutable reference to mutable static is discouraged [static_mut_refs] + //[e2021]~^ WARN mutable reference to mutable static [static_mut_refs] + //[e2024]~^^ ERROR mutable reference to mutable static [static_mut_refs] let _z = &raw mut X; let _p = &raw const X; let ref _a = X; - //[e2021]~^ WARN shared reference to mutable static is discouraged [static_mut_refs] - //[e2024]~^^ ERROR shared reference to mutable static is discouraged [static_mut_refs] + //[e2021]~^ WARN shared reference to mutable static [static_mut_refs] + //[e2024]~^^ ERROR shared reference to mutable static [static_mut_refs] let (_b, _c) = (&X, &Y); - //[e2021]~^ WARN shared reference to mutable static is discouraged [static_mut_refs] - //[e2024]~^^ ERROR shared reference to mutable static is discouraged [static_mut_refs] - //[e2021]~^^^ WARN shared reference to mutable static is discouraged [static_mut_refs] - //[e2024]~^^^^ ERROR shared reference to mutable static is discouraged [static_mut_refs] + //[e2021]~^ WARN shared reference to mutable static [static_mut_refs] + //[e2024]~^^ ERROR shared reference to mutable static [static_mut_refs] + //[e2021]~^^^ WARN shared reference to mutable static [static_mut_refs] + //[e2024]~^^^^ ERROR shared reference to mutable static [static_mut_refs] foo(&X); - //[e2021]~^ WARN shared reference to mutable static is discouraged [static_mut_refs] - //[e2024]~^^ ERROR shared reference to mutable static is discouraged [static_mut_refs] + //[e2021]~^ WARN shared reference to mutable static [static_mut_refs] + //[e2024]~^^ ERROR shared reference to mutable static [static_mut_refs] static mut Z: &[i32; 3] = &[0, 1, 2]; let _ = Z.len(); - //[e2021]~^ WARN creating a shared reference to mutable static is discouraged [static_mut_refs] - //[e2024]~^^ ERROR creating a shared reference to mutable static is discouraged [static_mut_refs] + //[e2021]~^ WARN creating a shared reference to mutable static [static_mut_refs] + //[e2024]~^^ ERROR creating a shared reference to mutable static [static_mut_refs] let _ = Z[0]; let _ = format!("{:?}", Z); - //[e2021]~^ WARN creating a shared reference to mutable static is discouraged [static_mut_refs] - //[e2024]~^^ ERROR creating a shared reference to mutable static is discouraged [static_mut_refs] + //[e2021]~^ WARN creating a shared reference to mutable static [static_mut_refs] + //[e2024]~^^ ERROR creating a shared reference to mutable static [static_mut_refs] let _v = &A.value; - //[e2021]~^ WARN creating a shared reference to mutable static is discouraged [static_mut_refs] - //[e2024]~^^ ERROR creating a shared reference to mutable static is discouraged [static_mut_refs] + //[e2021]~^ WARN creating a shared reference to mutable static [static_mut_refs] + //[e2024]~^^ ERROR creating a shared reference to mutable static [static_mut_refs] let _s = &A.s.value; - //[e2021]~^ WARN creating a shared reference to mutable static is discouraged [static_mut_refs] - //[e2024]~^^ ERROR creating a shared reference to mutable static is discouraged [static_mut_refs] + //[e2021]~^ WARN creating a shared reference to mutable static [static_mut_refs] + //[e2024]~^^ ERROR creating a shared reference to mutable static [static_mut_refs] let ref _v = A.value; - //[e2021]~^ WARN creating a shared reference to mutable static is discouraged [static_mut_refs] - //[e2024]~^^ ERROR creating a shared reference to mutable static is discouraged [static_mut_refs] + //[e2021]~^ WARN creating a shared reference to mutable static [static_mut_refs] + //[e2024]~^^ ERROR creating a shared reference to mutable static [static_mut_refs] let _x = bar!(FOO); diff --git a/tests/ui/nll/borrowck-thread-local-static-mut-borrow-outlives-fn.rs b/tests/ui/nll/borrowck-thread-local-static-mut-borrow-outlives-fn.rs index be882085c5c..73597408d10 100644 --- a/tests/ui/nll/borrowck-thread-local-static-mut-borrow-outlives-fn.rs +++ b/tests/ui/nll/borrowck-thread-local-static-mut-borrow-outlives-fn.rs @@ -15,7 +15,7 @@ struct S1 { impl S1 { fn new(_x: u64) -> S1 { S1 { a: unsafe { &mut X1 } } - //~^ WARN mutable reference to mutable static is discouraged [static_mut_refs] + //~^ WARN mutable reference to mutable static [static_mut_refs] } } diff --git a/tests/ui/nll/borrowck-thread-local-static-mut-borrow-outlives-fn.stderr b/tests/ui/nll/borrowck-thread-local-static-mut-borrow-outlives-fn.stderr index 9dbd6769693..8268f5df236 100644 --- a/tests/ui/nll/borrowck-thread-local-static-mut-borrow-outlives-fn.stderr +++ b/tests/ui/nll/borrowck-thread-local-static-mut-borrow-outlives-fn.stderr @@ -1,4 +1,4 @@ -warning: creating a mutable reference to mutable static is discouraged +warning: creating a mutable reference to mutable static --> $DIR/borrowck-thread-local-static-mut-borrow-outlives-fn.rs:17:26 | LL | S1 { a: unsafe { &mut X1 } } diff --git a/tests/ui/statics/issue-15261.rs b/tests/ui/statics/issue-15261.rs index ed79a201488..f8c5ebaa548 100644 --- a/tests/ui/statics/issue-15261.rs +++ b/tests/ui/statics/issue-15261.rs @@ -2,10 +2,9 @@ #![allow(dead_code)] #![allow(non_upper_case_globals)] - static mut n_mut: usize = 0; static n: &'static usize = unsafe { &n_mut }; -//~^ WARN shared reference to mutable static is discouraged [static_mut_refs] +//~^ WARN shared reference to mutable static [static_mut_refs] fn main() {} diff --git a/tests/ui/statics/issue-15261.stderr b/tests/ui/statics/issue-15261.stderr index 7e6aebcbb1f..d2dd762aa66 100644 --- a/tests/ui/statics/issue-15261.stderr +++ b/tests/ui/statics/issue-15261.stderr @@ -1,5 +1,5 @@ -warning: creating a shared reference to mutable static is discouraged - --> $DIR/issue-15261.rs:8:37 +warning: creating a shared reference to mutable static + --> $DIR/issue-15261.rs:7:37 | LL | static n: &'static usize = unsafe { &n_mut }; | ^^^^^^ shared reference to mutable static diff --git a/tests/ui/statics/static-mut-shared-parens.rs b/tests/ui/statics/static-mut-shared-parens.rs index 8e58152e27a..7eda7d67d92 100644 --- a/tests/ui/statics/static-mut-shared-parens.rs +++ b/tests/ui/statics/static-mut-shared-parens.rs @@ -1,13 +1,12 @@ //Missing paren in diagnostic msg: https://github.com/rust-lang/rust/issues/131977 //@check-pass - static mut TEST: usize = 0; fn main() { let _ = unsafe { (&TEST) as *const usize }; - //~^WARN creating a shared reference to mutable static is discouraged + //~^WARN creating a shared reference to mutable static - let _ = unsafe { ((&mut TEST)) as *const usize }; - //~^WARN creating a mutable reference to mutable static is discouraged + let _ = unsafe { (&mut TEST) as *const usize }; + //~^WARN creating a mutable reference to mutable static } diff --git a/tests/ui/statics/static-mut-shared-parens.stderr b/tests/ui/statics/static-mut-shared-parens.stderr index 30a586c286a..3825e8efc42 100644 --- a/tests/ui/statics/static-mut-shared-parens.stderr +++ b/tests/ui/statics/static-mut-shared-parens.stderr @@ -1,5 +1,5 @@ -warning: creating a shared reference to mutable static is discouraged - --> $DIR/static-mut-shared-parens.rs:8:22 +warning: creating a shared reference to mutable static + --> $DIR/static-mut-shared-parens.rs:7:22 | LL | let _ = unsafe { (&TEST) as *const usize }; | ^^^^^^^ shared reference to mutable static @@ -12,18 +12,18 @@ help: use `&raw const` instead to create a raw pointer LL | let _ = unsafe { (&raw const TEST) as *const usize }; | +++++++++ -warning: creating a mutable reference to mutable static is discouraged - --> $DIR/static-mut-shared-parens.rs:11:22 +warning: creating a mutable reference to mutable static + --> $DIR/static-mut-shared-parens.rs:10:22 | -LL | let _ = unsafe { ((&mut TEST)) as *const usize }; - | ^^^^^^^^^^^^^ mutable reference to mutable static +LL | let _ = unsafe { (&mut TEST) as *const usize }; + | ^^^^^^^^^^^ mutable reference to mutable static | = note: for more information, see = note: mutable references to mutable statics are dangerous; it's undefined behavior if any other pointer to the static is used or if any other reference is created for the static while the mutable reference lives help: use `&raw mut` instead to create a raw pointer | -LL | let _ = unsafe { ((&raw mut TEST)) as *const usize }; - | +++ +LL | let _ = unsafe { (&raw mut TEST) as *const usize }; + | +++ warning: 2 warnings emitted diff --git a/tests/ui/statics/static-mut-xc.rs b/tests/ui/statics/static-mut-xc.rs index c23cc822ce7..878f5a8e0f7 100644 --- a/tests/ui/statics/static-mut-xc.rs +++ b/tests/ui/statics/static-mut-xc.rs @@ -17,23 +17,23 @@ fn static_bound_set(a: &'static mut isize) { unsafe fn run() { assert_eq!(static_mut_xc::a, 3); - //~^ WARN creating a shared reference to mutable static is discouraged [static_mut_refs] + //~^ WARN creating a shared reference to mutable static [static_mut_refs] static_mut_xc::a = 4; assert_eq!(static_mut_xc::a, 4); - //~^ WARN creating a shared reference to mutable static is discouraged [static_mut_refs] + //~^ WARN creating a shared reference to mutable static [static_mut_refs] static_mut_xc::a += 1; assert_eq!(static_mut_xc::a, 5); - //~^ WARN creating a shared reference to mutable static is discouraged [static_mut_refs] + //~^ WARN creating a shared reference to mutable static [static_mut_refs] static_mut_xc::a *= 3; assert_eq!(static_mut_xc::a, 15); - //~^ WARN creating a shared reference to mutable static is discouraged [static_mut_refs] + //~^ WARN creating a shared reference to mutable static [static_mut_refs] static_mut_xc::a = -3; assert_eq!(static_mut_xc::a, -3); - //~^ WARN creating a shared reference to mutable static is discouraged [static_mut_refs] + //~^ WARN creating a shared reference to mutable static [static_mut_refs] static_bound(&static_mut_xc::a); - //~^ WARN shared reference to mutable static is discouraged [static_mut_refs] + //~^ WARN shared reference to mutable static [static_mut_refs] static_bound_set(&mut static_mut_xc::a); - //~^ WARN mutable reference to mutable static is discouraged [static_mut_refs] + //~^ WARN mutable reference to mutable static [static_mut_refs] } pub fn main() { diff --git a/tests/ui/statics/static-mut-xc.stderr b/tests/ui/statics/static-mut-xc.stderr index 69f334a5636..2d7a0553e92 100644 --- a/tests/ui/statics/static-mut-xc.stderr +++ b/tests/ui/statics/static-mut-xc.stderr @@ -1,4 +1,4 @@ -warning: creating a shared reference to mutable static is discouraged +warning: creating a shared reference to mutable static --> $DIR/static-mut-xc.rs:19:16 | LL | assert_eq!(static_mut_xc::a, 3); @@ -8,7 +8,7 @@ LL | assert_eq!(static_mut_xc::a, 3); = note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives = note: `#[warn(static_mut_refs)]` on by default -warning: creating a shared reference to mutable static is discouraged +warning: creating a shared reference to mutable static --> $DIR/static-mut-xc.rs:22:16 | LL | assert_eq!(static_mut_xc::a, 4); @@ -17,7 +17,7 @@ LL | assert_eq!(static_mut_xc::a, 4); = note: for more information, see = note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives -warning: creating a shared reference to mutable static is discouraged +warning: creating a shared reference to mutable static --> $DIR/static-mut-xc.rs:25:16 | LL | assert_eq!(static_mut_xc::a, 5); @@ -26,7 +26,7 @@ LL | assert_eq!(static_mut_xc::a, 5); = note: for more information, see = note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives -warning: creating a shared reference to mutable static is discouraged +warning: creating a shared reference to mutable static --> $DIR/static-mut-xc.rs:28:16 | LL | assert_eq!(static_mut_xc::a, 15); @@ -35,7 +35,7 @@ LL | assert_eq!(static_mut_xc::a, 15); = note: for more information, see = note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives -warning: creating a shared reference to mutable static is discouraged +warning: creating a shared reference to mutable static --> $DIR/static-mut-xc.rs:31:16 | LL | assert_eq!(static_mut_xc::a, -3); @@ -44,7 +44,7 @@ LL | assert_eq!(static_mut_xc::a, -3); = note: for more information, see = note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives -warning: creating a shared reference to mutable static is discouraged +warning: creating a shared reference to mutable static --> $DIR/static-mut-xc.rs:33:18 | LL | static_bound(&static_mut_xc::a); @@ -57,7 +57,7 @@ help: use `&raw const` instead to create a raw pointer LL | static_bound(&raw const static_mut_xc::a); | +++++++++ -warning: creating a mutable reference to mutable static is discouraged +warning: creating a mutable reference to mutable static --> $DIR/static-mut-xc.rs:35:22 | LL | static_bound_set(&mut static_mut_xc::a); diff --git a/tests/ui/statics/static-recursive.rs b/tests/ui/statics/static-recursive.rs index da23b54d1fc..dab60dd8641 100644 --- a/tests/ui/statics/static-recursive.rs +++ b/tests/ui/statics/static-recursive.rs @@ -1,7 +1,7 @@ //@ run-pass static mut S: *const u8 = unsafe { &S as *const *const u8 as *const u8 }; -//~^ WARN shared reference to mutable static is discouraged [static_mut_refs] +//~^ WARN shared reference to mutable static [static_mut_refs] struct StaticDoubleLinked { prev: &'static StaticDoubleLinked, @@ -17,7 +17,7 @@ static L3: StaticDoubleLinked = StaticDoubleLinked { prev: &L2, next: &L1, data: pub fn main() { unsafe { assert_eq!(S, *(S as *const *const u8)); - //~^ WARN creating a shared reference to mutable static is discouraged [static_mut_refs] + //~^ WARN creating a shared reference to mutable static [static_mut_refs] } let mut test_vec = Vec::new(); diff --git a/tests/ui/statics/static-recursive.stderr b/tests/ui/statics/static-recursive.stderr index 039934dfc69..252807e2e5d 100644 --- a/tests/ui/statics/static-recursive.stderr +++ b/tests/ui/statics/static-recursive.stderr @@ -1,4 +1,4 @@ -warning: creating a shared reference to mutable static is discouraged +warning: creating a shared reference to mutable static --> $DIR/static-recursive.rs:3:36 | LL | static mut S: *const u8 = unsafe { &S as *const *const u8 as *const u8 }; @@ -12,7 +12,7 @@ help: use `&raw const` instead to create a raw pointer LL | static mut S: *const u8 = unsafe { &raw const S as *const *const u8 as *const u8 }; | +++++++++ -warning: creating a shared reference to mutable static is discouraged +warning: creating a shared reference to mutable static --> $DIR/static-recursive.rs:19:20 | LL | assert_eq!(S, *(S as *const *const u8)); -- cgit 1.4.1-3-g733a5 From 15c4e4092817ee38c8235f3189d2644e1ac511ee Mon Sep 17 00:00:00 2001 From: primoly <168267431+primoly@users.noreply.github.com> Date: Sun, 27 Apr 2025 13:49:51 +0200 Subject: `unsafe(no_mangle)` in `miri_start` examples --- src/tools/miri/README.md | 2 +- src/tools/miri/src/bin/miri.rs | 4 ++-- src/tools/miri/tests/fail/no_main.stderr | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) (limited to 'src/tools') diff --git a/src/tools/miri/README.md b/src/tools/miri/README.md index e8ea988558c..95e1770aa7b 100644 --- a/src/tools/miri/README.md +++ b/src/tools/miri/README.md @@ -489,7 +489,7 @@ Miri knows where it is supposed to start execution: ```rust #[cfg(miri)] -#[no_mangle] +#[unsafe(no_mangle)] fn miri_start(argc: isize, argv: *const *const u8) -> isize { // Call the actual start function that your project implements, based on your target's conventions. } diff --git a/src/tools/miri/src/bin/miri.rs b/src/tools/miri/src/bin/miri.rs index 4e8fe0ca8ad..8ff1c9d6ff0 100644 --- a/src/tools/miri/src/bin/miri.rs +++ b/src/tools/miri/src/bin/miri.rs @@ -106,7 +106,7 @@ fn entry_fn(tcx: TyCtxt<'_>) -> (DefId, MiriEntryFnType) { } else { tcx.dcx().fatal( "`miri_start` must have the following signature:\n\ - fn miri_start(argc: isize, argv: *const *const u8) -> isize", + fn miri_start(argc: isize, argv: *const *const u8) -> isize", ); } } else { @@ -115,7 +115,7 @@ fn entry_fn(tcx: TyCtxt<'_>) -> (DefId, MiriEntryFnType) { Alternatively, you can export a `miri_start` function:\n\ \n\ #[cfg(miri)]\n\ - #[no_mangle]\n\ + #[unsafe(no_mangle)]\n\ fn miri_start(argc: isize, argv: *const *const u8) -> isize {\ \n // Call the actual start function that your project implements, based on your target's conventions.\n\ }" diff --git a/src/tools/miri/tests/fail/no_main.stderr b/src/tools/miri/tests/fail/no_main.stderr index e9b9e5d65b1..e7f63be794f 100644 --- a/src/tools/miri/tests/fail/no_main.stderr +++ b/src/tools/miri/tests/fail/no_main.stderr @@ -2,7 +2,7 @@ error: Miri can only run programs that have a main function. Alternatively, you can export a `miri_start` function: #[cfg(miri)] - #[no_mangle] + #[unsafe(no_mangle)] fn miri_start(argc: isize, argv: *const *const u8) -> isize { // Call the actual start function that your project implements, based on your target's conventions. } -- cgit 1.4.1-3-g733a5 From b023856f29743a288727d13d0d1044b8e0d3f9f3 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 27 Feb 2025 09:46:46 +0000 Subject: Add or-patterns to pattern types --- compiler/rustc_ast/src/ast.rs | 2 + compiler/rustc_ast/src/mut_visit.rs | 1 + compiler/rustc_ast/src/visit.rs | 1 + compiler/rustc_ast_lowering/src/pat.rs | 5 + compiler/rustc_ast_pretty/src/pprust/state.rs | 11 ++ compiler/rustc_builtin_macros/src/pattern_type.rs | 16 ++- .../rustc_const_eval/src/interpret/intrinsics.rs | 15 ++- .../rustc_const_eval/src/interpret/validity.rs | 8 ++ compiler/rustc_hir/src/hir.rs | 3 + compiler/rustc_hir/src/intravisit.rs | 1 + compiler/rustc_hir_analysis/src/collect/type_of.rs | 8 +- .../rustc_hir_analysis/src/hir_ty_lowering/mod.rs | 8 ++ .../rustc_hir_analysis/src/variance/constraints.rs | 5 + compiler/rustc_hir_pretty/src/lib.rs | 13 +++ compiler/rustc_lint/src/types.rs | 25 ++++- compiler/rustc_middle/src/ty/codec.rs | 10 ++ compiler/rustc_middle/src/ty/context.rs | 12 ++ compiler/rustc_middle/src/ty/pattern.rs | 27 +++++ compiler/rustc_middle/src/ty/relate.rs | 9 ++ compiler/rustc_middle/src/ty/structural_impls.rs | 1 + compiler/rustc_resolve/src/late.rs | 5 + compiler/rustc_smir/src/rustc_smir/convert/ty.rs | 1 + compiler/rustc_symbol_mangling/src/v0.rs | 5 + compiler/rustc_trait_selection/src/traits/wf.rs | 5 + compiler/rustc_ty_utils/src/layout.rs | 86 +++++++++++++- compiler/rustc_type_ir/src/interner.rs | 7 ++ compiler/rustc_type_ir/src/pattern.rs | 1 + compiler/rustc_type_ir/src/walk.rs | 5 + src/tools/clippy/clippy_utils/src/hir_utils.rs | 5 + src/tools/rustfmt/src/types.rs | 13 +++ tests/ui/type/pattern_types/or_patterns.rs | 45 ++++++++ tests/ui/type/pattern_types/or_patterns.stderr | 123 +++++++++++++++++++++ tests/ui/type/pattern_types/or_patterns_invalid.rs | 26 +++++ .../type/pattern_types/or_patterns_invalid.stderr | 10 ++ 34 files changed, 504 insertions(+), 14 deletions(-) create mode 100644 tests/ui/type/pattern_types/or_patterns.rs create mode 100644 tests/ui/type/pattern_types/or_patterns.stderr create mode 100644 tests/ui/type/pattern_types/or_patterns_invalid.rs create mode 100644 tests/ui/type/pattern_types/or_patterns_invalid.stderr (limited to 'src/tools') diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 8986430141b..9d216ef3dd8 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -2469,6 +2469,8 @@ pub enum TyPatKind { /// A range pattern (e.g., `1...2`, `1..2`, `1..`, `..2`, `1..=2`, `..=2`). Range(Option>, Option>, Spanned), + Or(ThinVec>), + /// Placeholder for a pattern that wasn't syntactically well formed in some way. Err(ErrorGuaranteed), } diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index 6aae2e481a5..cd2293423db 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -612,6 +612,7 @@ pub fn walk_ty_pat(vis: &mut T, ty: &mut P) { visit_opt(start, |c| vis.visit_anon_const(c)); visit_opt(end, |c| vis.visit_anon_const(c)); } + TyPatKind::Or(variants) => visit_thin_vec(variants, |p| vis.visit_ty_pat(p)), TyPatKind::Err(_) => {} } visit_lazy_tts(vis, tokens); diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index 79193fcec63..69a186c8cf1 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -608,6 +608,7 @@ pub fn walk_ty_pat<'a, V: Visitor<'a>>(visitor: &mut V, tp: &'a TyPat) -> V::Res visit_opt!(visitor, visit_anon_const, start); visit_opt!(visitor, visit_anon_const, end); } + TyPatKind::Or(variants) => walk_list!(visitor, visit_ty_pat, variants), TyPatKind::Err(_) => {} } V::Result::output() diff --git a/compiler/rustc_ast_lowering/src/pat.rs b/compiler/rustc_ast_lowering/src/pat.rs index f94d788a9b0..4a6929ef011 100644 --- a/compiler/rustc_ast_lowering/src/pat.rs +++ b/compiler/rustc_ast_lowering/src/pat.rs @@ -464,6 +464,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { ) }), ), + TyPatKind::Or(variants) => { + hir::TyPatKind::Or(self.arena.alloc_from_iter( + variants.iter().map(|pat| self.lower_ty_pat_mut(pat, base_type)), + )) + } TyPatKind::Err(guar) => hir::TyPatKind::Err(*guar), }; diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index 62a50c73855..9411237421d 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -1162,6 +1162,17 @@ impl<'a> State<'a> { self.print_expr_anon_const(end, &[]); } } + rustc_ast::TyPatKind::Or(variants) => { + let mut first = true; + for pat in variants { + if first { + first = false + } else { + self.word(" | "); + } + self.print_ty_pat(pat); + } + } rustc_ast::TyPatKind::Err(_) => { self.popen(); self.word("/*ERROR*/"); diff --git a/compiler/rustc_builtin_macros/src/pattern_type.rs b/compiler/rustc_builtin_macros/src/pattern_type.rs index aaf5b233651..3529e5525fc 100644 --- a/compiler/rustc_builtin_macros/src/pattern_type.rs +++ b/compiler/rustc_builtin_macros/src/pattern_type.rs @@ -4,6 +4,7 @@ use rustc_ast::{AnonConst, DUMMY_NODE_ID, Ty, TyPat, TyPatKind, ast, token}; use rustc_errors::PResult; use rustc_expand::base::{self, DummyResult, ExpandResult, ExtCtxt, MacroExpanderResult}; use rustc_parse::exp; +use rustc_parse::parser::{CommaRecoveryMode, RecoverColon, RecoverComma}; use rustc_span::Span; pub(crate) fn expand<'cx>( @@ -27,7 +28,17 @@ fn parse_pat_ty<'a>(cx: &mut ExtCtxt<'a>, stream: TokenStream) -> PResult<'a, (P let ty = parser.parse_ty()?; parser.expect_keyword(exp!(Is))?; - let pat = pat_to_ty_pat(cx, parser.parse_pat_no_top_alt(None, None)?.into_inner()); + let pat = pat_to_ty_pat( + cx, + parser + .parse_pat_no_top_guard( + None, + RecoverComma::No, + RecoverColon::No, + CommaRecoveryMode::EitherTupleOrPipe, + )? + .into_inner(), + ); if parser.token != token::Eof { parser.unexpected()?; @@ -47,6 +58,9 @@ fn pat_to_ty_pat(cx: &mut ExtCtxt<'_>, pat: ast::Pat) -> P { end.map(|value| P(AnonConst { id: DUMMY_NODE_ID, value })), include_end, ), + ast::PatKind::Or(variants) => TyPatKind::Or( + variants.into_iter().map(|pat| pat_to_ty_pat(cx, pat.into_inner())).collect(), + ), ast::PatKind::Err(guar) => TyPatKind::Err(guar), _ => TyPatKind::Err(cx.dcx().span_err(pat.span, "pattern not supported in pattern types")), }; diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs index 40c63f2b250..97d066ffe3f 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs @@ -61,16 +61,21 @@ pub(crate) fn eval_nullary_intrinsic<'tcx>( ensure_monomorphic_enough(tcx, tp_ty)?; ConstValue::from_u128(tcx.type_id_hash(tp_ty).as_u128()) } - sym::variant_count => match tp_ty.kind() { + sym::variant_count => match match tp_ty.kind() { + // Pattern types have the same number of variants as their base type. + // Even if we restrict e.g. which variants are valid, the variants are essentially just uninhabited. + // And `Result<(), !>` still has two variants according to `variant_count`. + ty::Pat(base, _) => *base, + _ => tp_ty, + } + .kind() + { // Correctly handles non-monomorphic calls, so there is no need for ensure_monomorphic_enough. ty::Adt(adt, _) => ConstValue::from_target_usize(adt.variants().len() as u64, &tcx), ty::Alias(..) | ty::Param(_) | ty::Placeholder(_) | ty::Infer(_) => { throw_inval!(TooGeneric) } - ty::Pat(_, pat) => match **pat { - ty::PatternKind::Range { .. } => ConstValue::from_target_usize(0u64, &tcx), - // Future pattern kinds may have more variants - }, + ty::Pat(..) => unreachable!(), ty::Bound(_, _) => bug!("bound ty during ctfe"), ty::Bool | ty::Char diff --git a/compiler/rustc_const_eval/src/interpret/validity.rs b/compiler/rustc_const_eval/src/interpret/validity.rs index fb7ba6d7ef5..c86af5a9a4b 100644 --- a/compiler/rustc_const_eval/src/interpret/validity.rs +++ b/compiler/rustc_const_eval/src/interpret/validity.rs @@ -1248,6 +1248,14 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValueVisitor<'tcx, M> for ValidityVisitor<'rt, // Range patterns are precisely reflected into `valid_range` and thus // handled fully by `visit_scalar` (called below). ty::PatternKind::Range { .. } => {}, + + // FIXME(pattern_types): check that the value is covered by one of the variants. + // For now, we rely on layout computation setting the scalar's `valid_range` to + // match the pattern. However, this cannot always work; the layout may + // pessimistically cover actually illegal ranges and Miri would miss that UB. + // The consolation here is that codegen also will miss that UB, so at least + // we won't see optimizations actually breaking such programs. + ty::PatternKind::Or(_patterns) => {} } } _ => { diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 2f8a8534247..af587ee5bdc 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -1813,6 +1813,9 @@ pub enum TyPatKind<'hir> { /// A range pattern (e.g., `1..=2` or `1..2`). Range(&'hir ConstArg<'hir>, &'hir ConstArg<'hir>), + /// A list of patterns where only one needs to be satisfied + Or(&'hir [TyPat<'hir>]), + /// A placeholder for a pattern that wasn't well formed in some way. Err(ErrorGuaranteed), } diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index 3c2897ef1d9..a60de4b1fc3 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -710,6 +710,7 @@ pub fn walk_ty_pat<'v, V: Visitor<'v>>(visitor: &mut V, pattern: &'v TyPat<'v>) try_visit!(visitor.visit_const_arg_unambig(lower_bound)); try_visit!(visitor.visit_const_arg_unambig(upper_bound)); } + TyPatKind::Or(patterns) => walk_list!(visitor, visit_pattern_type_pattern, patterns), TyPatKind::Err(_) => (), } V::Result::output() diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs index 694c1228859..c20b14df770 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs @@ -94,10 +94,12 @@ fn const_arg_anon_type_of<'tcx>(icx: &ItemCtxt<'tcx>, arg_hir_id: HirId, span: S } Node::TyPat(pat) => { - let hir::TyKind::Pat(ty, p) = tcx.parent_hir_node(pat.hir_id).expect_ty().kind else { - bug!() + let node = match tcx.parent_hir_node(pat.hir_id) { + // Or patterns can be nested one level deep + Node::TyPat(p) => tcx.parent_hir_node(p.hir_id), + other => other, }; - assert_eq!(p.hir_id, pat.hir_id); + let hir::TyKind::Pat(ty, _) = node.expect_ty().kind else { bug!() }; icx.lower_ty(ty) } 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 6e1e650a817..53792c7b093 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -2735,6 +2735,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { ty_span: Span, pat: &hir::TyPat<'tcx>, ) -> Result, ErrorGuaranteed> { + let tcx = self.tcx(); match pat.kind { hir::TyPatKind::Range(start, end) => { match ty.kind() { @@ -2750,6 +2751,13 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { .span_delayed_bug(ty_span, "invalid base type for range pattern")), } } + hir::TyPatKind::Or(patterns) => { + self.tcx() + .mk_patterns_from_iter(patterns.iter().map(|pat| { + self.lower_pat_ty_pat(ty, ty_span, pat).map(|pat| tcx.mk_pat(pat)) + })) + .map(ty::PatternKind::Or) + } hir::TyPatKind::Err(e) => Err(e), } } diff --git a/compiler/rustc_hir_analysis/src/variance/constraints.rs b/compiler/rustc_hir_analysis/src/variance/constraints.rs index 8123326a47f..ff73d163f84 100644 --- a/compiler/rustc_hir_analysis/src/variance/constraints.rs +++ b/compiler/rustc_hir_analysis/src/variance/constraints.rs @@ -340,6 +340,11 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { self.add_constraints_from_const(current, start, variance); self.add_constraints_from_const(current, end, variance); } + ty::PatternKind::Or(patterns) => { + for pat in patterns { + self.add_constraints_from_pat(current, variance, pat) + } + } } } diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index c95d6a277c7..37c7e613b2c 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -1866,6 +1866,19 @@ impl<'a> State<'a> { self.word("..="); self.print_const_arg(end); } + TyPatKind::Or(patterns) => { + self.popen(); + let mut first = true; + for pat in patterns { + if first { + first = false; + } else { + self.word(" | "); + } + self.print_ty_pat(pat); + } + self.pclose(); + } TyPatKind::Err(_) => { self.popen(); self.word("/*ERROR*/"); diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs index 2511d3f6b16..42194bac3dc 100644 --- a/compiler/rustc_lint/src/types.rs +++ b/compiler/rustc_lint/src/types.rs @@ -900,6 +900,9 @@ fn pat_ty_is_known_nonnull<'tcx>( // to ensure we aren't wrapping over zero. start > 0 && end >= start } + ty::PatternKind::Or(patterns) => { + patterns.iter().all(|pat| pat_ty_is_known_nonnull(tcx, typing_env, pat)) + } } }, ) @@ -1046,13 +1049,29 @@ pub(crate) fn repr_nullable_ptr<'tcx>( } None } - ty::Pat(base, pat) => match **pat { - ty::PatternKind::Range { .. } => get_nullable_type(tcx, typing_env, *base), - }, + ty::Pat(base, pat) => get_nullable_type_from_pat(tcx, typing_env, *base, *pat), _ => None, } } +fn get_nullable_type_from_pat<'tcx>( + tcx: TyCtxt<'tcx>, + typing_env: ty::TypingEnv<'tcx>, + base: Ty<'tcx>, + pat: ty::Pattern<'tcx>, +) -> Option> { + match *pat { + ty::PatternKind::Range { .. } => get_nullable_type(tcx, typing_env, base), + ty::PatternKind::Or(patterns) => { + let first = get_nullable_type_from_pat(tcx, typing_env, base, patterns[0])?; + for &pat in &patterns[1..] { + assert_eq!(first, get_nullable_type_from_pat(tcx, typing_env, base, pat)?); + } + Some(first) + } + } +} + impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { /// Check if the type is array and emit an unsafe type lint. fn check_for_array_ty(&mut self, sp: Span, ty: Ty<'tcx>) -> bool { diff --git a/compiler/rustc_middle/src/ty/codec.rs b/compiler/rustc_middle/src/ty/codec.rs index 23927c112bc..5ff87959a80 100644 --- a/compiler/rustc_middle/src/ty/codec.rs +++ b/compiler/rustc_middle/src/ty/codec.rs @@ -442,6 +442,15 @@ impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for ty::List> RefDecodable<'tcx, D> for ty::List> { + fn decode(decoder: &mut D) -> &'tcx Self { + let len = decoder.read_usize(); + decoder.interner().mk_patterns_from_iter( + (0..len).map::, _>(|_| Decodable::decode(decoder)), + ) + } +} + impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for ty::List> { fn decode(decoder: &mut D) -> &'tcx Self { let len = decoder.read_usize(); @@ -503,6 +512,7 @@ impl_decodable_via_ref! { &'tcx mir::Body<'tcx>, &'tcx mir::ConcreteOpaqueTypes<'tcx>, &'tcx ty::List, + &'tcx ty::List>, &'tcx ty::ListWithCachedTypeInfo>, &'tcx ty::List, &'tcx ty::List<(VariantIdx, FieldIdx)>, diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index e8dad1e056c..f97e13f13b0 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -136,6 +136,7 @@ impl<'tcx> Interner for TyCtxt<'tcx> { type AllocId = crate::mir::interpret::AllocId; type Pat = Pattern<'tcx>; + type PatList = &'tcx List>; type Safety = hir::Safety; type Abi = ExternAbi; type Const = ty::Const<'tcx>; @@ -843,6 +844,7 @@ pub struct CtxtInterners<'tcx> { captures: InternedSet<'tcx, List<&'tcx ty::CapturedPlace<'tcx>>>, offset_of: InternedSet<'tcx, List<(VariantIdx, FieldIdx)>>, valtree: InternedSet<'tcx, ty::ValTreeKind<'tcx>>, + patterns: InternedSet<'tcx, List>>, } impl<'tcx> CtxtInterners<'tcx> { @@ -879,6 +881,7 @@ impl<'tcx> CtxtInterners<'tcx> { captures: InternedSet::with_capacity(N), offset_of: InternedSet::with_capacity(N), valtree: InternedSet::with_capacity(N), + patterns: InternedSet::with_capacity(N), } } @@ -2659,6 +2662,7 @@ slice_interners!( local_def_ids: intern_local_def_ids(LocalDefId), captures: intern_captures(&'tcx ty::CapturedPlace<'tcx>), offset_of: pub mk_offset_of((VariantIdx, FieldIdx)), + patterns: pub mk_patterns(Pattern<'tcx>), ); impl<'tcx> TyCtxt<'tcx> { @@ -2932,6 +2936,14 @@ impl<'tcx> TyCtxt<'tcx> { self.intern_local_def_ids(def_ids) } + pub fn mk_patterns_from_iter(self, iter: I) -> T::Output + where + I: Iterator, + T: CollectAndApply, &'tcx List>>, + { + T::collect_and_apply(iter, |xs| self.mk_patterns(xs)) + } + pub fn mk_local_def_ids_from_iter(self, iter: I) -> T::Output where I: Iterator, diff --git a/compiler/rustc_middle/src/ty/pattern.rs b/compiler/rustc_middle/src/ty/pattern.rs index 758adc42e3e..5af9b17dd77 100644 --- a/compiler/rustc_middle/src/ty/pattern.rs +++ b/compiler/rustc_middle/src/ty/pattern.rs @@ -23,6 +23,13 @@ impl<'tcx> Flags for Pattern<'tcx> { FlagComputation::for_const_kind(&start.kind()).flags | FlagComputation::for_const_kind(&end.kind()).flags } + ty::PatternKind::Or(pats) => { + let mut flags = pats[0].flags(); + for pat in pats[1..].iter() { + flags |= pat.flags(); + } + flags + } } } @@ -31,6 +38,13 @@ impl<'tcx> Flags for Pattern<'tcx> { ty::PatternKind::Range { start, end } => { start.outer_exclusive_binder().max(end.outer_exclusive_binder()) } + ty::PatternKind::Or(pats) => { + let mut idx = pats[0].outer_exclusive_binder(); + for pat in pats[1..].iter() { + idx = idx.max(pat.outer_exclusive_binder()); + } + idx + } } } } @@ -77,6 +91,19 @@ impl<'tcx> IrPrint> for TyCtxt<'tcx> { write!(f, "..={end}") } + PatternKind::Or(patterns) => { + write!(f, "(")?; + let mut first = true; + for pat in patterns { + if first { + first = false + } else { + write!(f, " | ")?; + } + write!(f, "{pat:?}")?; + } + write!(f, ")") + } } } diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs index c3ee72bcaed..6ad4e5276b2 100644 --- a/compiler/rustc_middle/src/ty/relate.rs +++ b/compiler/rustc_middle/src/ty/relate.rs @@ -59,6 +59,15 @@ impl<'tcx> Relate> for ty::Pattern<'tcx> { let end = relation.relate(end_a, end_b)?; Ok(tcx.mk_pat(ty::PatternKind::Range { start, end })) } + (&ty::PatternKind::Or(a), &ty::PatternKind::Or(b)) => { + if a.len() != b.len() { + return Err(TypeError::Mismatch); + } + let v = iter::zip(a, b).map(|(a, b)| relation.relate(a, b)); + let patterns = tcx.mk_patterns_from_iter(v)?; + Ok(tcx.mk_pat(ty::PatternKind::Or(patterns))) + } + (ty::PatternKind::Range { .. } | ty::PatternKind::Or(_), _) => Err(TypeError::Mismatch), } } } diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index 26861666c1d..2fcb2a1572a 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -779,5 +779,6 @@ list_fold! { ty::Clauses<'tcx> : mk_clauses, &'tcx ty::List> : mk_poly_existential_predicates, &'tcx ty::List> : mk_place_elems, + &'tcx ty::List> : mk_patterns, CanonicalVarInfos<'tcx> : mk_canonical_var_infos, } diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index bae2fdeecaf..faee0e7dd5f 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -958,6 +958,11 @@ impl<'ra: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'_, 'ast, 'r self.resolve_anon_const(end, AnonConstKind::ConstArg(IsRepeatExpr::No)); } } + TyPatKind::Or(patterns) => { + for pat in patterns { + self.visit_ty_pat(pat) + } + } TyPatKind::Err(_) => {} } } diff --git a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs index c0ed3b90eb4..1c33101da35 100644 --- a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs +++ b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs @@ -412,6 +412,7 @@ impl<'tcx> Stable<'tcx> for ty::Pattern<'tcx> { end: Some(end.stable(tables)), include_end: true, }, + ty::PatternKind::Or(_) => todo!(), } } } diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs index 6cde28d0ee9..cc608736b67 100644 --- a/compiler/rustc_symbol_mangling/src/v0.rs +++ b/compiler/rustc_symbol_mangling/src/v0.rs @@ -256,6 +256,11 @@ impl<'tcx> SymbolMangler<'tcx> { Ty::new_array_with_const_len(self.tcx, self.tcx.types.unit, ct).print(self)?; } } + ty::PatternKind::Or(patterns) => { + for pat in patterns { + self.print_pat(pat)?; + } + } }) } } diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index 0a6b3b29990..6e85d3b5b13 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -695,6 +695,11 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { check(start); check(end); } + ty::PatternKind::Or(patterns) => { + for pat in patterns { + self.add_wf_preds_for_pat_ty(base_ty, pat) + } + } } } } diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs index 1915ba623cb..b962979bec7 100644 --- a/compiler/rustc_ty_utils/src/layout.rs +++ b/compiler/rustc_ty_utils/src/layout.rs @@ -255,13 +255,95 @@ fn layout_of_uncached<'tcx>( }; layout.largest_niche = Some(niche); - - tcx.mk_layout(layout) } else { bug!("pattern type with range but not scalar layout: {ty:?}, {layout:?}") } } + ty::PatternKind::Or(variants) => match *variants[0] { + ty::PatternKind::Range { .. } => { + if let BackendRepr::Scalar(scalar) = &mut layout.backend_repr { + let variants: Result, _> = variants + .iter() + .map(|pat| match *pat { + ty::PatternKind::Range { start, end } => Ok(( + extract_const_value(cx, ty, start) + .unwrap() + .try_to_bits(tcx, cx.typing_env) + .ok_or_else(|| error(cx, LayoutError::Unknown(ty)))?, + extract_const_value(cx, ty, end) + .unwrap() + .try_to_bits(tcx, cx.typing_env) + .ok_or_else(|| error(cx, LayoutError::Unknown(ty)))?, + )), + ty::PatternKind::Or(_) => { + unreachable!("mixed or patterns are not allowed") + } + }) + .collect(); + let mut variants = variants?; + if !scalar.is_signed() { + let guar = tcx.dcx().err(format!( + "only signed integer base types are allowed for or-pattern pattern types at present" + )); + + return Err(error(cx, LayoutError::ReferencesError(guar))); + } + variants.sort(); + if variants.len() != 2 { + let guar = tcx + .dcx() + .err(format!("the only or-pattern types allowed are two range patterns that are directly connected at their overflow site")); + + return Err(error(cx, LayoutError::ReferencesError(guar))); + } + + // first is the one starting at the signed in range min + let mut first = variants[0]; + let mut second = variants[1]; + if second.0 + == layout.size.truncate(layout.size.signed_int_min() as u128) + { + (second, first) = (first, second); + } + + if layout.size.sign_extend(first.1) >= layout.size.sign_extend(second.0) + { + let guar = tcx.dcx().err(format!( + "only non-overlapping pattern type ranges are allowed at present" + )); + + return Err(error(cx, LayoutError::ReferencesError(guar))); + } + if layout.size.signed_int_max() as u128 != second.1 { + let guar = tcx.dcx().err(format!( + "one pattern needs to end at `{ty}::MAX`, but was {} instead", + second.1 + )); + + return Err(error(cx, LayoutError::ReferencesError(guar))); + } + + // Now generate a wrapping range (which aren't allowed in surface syntax). + scalar.valid_range_mut().start = second.0; + scalar.valid_range_mut().end = first.1; + + let niche = Niche { + offset: Size::ZERO, + value: scalar.primitive(), + valid_range: scalar.valid_range(cx), + }; + + layout.largest_niche = Some(niche); + } else { + bug!( + "pattern type with range but not scalar layout: {ty:?}, {layout:?}" + ) + } + } + ty::PatternKind::Or(..) => bug!("patterns cannot have nested or patterns"), + }, } + tcx.mk_layout(layout) } // Basic scalars. diff --git a/compiler/rustc_type_ir/src/interner.rs b/compiler/rustc_type_ir/src/interner.rs index 9758cecaf6a..6410da1f740 100644 --- a/compiler/rustc_type_ir/src/interner.rs +++ b/compiler/rustc_type_ir/src/interner.rs @@ -113,6 +113,13 @@ pub trait Interner: + Relate + Flags + IntoKind>; + type PatList: Copy + + Debug + + Hash + + Default + + Eq + + TypeVisitable + + SliceLike; type Safety: Safety; type Abi: Abi; diff --git a/compiler/rustc_type_ir/src/pattern.rs b/compiler/rustc_type_ir/src/pattern.rs index d74a82da1f9..7e56565917c 100644 --- a/compiler/rustc_type_ir/src/pattern.rs +++ b/compiler/rustc_type_ir/src/pattern.rs @@ -13,4 +13,5 @@ use crate::Interner; )] pub enum PatternKind { Range { start: I::Const, end: I::Const }, + Or(I::PatList), } diff --git a/compiler/rustc_type_ir/src/walk.rs b/compiler/rustc_type_ir/src/walk.rs index ebfb3f786e8..737550eb73e 100644 --- a/compiler/rustc_type_ir/src/walk.rs +++ b/compiler/rustc_type_ir/src/walk.rs @@ -173,5 +173,10 @@ fn push_ty_pat(stack: &mut TypeWalkerStack, pat: I::Pat) { stack.push(end.into()); stack.push(start.into()); } + ty::PatternKind::Or(pats) => { + for pat in pats.iter() { + push_ty_pat::(stack, pat) + } + } } } diff --git a/src/tools/clippy/clippy_utils/src/hir_utils.rs b/src/tools/clippy/clippy_utils/src/hir_utils.rs index fe1fd70a9fa..17368a7530d 100644 --- a/src/tools/clippy/clippy_utils/src/hir_utils.rs +++ b/src/tools/clippy/clippy_utils/src/hir_utils.rs @@ -1117,6 +1117,11 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { self.hash_const_arg(s); self.hash_const_arg(e); }, + TyPatKind::Or(variants) => { + for variant in variants.iter() { + self.hash_ty_pat(variant) + } + }, TyPatKind::Err(_) => {}, } } diff --git a/src/tools/rustfmt/src/types.rs b/src/tools/rustfmt/src/types.rs index 75a5a8532b8..7ec1032dcb4 100644 --- a/src/tools/rustfmt/src/types.rs +++ b/src/tools/rustfmt/src/types.rs @@ -1093,6 +1093,19 @@ impl Rewrite for ast::TyPat { ast::TyPatKind::Range(ref lhs, ref rhs, ref end_kind) => { rewrite_range_pat(context, shape, lhs, rhs, end_kind, self.span) } + ast::TyPatKind::Or(ref variants) => { + let mut first = true; + let mut s = String::new(); + for variant in variants { + if first { + first = false + } else { + s.push_str(" | "); + } + s.push_str(&variant.rewrite_result(context, shape)?); + } + Ok(s) + } ast::TyPatKind::Err(_) => Err(RewriteError::Unknown), } } diff --git a/tests/ui/type/pattern_types/or_patterns.rs b/tests/ui/type/pattern_types/or_patterns.rs new file mode 100644 index 00000000000..25cb1867047 --- /dev/null +++ b/tests/ui/type/pattern_types/or_patterns.rs @@ -0,0 +1,45 @@ +//! Demonstrate some use cases of or patterns + +//@ normalize-stderr: "pref: Align\([1-8] bytes\)" -> "pref: $$SOME_ALIGN" +//@ normalize-stderr: "randomization_seed: \d+" -> "randomization_seed: $$SEED" + +#![feature( + pattern_type_macro, + pattern_types, + rustc_attrs, + const_trait_impl, + pattern_type_range_trait +)] + +use std::pat::pattern_type; + +#[rustc_layout(debug)] +type NonNullI8 = pattern_type!(i8 is ..0 | 1..); +//~^ ERROR: layout_of + +#[rustc_layout(debug)] +type NonNegOneI8 = pattern_type!(i8 is ..-1 | 0..); +//~^ ERROR: layout_of + +fn main() { + let _: NonNullI8 = 42; + let _: NonNullI8 = 1; + let _: NonNullI8 = 0; + //~^ ERROR: mismatched types + let _: NonNullI8 = -1; + //~^ ERROR: cannot apply unary operator + let _: NonNullI8 = -128; + //~^ ERROR: cannot apply unary operator + let _: NonNullI8 = 127; + + let _: NonNegOneI8 = 42; + let _: NonNegOneI8 = 1; + let _: NonNegOneI8 = 0; + let _: NonNegOneI8 = -1; + //~^ ERROR: cannot apply unary operator + let _: NonNegOneI8 = -2; + //~^ ERROR: cannot apply unary operator + let _: NonNegOneI8 = -128; + //~^ ERROR: cannot apply unary operator + let _: NonNegOneI8 = 127; +} diff --git a/tests/ui/type/pattern_types/or_patterns.stderr b/tests/ui/type/pattern_types/or_patterns.stderr new file mode 100644 index 00000000000..58ca585f4a9 --- /dev/null +++ b/tests/ui/type/pattern_types/or_patterns.stderr @@ -0,0 +1,123 @@ +error[E0308]: mismatched types + --> $DIR/or_patterns.rs:27:24 + | +LL | let _: NonNullI8 = 0; + | --------- ^ expected `(i8) is (i8::MIN..=-1 | 1..)`, found integer + | | + | expected due to this + | + = note: expected pattern type `(i8) is (i8::MIN..=-1 | 1..)` + found type `{integer}` + +error[E0600]: cannot apply unary operator `-` to type `(i8) is (i8::MIN..=-1 | 1..)` + --> $DIR/or_patterns.rs:29:24 + | +LL | let _: NonNullI8 = -1; + | ^^ cannot apply unary operator `-` + +error[E0600]: cannot apply unary operator `-` to type `(i8) is (i8::MIN..=-1 | 1..)` + --> $DIR/or_patterns.rs:31:24 + | +LL | let _: NonNullI8 = -128; + | ^^^^ cannot apply unary operator `-` + +error[E0600]: cannot apply unary operator `-` to type `(i8) is (i8::MIN..=-2 | 0..)` + --> $DIR/or_patterns.rs:38:26 + | +LL | let _: NonNegOneI8 = -1; + | ^^ cannot apply unary operator `-` + +error[E0600]: cannot apply unary operator `-` to type `(i8) is (i8::MIN..=-2 | 0..)` + --> $DIR/or_patterns.rs:40:26 + | +LL | let _: NonNegOneI8 = -2; + | ^^ cannot apply unary operator `-` + +error[E0600]: cannot apply unary operator `-` to type `(i8) is (i8::MIN..=-2 | 0..)` + --> $DIR/or_patterns.rs:42:26 + | +LL | let _: NonNegOneI8 = -128; + | ^^^^ cannot apply unary operator `-` + +error: layout_of((i8) is (i8::MIN..=-1 | 1..)) = Layout { + size: Size(1 bytes), + align: AbiAndPrefAlign { + abi: Align(1 bytes), + pref: $SOME_ALIGN, + }, + backend_repr: Scalar( + Initialized { + value: Int( + I8, + true, + ), + valid_range: 1..=255, + }, + ), + fields: Primitive, + largest_niche: Some( + Niche { + offset: Size(0 bytes), + value: Int( + I8, + true, + ), + valid_range: 1..=255, + }, + ), + uninhabited: false, + variants: Single { + index: 0, + }, + max_repr_align: None, + unadjusted_abi_align: Align(1 bytes), + randomization_seed: $SEED, + } + --> $DIR/or_patterns.rs:17:1 + | +LL | type NonNullI8 = pattern_type!(i8 is ..0 | 1..); + | ^^^^^^^^^^^^^^ + +error: layout_of((i8) is (i8::MIN..=-2 | 0..)) = Layout { + size: Size(1 bytes), + align: AbiAndPrefAlign { + abi: Align(1 bytes), + pref: $SOME_ALIGN, + }, + backend_repr: Scalar( + Initialized { + value: Int( + I8, + true, + ), + valid_range: 0..=254, + }, + ), + fields: Primitive, + largest_niche: Some( + Niche { + offset: Size(0 bytes), + value: Int( + I8, + true, + ), + valid_range: 0..=254, + }, + ), + uninhabited: false, + variants: Single { + index: 0, + }, + max_repr_align: None, + unadjusted_abi_align: Align(1 bytes), + randomization_seed: $SEED, + } + --> $DIR/or_patterns.rs:21:1 + | +LL | type NonNegOneI8 = pattern_type!(i8 is ..-1 | 0..); + | ^^^^^^^^^^^^^^^^ + +error: aborting due to 8 previous errors + +Some errors have detailed explanations: E0308, E0600. +For more information about an error, try `rustc --explain E0308`. diff --git a/tests/ui/type/pattern_types/or_patterns_invalid.rs b/tests/ui/type/pattern_types/or_patterns_invalid.rs new file mode 100644 index 00000000000..d341927601d --- /dev/null +++ b/tests/ui/type/pattern_types/or_patterns_invalid.rs @@ -0,0 +1,26 @@ +//! Demonstrate some use cases of or patterns + +#![feature( + pattern_type_macro, + pattern_types, + rustc_attrs, + const_trait_impl, + pattern_type_range_trait +)] + +use std::pat::pattern_type; + +fn main() { + //~? ERROR: only non-overlapping pattern type ranges are allowed at present + let not_adjacent: pattern_type!(i8 is -127..0 | 1..) = unsafe { std::mem::transmute(0) }; + + //~? ERROR: one pattern needs to end at `i8::MAX`, but was 29 instead + let not_wrapping: pattern_type!(i8 is 10..20 | 20..30) = unsafe { std::mem::transmute(0) }; + + //~? ERROR: only signed integer base types are allowed for or-pattern pattern types + let not_signed: pattern_type!(u8 is 10.. | 0..5) = unsafe { std::mem::transmute(0) }; + + //~? ERROR: allowed are two range patterns that are directly connected + let not_simple_enough_for_mvp: pattern_type!(i8 is ..0 | 1..10 | 10..) = + unsafe { std::mem::transmute(0) }; +} diff --git a/tests/ui/type/pattern_types/or_patterns_invalid.stderr b/tests/ui/type/pattern_types/or_patterns_invalid.stderr new file mode 100644 index 00000000000..6964788a6c2 --- /dev/null +++ b/tests/ui/type/pattern_types/or_patterns_invalid.stderr @@ -0,0 +1,10 @@ +error: only non-overlapping pattern type ranges are allowed at present + +error: one pattern needs to end at `i8::MAX`, but was 29 instead + +error: only signed integer base types are allowed for or-pattern pattern types at present + +error: the only or-pattern types allowed are two range patterns that are directly connected at their overflow site + +error: aborting due to 4 previous errors + -- cgit 1.4.1-3-g733a5 From c366756a8537ef998d32c1ef57098d5aae7ca92f Mon Sep 17 00:00:00 2001 From: Andrew Zhogin Date: Mon, 26 Aug 2024 16:45:15 +0300 Subject: AsyncDrop implementation using shim codegen of async_drop_in_place::{closure}, scoped async drop added. --- compiler/rustc_borrowck/src/lib.rs | 9 +- .../src/polonius/legacy/loan_invalidations.rs | 9 +- compiler/rustc_borrowck/src/type_check/mod.rs | 10 +- compiler/rustc_codegen_cranelift/src/abi/mod.rs | 9 +- compiler/rustc_codegen_cranelift/src/base.rs | 6 +- .../src/debuginfo/metadata/enums/cpp_like.rs | 3 +- .../src/debuginfo/metadata/enums/native.rs | 6 +- .../rustc_codegen_ssa/src/back/symbol_export.rs | 23 +- compiler/rustc_codegen_ssa/src/mir/block.rs | 18 +- .../rustc_const_eval/src/const_eval/machine.rs | 1 + compiler/rustc_const_eval/src/interpret/call.rs | 2 + compiler/rustc_const_eval/src/interpret/step.rs | 6 +- compiler/rustc_feature/src/unstable.rs | 2 + compiler/rustc_hir/src/lang_items.rs | 18 +- compiler/rustc_hir_typeck/src/callee.rs | 6 +- compiler/rustc_interface/src/passes.rs | 12 +- compiler/rustc_middle/messages.ftl | 6 + compiler/rustc_middle/src/arena.rs | 1 + .../rustc_middle/src/middle/exported_symbols.rs | 4 + compiler/rustc_middle/src/mir/mod.rs | 30 +- compiler/rustc_middle/src/mir/mono.rs | 2 + compiler/rustc_middle/src/mir/pretty.rs | 40 +- compiler/rustc_middle/src/mir/syntax.rs | 32 +- compiler/rustc_middle/src/mir/terminator.rs | 126 ++- compiler/rustc_middle/src/mir/visit.rs | 19 +- compiler/rustc_middle/src/query/mod.rs | 18 +- compiler/rustc_middle/src/ty/context.rs | 5 +- compiler/rustc_middle/src/ty/instance.rs | 95 +- compiler/rustc_middle/src/ty/mod.rs | 58 +- compiler/rustc_middle/src/ty/sty.rs | 172 +--- compiler/rustc_middle/src/ty/util.rs | 109 +-- .../src/builder/custom/parse/instruction.rs | 2 + .../rustc_mir_build/src/builder/expr/as_rvalue.rs | 2 + compiler/rustc_mir_build/src/builder/scope.rs | 159 +++- .../rustc_mir_dataflow/src/impls/initialized.rs | 9 +- compiler/rustc_mir_dataflow/src/value_analysis.rs | 3 + .../src/add_moves_for_packed_drops.rs | 6 +- compiler/rustc_mir_transform/src/coroutine.rs | 315 +++---- compiler/rustc_mir_transform/src/coroutine/drop.rs | 725 +++++++++++++++ compiler/rustc_mir_transform/src/elaborate_drop.rs | 480 ++++++++-- .../rustc_mir_transform/src/elaborate_drops.rs | 23 +- compiler/rustc_mir_transform/src/inline.rs | 31 +- compiler/rustc_mir_transform/src/inline/cycle.rs | 5 +- .../rustc_mir_transform/src/known_panics_lint.rs | 9 +- compiler/rustc_mir_transform/src/lib.rs | 2 +- .../src/lint_tail_expr_drop_order.rs | 2 + compiler/rustc_mir_transform/src/patch.rs | 8 + compiler/rustc_mir_transform/src/remove_zsts.rs | 5 + compiler/rustc_mir_transform/src/shim.rs | 111 ++- .../src/shim/async_destructor_ctor.rs | 991 ++++++++------------- compiler/rustc_mir_transform/src/validate.rs | 11 +- compiler/rustc_monomorphize/src/collector.rs | 6 +- compiler/rustc_monomorphize/src/partitioning.rs | 7 +- .../src/solve/assembly/mod.rs | 8 - .../src/solve/effect_goals.rs | 7 - .../src/solve/normalizes_to/mod.rs | 60 -- .../src/solve/trait_goals.rs | 13 - compiler/rustc_passes/src/lib.rs | 1 + compiler/rustc_smir/src/rustc_smir/context.rs | 7 - compiler/rustc_smir/src/rustc_smir/convert/mir.rs | 22 +- compiler/rustc_smir/src/rustc_smir/convert/ty.rs | 2 + .../src/stable_mir/compiler_interface.rs | 5 - compiler/rustc_smir/src/stable_mir/mir/body.rs | 17 + compiler/rustc_smir/src/stable_mir/mir/mono.rs | 5 +- compiler/rustc_smir/src/stable_mir/mir/pretty.rs | 4 +- compiler/rustc_smir/src/stable_mir/mir/visit.rs | 3 +- compiler/rustc_span/src/symbol.rs | 16 +- compiler/rustc_symbol_mangling/src/legacy.rs | 13 +- compiler/rustc_symbol_mangling/src/v0.rs | 10 +- .../rustc_trait_selection/src/traits/project.rs | 41 - .../src/traits/select/candidate_assembly.rs | 3 - compiler/rustc_ty_utils/src/abi.rs | 6 +- compiler/rustc_ty_utils/src/common_traits.rs | 8 + compiler/rustc_ty_utils/src/instance.rs | 24 +- compiler/rustc_ty_utils/src/layout.rs | 8 +- compiler/rustc_ty_utils/src/needs_drop.rs | 38 +- compiler/rustc_type_ir/src/inherent.rs | 1 - compiler/rustc_type_ir/src/lang_items.rs | 1 - library/core/src/future/async_drop.rs | 311 +------ library/core/src/future/mod.rs | 3 +- library/core/src/ops/drop.rs | 7 - library/core/src/ops/mod.rs | 1 - library/core/src/panicking.rs | 94 +- src/tools/miri/tests/pass/async-drop.rs | 115 ++- src/tools/miri/tests/pass/async-drop.stack.stdout | 37 +- src/tools/miri/tests/pass/async-drop.tree.stdout | 37 +- tests/crashes/128695.rs | 11 - tests/crashes/132103.rs | 22 - ...ove.foo-{closure#0}-{closure#0}.built.after.mir | 8 +- ...e.foo-{closure#0}-{synthetic#0}.built.after.mir | 8 +- ...sure#0}-{closure#0}-{closure#0}.built.after.mir | 8 +- ...re#0}-{closure#0}-{synthetic#0}.built.after.mir | 8 +- ...sure#0}-{closure#1}-{closure#0}.built.after.mir | 8 +- ...re#0}-{closure#1}-{synthetic#0}.built.after.mir | 8 +- tests/ui/async-await/async-drop.rs | 222 ----- tests/ui/async-await/async-drop.run.stdout | 22 - .../async-drop/async-drop-future-from-future.rs | 101 +++ .../async-drop-future-from-future.run.stdout | 5 + .../async-drop-future-in-sync-context.rs | 82 ++ .../async-drop-future-in-sync-context.run.stdout | 3 + .../async-drop/async-drop-glue-array.rs | 112 +++ .../async-drop/async-drop-glue-array.run.stdout | 12 + .../async-drop/async-drop-glue-generic.rs | 111 +++ .../async-drop/async-drop-glue-generic.run.stdout | 12 + tests/ui/async-await/async-drop/async-drop-glue.rs | 124 +++ .../async-drop/async-drop-glue.run.stdout | 11 + .../async-await/async-drop/async-drop-initial.rs | 243 +++++ .../async-drop/async-drop-initial.run.stdout | 22 + .../async-drop/async-drop-middle-drop.rs | 110 +++ .../async-drop/async-drop-middle-drop.run.stdout | 4 + tests/ui/async-await/async-drop/async-drop-open.rs | 127 +++ .../async-drop/async-drop-open.run.stdout | 11 + tests/ui/async-await/async-drop/async-drop.rs | 105 +++ .../async-await/async-drop/async-drop.run.stdout | 6 + tests/ui/async-await/async-drop/ex-ice-132103.rs | 27 + tests/ui/async-await/async-drop/ex-ice1.rs | 13 + tests/ui/async-await/async-drop/ex-ice1.stderr | 19 + tests/ui/feature-gates/feature-gate-async-drop.rs | 16 + .../feature-gates/feature-gate-async-drop.stderr | 33 + 119 files changed, 4253 insertions(+), 2078 deletions(-) create mode 100644 compiler/rustc_mir_transform/src/coroutine/drop.rs delete mode 100644 tests/crashes/128695.rs delete mode 100644 tests/crashes/132103.rs delete mode 100644 tests/ui/async-await/async-drop.rs delete mode 100644 tests/ui/async-await/async-drop.run.stdout create mode 100644 tests/ui/async-await/async-drop/async-drop-future-from-future.rs create mode 100644 tests/ui/async-await/async-drop/async-drop-future-from-future.run.stdout create mode 100644 tests/ui/async-await/async-drop/async-drop-future-in-sync-context.rs create mode 100644 tests/ui/async-await/async-drop/async-drop-future-in-sync-context.run.stdout create mode 100644 tests/ui/async-await/async-drop/async-drop-glue-array.rs create mode 100644 tests/ui/async-await/async-drop/async-drop-glue-array.run.stdout create mode 100644 tests/ui/async-await/async-drop/async-drop-glue-generic.rs create mode 100644 tests/ui/async-await/async-drop/async-drop-glue-generic.run.stdout create mode 100644 tests/ui/async-await/async-drop/async-drop-glue.rs create mode 100644 tests/ui/async-await/async-drop/async-drop-glue.run.stdout create mode 100644 tests/ui/async-await/async-drop/async-drop-initial.rs create mode 100644 tests/ui/async-await/async-drop/async-drop-initial.run.stdout create mode 100644 tests/ui/async-await/async-drop/async-drop-middle-drop.rs create mode 100644 tests/ui/async-await/async-drop/async-drop-middle-drop.run.stdout create mode 100644 tests/ui/async-await/async-drop/async-drop-open.rs create mode 100644 tests/ui/async-await/async-drop/async-drop-open.run.stdout create mode 100644 tests/ui/async-await/async-drop/async-drop.rs create mode 100644 tests/ui/async-await/async-drop/async-drop.run.stdout create mode 100644 tests/ui/async-await/async-drop/ex-ice-132103.rs create mode 100644 tests/ui/async-await/async-drop/ex-ice1.rs create mode 100644 tests/ui/async-await/async-drop/ex-ice1.stderr create mode 100644 tests/ui/feature-gates/feature-gate-async-drop.rs create mode 100644 tests/ui/feature-gates/feature-gate-async-drop.stderr (limited to 'src/tools') diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 51d37353520..44af1b76539 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -795,7 +795,14 @@ impl<'a, 'tcx> ResultsVisitor<'tcx, Borrowck<'a, 'tcx>> for MirBorrowckCtxt<'a, TerminatorKind::SwitchInt { discr, targets: _ } => { self.consume_operand(loc, (discr, span), state); } - TerminatorKind::Drop { place, target: _, unwind: _, replace } => { + TerminatorKind::Drop { + place, + target: _, + unwind: _, + replace, + drop: _, + async_fut: _, + } => { debug!( "visit_terminator_drop \ loc: {:?} term: {:?} place: {:?} span: {:?}", diff --git a/compiler/rustc_borrowck/src/polonius/legacy/loan_invalidations.rs b/compiler/rustc_borrowck/src/polonius/legacy/loan_invalidations.rs index 0d1d8642bca..99dd0b2dd46 100644 --- a/compiler/rustc_borrowck/src/polonius/legacy/loan_invalidations.rs +++ b/compiler/rustc_borrowck/src/polonius/legacy/loan_invalidations.rs @@ -101,7 +101,14 @@ impl<'a, 'tcx> Visitor<'tcx> for LoanInvalidationsGenerator<'a, 'tcx> { TerminatorKind::SwitchInt { discr, targets: _ } => { self.consume_operand(location, discr); } - TerminatorKind::Drop { place: drop_place, target: _, unwind: _, replace } => { + TerminatorKind::Drop { + place: drop_place, + target: _, + unwind: _, + replace, + drop: _, + async_fut: _, + } => { let write_kind = if *replace { WriteKind::Replace } else { WriteKind::StorageDeadOrDrop }; self.access_place( diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 3c00b819a96..99a544279b9 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -2079,8 +2079,14 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } } TerminatorKind::Unreachable => {} - TerminatorKind::Drop { target, unwind, .. } - | TerminatorKind::Assert { target, unwind, .. } => { + TerminatorKind::Drop { target, unwind, drop, .. } => { + self.assert_iscleanup(block_data, target, is_cleanup); + self.assert_iscleanup_unwind(block_data, unwind, is_cleanup); + if let Some(drop) = drop { + self.assert_iscleanup(block_data, drop, is_cleanup); + } + } + TerminatorKind::Assert { target, unwind, .. } => { self.assert_iscleanup(block_data, target, is_cleanup); self.assert_iscleanup_unwind(block_data, unwind, is_cleanup); } diff --git a/compiler/rustc_codegen_cranelift/src/abi/mod.rs b/compiler/rustc_codegen_cranelift/src/abi/mod.rs index ddd119e0c61..5f631405a9a 100644 --- a/compiler/rustc_codegen_cranelift/src/abi/mod.rs +++ b/compiler/rustc_codegen_cranelift/src/abi/mod.rs @@ -441,7 +441,9 @@ pub(crate) fn codegen_terminator_call<'tcx>( Err(instance) => Some(instance), } } - InstanceKind::DropGlue(_, None) | ty::InstanceKind::AsyncDropGlueCtorShim(_, None) => { + // We don't need AsyncDropGlueCtorShim here because it is not `noop func`, + // it is `func returning noop future` + InstanceKind::DropGlue(_, None) => { // empty drop glue - a nop. let dest = target.expect("Non terminating drop_in_place_real???"); let ret_block = fx.get_block(dest); @@ -707,9 +709,8 @@ pub(crate) fn codegen_drop<'tcx>( let ty = drop_place.layout().ty; let drop_instance = Instance::resolve_drop_in_place(fx.tcx, ty); - if let ty::InstanceKind::DropGlue(_, None) | ty::InstanceKind::AsyncDropGlueCtorShim(_, None) = - drop_instance.def - { + // AsyncDropGlueCtorShim can't be here + if let ty::InstanceKind::DropGlue(_, None) = drop_instance.def { // we don't actually need to drop anything } else { match ty.kind() { diff --git a/compiler/rustc_codegen_cranelift/src/base.rs b/compiler/rustc_codegen_cranelift/src/base.rs index adaa754491e..e9c7186b03c 100644 --- a/compiler/rustc_codegen_cranelift/src/base.rs +++ b/compiler/rustc_codegen_cranelift/src/base.rs @@ -565,7 +565,11 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) { | TerminatorKind::CoroutineDrop => { bug!("shouldn't exist at codegen {:?}", bb_data.terminator()); } - TerminatorKind::Drop { place, target, unwind: _, replace: _ } => { + TerminatorKind::Drop { place, target, unwind: _, replace: _, drop, async_fut } => { + assert!( + async_fut.is_none() && drop.is_none(), + "Async Drop must be expanded or reset to sync before codegen" + ); let drop_place = codegen_place(fx, *place); crate::abi::codegen_drop(fx, source_info, drop_place, *target); } diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs index 07075be55fa..e9574108696 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs @@ -721,8 +721,7 @@ fn build_union_fields_for_direct_tag_coroutine<'ll, 'tcx>( _ => unreachable!(), }; - let coroutine_layout = - cx.tcx.coroutine_layout(coroutine_def_id, coroutine_args.kind_ty()).unwrap(); + let coroutine_layout = cx.tcx.coroutine_layout(coroutine_def_id, coroutine_args.args).unwrap(); let common_upvar_names = cx.tcx.closure_saved_names_of_captured_variables(coroutine_def_id); let variant_range = coroutine_args.variant_range(coroutine_def_id, cx.tcx); diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs index bfd131cfd3d..20a841f2287 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs @@ -174,10 +174,8 @@ pub(super) fn build_coroutine_di_node<'ll, 'tcx>( DIFlags::FlagZero, ), |cx, coroutine_type_di_node| { - let coroutine_layout = cx - .tcx - .coroutine_layout(coroutine_def_id, coroutine_args.as_coroutine().kind_ty()) - .unwrap(); + let coroutine_layout = + cx.tcx.coroutine_layout(coroutine_def_id, coroutine_args).unwrap(); let Variants::Multiple { tag_encoding: TagEncoding::Direct, ref variants, .. } = coroutine_type_and_layout.variants diff --git a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs index fd06c50eb81..2bfab1f43bc 100644 --- a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs +++ b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs @@ -374,7 +374,7 @@ fn exported_symbols_provider_local( )); } MonoItem::Fn(Instance { - def: InstanceKind::AsyncDropGlueCtorShim(_, Some(ty)), + def: InstanceKind::AsyncDropGlueCtorShim(_, ty), args, }) => { // A little sanity-check @@ -388,6 +388,16 @@ fn exported_symbols_provider_local( }, )); } + MonoItem::Fn(Instance { def: InstanceKind::AsyncDropGlue(def, ty), args: _ }) => { + symbols.push(( + ExportedSymbol::AsyncDropGlue(def, ty), + SymbolExportInfo { + level: SymbolExportLevel::Rust, + kind: SymbolExportKind::Text, + used: false, + }, + )); + } _ => { // Any other symbols don't qualify for sharing } @@ -429,11 +439,10 @@ fn upstream_monomorphizations_provider( if let Some(async_drop_in_place_fn_def_id) = async_drop_in_place_fn_def_id { (async_drop_in_place_fn_def_id, tcx.mk_args(&[ty.into()])) } else { - // `drop_in_place` in place does not exist, don't try - // to use it. continue; } } + ExportedSymbol::AsyncDropGlue(def_id, ty) => (def_id, tcx.mk_args(&[ty.into()])), ExportedSymbol::NonGeneric(..) | ExportedSymbol::ThreadLocalShim(..) | ExportedSymbol::NoDefId(..) => { @@ -582,6 +591,13 @@ pub(crate) fn symbol_name_for_instance_in_crate<'tcx>( instantiating_crate, ) } + ExportedSymbol::AsyncDropGlue(def_id, ty) => { + rustc_symbol_mangling::symbol_name_for_instance_in_crate( + tcx, + Instance::resolve_async_drop_in_place_poll(tcx, def_id, ty), + instantiating_crate, + ) + } ExportedSymbol::NoDefId(symbol_name) => symbol_name.to_string(), } } @@ -604,6 +620,7 @@ fn calling_convention_for_symbol<'tcx>( // AsyncDropGlueCtorShim always use the Rust calling convention and thus follow the // target's default symbol decoration scheme. ExportedSymbol::AsyncDropGlueCtorShim(..) => None, + ExportedSymbol::AsyncDropGlue(..) => None, // NoDefId always follow the target's default symbol decoration scheme. ExportedSymbol::NoDefId(..) => None, // ThreadLocalShim always follow the target's default symbol decoration scheme. diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index d184ce3d61d..950f19a6f0f 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -926,10 +926,9 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let def = instance.map(|i| i.def); - if let Some( - ty::InstanceKind::DropGlue(_, None) | ty::InstanceKind::AsyncDropGlueCtorShim(_, None), - ) = def - { + // We don't need AsyncDropGlueCtorShim here because it is not `noop func`, + // it is `func returning noop future` + if let Some(ty::InstanceKind::DropGlue(_, None)) = def { // Empty drop glue; a no-op. let target = target.unwrap(); return helper.funclet_br(self, bx, target, mergeable_succ); @@ -1386,8 +1385,12 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { MergingSucc::False } - mir::TerminatorKind::Drop { place, target, unwind, replace: _ } => self - .codegen_drop_terminator( + mir::TerminatorKind::Drop { place, target, unwind, replace: _, drop, async_fut } => { + assert!( + async_fut.is_none() && drop.is_none(), + "Async Drop must be expanded or reset to sync before codegen" + ); + self.codegen_drop_terminator( helper, bx, &terminator.source_info, @@ -1395,7 +1398,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { target, unwind, mergeable_succ(), - ), + ) + } mir::TerminatorKind::Assert { ref cond, expected, ref msg, target, unwind } => self .codegen_assert_terminator( diff --git a/compiler/rustc_const_eval/src/const_eval/machine.rs b/compiler/rustc_const_eval/src/const_eval/machine.rs index 61a7ec13511..7c7daed525b 100644 --- a/compiler/rustc_const_eval/src/const_eval/machine.rs +++ b/compiler/rustc_const_eval/src/const_eval/machine.rs @@ -502,6 +502,7 @@ impl<'tcx> interpret::Machine<'tcx> for CompileTimeMachine<'tcx> { RemainderByZero(op) => RemainderByZero(eval_to_int(op)?), ResumedAfterReturn(coroutine_kind) => ResumedAfterReturn(*coroutine_kind), ResumedAfterPanic(coroutine_kind) => ResumedAfterPanic(*coroutine_kind), + ResumedAfterDrop(coroutine_kind) => ResumedAfterDrop(*coroutine_kind), MisalignedPointerDereference { required, found } => MisalignedPointerDereference { required: eval_to_int(required)?, found: eval_to_int(found)?, diff --git a/compiler/rustc_const_eval/src/interpret/call.rs b/compiler/rustc_const_eval/src/interpret/call.rs index 29f819cca1f..216800717fd 100644 --- a/compiler/rustc_const_eval/src/interpret/call.rs +++ b/compiler/rustc_const_eval/src/interpret/call.rs @@ -570,6 +570,8 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { | ty::InstanceKind::FnPtrAddrShim(..) | ty::InstanceKind::ThreadLocalShim(..) | ty::InstanceKind::AsyncDropGlueCtorShim(..) + | ty::InstanceKind::AsyncDropGlue(..) + | ty::InstanceKind::FutureDropPollShim(..) | ty::InstanceKind::Item(_) => { // We need MIR for this fn. // Note that this can be an intrinsic, if we are executing its fallback body. diff --git a/compiler/rustc_const_eval/src/interpret/step.rs b/compiler/rustc_const_eval/src/interpret/step.rs index ddf2d65914f..363ceee1970 100644 --- a/compiler/rustc_const_eval/src/interpret/step.rs +++ b/compiler/rustc_const_eval/src/interpret/step.rs @@ -539,7 +539,11 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { } } - Drop { place, target, unwind, replace: _ } => { + Drop { place, target, unwind, replace: _, drop, async_fut } => { + assert!( + async_fut.is_none() && drop.is_none(), + "Async Drop must be expanded or reset to sync in runtime MIR" + ); let place = self.eval_place(place)?; let instance = Instance::resolve_drop_in_place(*self.tcx, place.layout.ty); if let ty::InstanceKind::DropGlue(_, None) = instance.def { diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index cbc121e3632..8a31a03db72 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -381,6 +381,8 @@ declare_features! ( (unstable, associated_const_equality, "1.58.0", Some(92827)), /// Allows associated type defaults. (unstable, associated_type_defaults, "1.2.0", Some(29661)), + /// Allows implementing `AsyncDrop`. + (incomplete, async_drop, "CURRENT_RUSTC_VERSION", Some(126482)), /// Allows async functions to be called from `dyn Trait`. (incomplete, async_fn_in_dyn_trait, "1.85.0", Some(133119)), /// Allows `#[track_caller]` on async functions. diff --git a/compiler/rustc_hir/src/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs index b9f4a8cd165..21d36ed54cd 100644 --- a/compiler/rustc_hir/src/lang_items.rs +++ b/compiler/rustc_hir/src/lang_items.rs @@ -189,19 +189,8 @@ language_item_table! { Drop, sym::drop, drop_trait, Target::Trait, GenericRequirement::None; Destruct, sym::destruct, destruct_trait, Target::Trait, GenericRequirement::None; - - AsyncDrop, sym::async_drop, async_drop_trait, Target::Trait, GenericRequirement::Exact(0); - AsyncDestruct, sym::async_destruct, async_destruct_trait, Target::Trait, GenericRequirement::Exact(0); + AsyncDrop, sym::async_drop, async_drop_trait, Target::Trait, GenericRequirement::None; AsyncDropInPlace, sym::async_drop_in_place, async_drop_in_place_fn, Target::Fn, GenericRequirement::Exact(1); - SurfaceAsyncDropInPlace, sym::surface_async_drop_in_place, surface_async_drop_in_place_fn, Target::Fn, GenericRequirement::Exact(1); - AsyncDropSurfaceDropInPlace, sym::async_drop_surface_drop_in_place, async_drop_surface_drop_in_place_fn, Target::Fn, GenericRequirement::Exact(1); - AsyncDropSlice, sym::async_drop_slice, async_drop_slice_fn, Target::Fn, GenericRequirement::Exact(1); - AsyncDropChain, sym::async_drop_chain, async_drop_chain_fn, Target::Fn, GenericRequirement::Exact(2); - AsyncDropNoop, sym::async_drop_noop, async_drop_noop_fn, Target::Fn, GenericRequirement::Exact(0); - AsyncDropDeferredDropInPlace, sym::async_drop_deferred_drop_in_place, async_drop_deferred_drop_in_place_fn, Target::Fn, GenericRequirement::Exact(1); - AsyncDropFuse, sym::async_drop_fuse, async_drop_fuse_fn, Target::Fn, GenericRequirement::Exact(1); - AsyncDropDefer, sym::async_drop_defer, async_drop_defer_fn, Target::Fn, GenericRequirement::Exact(1); - AsyncDropEither, sym::async_drop_either, async_drop_either_fn, Target::Fn, GenericRequirement::Exact(3); CoerceUnsized, sym::coerce_unsized, coerce_unsized_trait, Target::Trait, GenericRequirement::Minimum(1); DispatchFromDyn, sym::dispatch_from_dyn, dispatch_from_dyn_trait, Target::Trait, GenericRequirement::Minimum(1); @@ -321,6 +310,10 @@ language_item_table! { PanicAsyncGenFnResumedPanic, sym::panic_const_async_gen_fn_resumed_panic, panic_const_async_gen_fn_resumed_panic, Target::Fn, GenericRequirement::None; PanicGenFnNonePanic, sym::panic_const_gen_fn_none_panic, panic_const_gen_fn_none_panic, Target::Fn, GenericRequirement::None; PanicNullPointerDereference, sym::panic_null_pointer_dereference, panic_null_pointer_dereference, Target::Fn, GenericRequirement::None; + PanicCoroutineResumedDrop, sym::panic_const_coroutine_resumed_drop, panic_const_coroutine_resumed_drop, Target::Fn, GenericRequirement::None; + PanicAsyncFnResumedDrop, sym::panic_const_async_fn_resumed_drop, panic_const_async_fn_resumed_drop, Target::Fn, GenericRequirement::None; + PanicAsyncGenFnResumedDrop, sym::panic_const_async_gen_fn_resumed_drop, panic_const_async_gen_fn_resumed_drop, Target::Fn, GenericRequirement::None; + PanicGenFnNoneDrop, sym::panic_const_gen_fn_none_drop, panic_const_gen_fn_none_drop, Target::Fn, GenericRequirement::None; /// libstd panic entry point. Necessary for const eval to be able to catch it BeginPanic, sym::begin_panic, begin_panic_fn, Target::Fn, GenericRequirement::None; @@ -333,7 +326,6 @@ language_item_table! { ExchangeMalloc, sym::exchange_malloc, exchange_malloc_fn, Target::Fn, GenericRequirement::None; DropInPlace, sym::drop_in_place, drop_in_place_fn, Target::Fn, GenericRequirement::Minimum(1); - FallbackSurfaceDrop, sym::fallback_surface_drop, fallback_surface_drop_fn, Target::Fn, GenericRequirement::None; AllocLayout, sym::alloc_layout, alloc_layout, Target::Struct, GenericRequirement::None; /// For all binary crates without `#![no_main]`, Rust will generate a "main" function. diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs index d770937bd66..5f5e9e45612 100644 --- a/compiler/rustc_hir_typeck/src/callee.rs +++ b/compiler/rustc_hir_typeck/src/callee.rs @@ -34,11 +34,9 @@ pub(crate) fn check_legal_trait_for_method_call( receiver: Option, expr_span: Span, trait_id: DefId, - body_id: DefId, + _body_id: DefId, ) -> Result<(), ErrorGuaranteed> { - if tcx.is_lang_item(trait_id, LangItem::Drop) - && !tcx.is_lang_item(body_id, LangItem::FallbackSurfaceDrop) - { + if tcx.is_lang_item(trait_id, LangItem::Drop) { let sugg = if let Some(receiver) = receiver.filter(|s| !s.is_empty()) { errors::ExplicitDestructorCallSugg::Snippet { lo: expr_span.shrink_to_lo(), diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index fde1872fb39..66d2a79b93a 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -982,11 +982,13 @@ fn run_required_analyses(tcx: TyCtxt<'_>) { let _ = tcx.ensure_ok().check_coroutine_obligations( tcx.typeck_root_def_id(def_id.to_def_id()).expect_local(), ); - // Eagerly check the unsubstituted layout for cycles. - tcx.ensure_ok().layout_of( - ty::TypingEnv::post_analysis(tcx, def_id.to_def_id()) - .as_query_input(tcx.type_of(def_id).instantiate_identity()), - ); + if !tcx.is_async_drop_in_place_coroutine(def_id.to_def_id()) { + // Eagerly check the unsubstituted layout for cycles. + tcx.ensure_ok().layout_of( + ty::TypingEnv::post_analysis(tcx, def_id.to_def_id()) + .as_query_input(tcx.type_of(def_id).instantiate_identity()), + ); + } } }); }); diff --git a/compiler/rustc_middle/messages.ftl b/compiler/rustc_middle/messages.ftl index 0b3c0be1a4e..3d27e587b6c 100644 --- a/compiler/rustc_middle/messages.ftl +++ b/compiler/rustc_middle/messages.ftl @@ -1,7 +1,11 @@ +middle_assert_async_resume_after_drop = `async fn` resumed after async drop + middle_assert_async_resume_after_panic = `async fn` resumed after panicking middle_assert_async_resume_after_return = `async fn` resumed after completion +middle_assert_coroutine_resume_after_drop = coroutine resumed after async drop + middle_assert_coroutine_resume_after_panic = coroutine resumed after panicking middle_assert_coroutine_resume_after_return = coroutine resumed after completion @@ -9,6 +13,8 @@ middle_assert_coroutine_resume_after_return = coroutine resumed after completion middle_assert_divide_by_zero = attempt to divide `{$val}` by zero +middle_assert_gen_resume_after_drop = `gen` fn or block cannot be further iterated on after it async dropped + middle_assert_gen_resume_after_panic = `gen` fn or block cannot be further iterated on after it panicked middle_assert_misaligned_ptr_deref = diff --git a/compiler/rustc_middle/src/arena.rs b/compiler/rustc_middle/src/arena.rs index d1bbb0598fe..2dcb0de92b7 100644 --- a/compiler/rustc_middle/src/arena.rs +++ b/compiler/rustc_middle/src/arena.rs @@ -9,6 +9,7 @@ macro_rules! arena_types { ($macro:path) => ( $macro!([ [] layout: rustc_abi::LayoutData, + [] proxy_coroutine_layout: rustc_middle::mir::CoroutineLayout<'tcx>, [] fn_abi: rustc_target::callconv::FnAbi<'tcx, rustc_middle::ty::Ty<'tcx>>, // AdtDef are interned and compared by address [decode] adt_def: rustc_middle::ty::AdtDefData, diff --git a/compiler/rustc_middle/src/middle/exported_symbols.rs b/compiler/rustc_middle/src/middle/exported_symbols.rs index 0bfbd398797..3c62017072e 100644 --- a/compiler/rustc_middle/src/middle/exported_symbols.rs +++ b/compiler/rustc_middle/src/middle/exported_symbols.rs @@ -44,6 +44,7 @@ pub enum ExportedSymbol<'tcx> { Generic(DefId, GenericArgsRef<'tcx>), DropGlue(Ty<'tcx>), AsyncDropGlueCtorShim(Ty<'tcx>), + AsyncDropGlue(DefId, Ty<'tcx>), ThreadLocalShim(DefId), NoDefId(ty::SymbolName<'tcx>), } @@ -63,6 +64,9 @@ impl<'tcx> ExportedSymbol<'tcx> { ExportedSymbol::AsyncDropGlueCtorShim(ty) => { tcx.symbol_name(ty::Instance::resolve_async_drop_in_place(tcx, ty)) } + ExportedSymbol::AsyncDropGlue(def_id, ty) => { + tcx.symbol_name(ty::Instance::resolve_async_drop_in_place_poll(tcx, def_id, ty)) + } ExportedSymbol::ThreadLocalShim(def_id) => tcx.symbol_name(ty::Instance { def: ty::InstanceKind::ThreadLocalShim(def_id), args: ty::GenericArgs::empty(), diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index db19c858e7c..adc100941a3 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -200,7 +200,13 @@ pub struct CoroutineInfo<'tcx> { /// Coroutine drop glue. This field is populated after the state transform pass. pub coroutine_drop: Option>, - /// The layout of a coroutine. This field is populated after the state transform pass. + /// Coroutine async drop glue. + pub coroutine_drop_async: Option>, + + /// When coroutine has sync drop, this is async proxy calling `coroutine_drop` sync impl. + pub coroutine_drop_proxy_async: Option>, + + /// The layout of a coroutine. Produced by the state transformation. pub coroutine_layout: Option>, /// If this is a coroutine then record the type of source expression that caused this coroutine @@ -220,6 +226,8 @@ impl<'tcx> CoroutineInfo<'tcx> { yield_ty: Some(yield_ty), resume_ty: Some(resume_ty), coroutine_drop: None, + coroutine_drop_async: None, + coroutine_drop_proxy_async: None, coroutine_layout: None, } } @@ -587,6 +595,26 @@ impl<'tcx> Body<'tcx> { self.coroutine.as_ref().and_then(|coroutine| coroutine.coroutine_drop.as_ref()) } + #[inline] + pub fn coroutine_drop_async(&self) -> Option<&Body<'tcx>> { + self.coroutine.as_ref().and_then(|coroutine| coroutine.coroutine_drop_async.as_ref()) + } + + #[inline] + pub fn coroutine_requires_async_drop(&self) -> bool { + self.coroutine_drop_async().is_some() + } + + #[inline] + pub fn future_drop_poll(&self) -> Option<&Body<'tcx>> { + self.coroutine.as_ref().and_then(|coroutine| { + coroutine + .coroutine_drop_async + .as_ref() + .or(coroutine.coroutine_drop_proxy_async.as_ref()) + }) + } + #[inline] pub fn coroutine_kind(&self) -> Option { self.coroutine.as_ref().map(|coroutine| coroutine.coroutine_kind) diff --git a/compiler/rustc_middle/src/mir/mono.rs b/compiler/rustc_middle/src/mir/mono.rs index 1ffe958dbdd..6b413a7383a 100644 --- a/compiler/rustc_middle/src/mir/mono.rs +++ b/compiler/rustc_middle/src/mir/mono.rs @@ -530,6 +530,8 @@ impl<'tcx> CodegenUnit<'tcx> { | InstanceKind::CloneShim(..) | InstanceKind::ThreadLocalShim(..) | InstanceKind::FnPtrAddrShim(..) + | InstanceKind::AsyncDropGlue(..) + | InstanceKind::FutureDropPollShim(..) | InstanceKind::AsyncDropGlueCtorShim(..) => None, } } diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs index d57019fee0f..57ae7dc55c5 100644 --- a/compiler/rustc_middle/src/mir/pretty.rs +++ b/compiler/rustc_middle/src/mir/pretty.rs @@ -253,9 +253,7 @@ fn dump_path<'tcx>( })); s } - ty::InstanceKind::AsyncDropGlueCtorShim(_, Some(ty)) => { - // Unfortunately, pretty-printed typed are not very filename-friendly. - // We dome some filtering. + ty::InstanceKind::AsyncDropGlueCtorShim(_, ty) => { let mut s = ".".to_owned(); s.extend(ty.to_string().chars().filter_map(|c| match c { ' ' => None, @@ -264,6 +262,34 @@ fn dump_path<'tcx>( })); s } + ty::InstanceKind::AsyncDropGlue(_, ty) => { + let ty::Coroutine(_, args) = ty.kind() else { + bug!(); + }; + let ty = args.first().unwrap().expect_ty(); + let mut s = ".".to_owned(); + s.extend(ty.to_string().chars().filter_map(|c| match c { + ' ' => None, + ':' | '<' | '>' => Some('_'), + c => Some(c), + })); + s + } + ty::InstanceKind::FutureDropPollShim(_, proxy_cor, impl_cor) => { + let mut s = ".".to_owned(); + s.extend(proxy_cor.to_string().chars().filter_map(|c| match c { + ' ' => None, + ':' | '<' | '>' => Some('_'), + c => Some(c), + })); + s.push('.'); + s.extend(impl_cor.to_string().chars().filter_map(|c| match c { + ' ' => None, + ':' | '<' | '>' => Some('_'), + c => Some(c), + })); + s + } _ => String::new(), }; @@ -1050,7 +1076,13 @@ impl<'tcx> TerminatorKind<'tcx> { Call { target: None, unwind: _, .. } => vec![], Yield { drop: Some(_), .. } => vec!["resume".into(), "drop".into()], Yield { drop: None, .. } => vec!["resume".into()], - Drop { unwind: UnwindAction::Cleanup(_), .. } => vec!["return".into(), "unwind".into()], + Drop { unwind: UnwindAction::Cleanup(_), drop: Some(_), .. } => { + vec!["return".into(), "unwind".into(), "drop".into()] + } + Drop { unwind: UnwindAction::Cleanup(_), drop: None, .. } => { + vec!["return".into(), "unwind".into()] + } + Drop { unwind: _, drop: Some(_), .. } => vec!["return".into(), "drop".into()], Drop { unwind: _, .. } => vec!["return".into()], Assert { unwind: UnwindAction::Cleanup(_), .. } => { vec!["success".into(), "unwind".into()] diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs index 304b3caa6e1..bb068f3821d 100644 --- a/compiler/rustc_middle/src/mir/syntax.rs +++ b/compiler/rustc_middle/src/mir/syntax.rs @@ -77,6 +77,8 @@ pub enum MirPhase { /// exception is fields of packed structs. In analysis MIR, `Drop(P)` for a `P` that might be /// misaligned for this reason implicitly moves `P` to a temporary before dropping. Runtime /// MIR has no such rules, and dropping a misaligned place is simply UB. + /// - Async drops: after drop elaboration some drops may become async (`drop`, `async_fut` fields). + /// StateTransform pass will expand those async drops or reset to sync. /// - Unwinding: in analysis MIR, unwinding from a function which may not unwind aborts. In /// runtime MIR, this is UB. /// - Retags: If `-Zmir-emit-retag` is enabled, analysis MIR has "implicit" retags in the same @@ -768,7 +770,34 @@ pub enum TerminatorKind<'tcx> { /// The `replace` flag indicates whether this terminator was created as part of an assignment. /// This should only be used for diagnostic purposes, and does not have any operational /// meaning. - Drop { place: Place<'tcx>, target: BasicBlock, unwind: UnwindAction, replace: bool }, + /// + /// Async drop processing: + /// In compiler/rustc_mir_build/src/build/scope.rs we detect possible async drop: + /// drop of object with `needs_async_drop`. + /// Async drop later, in StateTransform pass, may be expanded into additional yield-point + /// for poll-loop of async drop future. + /// So we need prepared 'drop' target block in the similar way as for `Yield` terminator + /// (see `drops.build_mir::` in scopes.rs). + /// In compiler/rustc_mir_transform/src/elaborate_drops.rs for object implementing `AsyncDrop` trait + /// we need to prepare async drop feature - resolve `AsyncDrop::drop` and codegen call. + /// `async_fut` is set to the corresponding local. + /// For coroutine drop we don't need this logic because coroutine drop works with the same + /// layout object as coroutine itself. So `async_fut` will be `None` for coroutine drop. + /// Both `drop` and `async_fut` fields are only used in compiler/rustc_mir_transform/src/coroutine.rs, + /// StateTransform pass. In `expand_async_drops` async drops are expanded + /// into one or two yield points with poll ready/pending switch. + /// When a coroutine has any internal async drop, the coroutine drop function will be async + /// (generated by `create_coroutine_drop_shim_async`, not `create_coroutine_drop_shim`). + Drop { + place: Place<'tcx>, + target: BasicBlock, + unwind: UnwindAction, + replace: bool, + /// Cleanup to be done if the coroutine is dropped at this suspend point (for async drop). + drop: Option, + /// Prepared async future local (for async drop) + async_fut: Option, + }, /// Roughly speaking, evaluates the `func` operand and the arguments, and starts execution of /// the referred to function. The operand types must match the argument types of the function. @@ -1043,6 +1072,7 @@ pub enum AssertKind { RemainderByZero(O), ResumedAfterReturn(CoroutineKind), ResumedAfterPanic(CoroutineKind), + ResumedAfterDrop(CoroutineKind), MisalignedPointerDereference { required: O, found: O }, NullPointerDereference, } diff --git a/compiler/rustc_middle/src/mir/terminator.rs b/compiler/rustc_middle/src/mir/terminator.rs index 82e8422c52d..8a1ead7d19d 100644 --- a/compiler/rustc_middle/src/mir/terminator.rs +++ b/compiler/rustc_middle/src/mir/terminator.rs @@ -208,6 +208,16 @@ impl AssertKind { LangItem::PanicGenFnNonePanic } NullPointerDereference => LangItem::PanicNullPointerDereference, + ResumedAfterDrop(CoroutineKind::Coroutine(_)) => LangItem::PanicCoroutineResumedDrop, + ResumedAfterDrop(CoroutineKind::Desugared(CoroutineDesugaring::Async, _)) => { + LangItem::PanicAsyncFnResumedDrop + } + ResumedAfterDrop(CoroutineKind::Desugared(CoroutineDesugaring::AsyncGen, _)) => { + LangItem::PanicAsyncGenFnResumedDrop + } + ResumedAfterDrop(CoroutineKind::Desugared(CoroutineDesugaring::Gen, _)) => { + LangItem::PanicGenFnNoneDrop + } BoundsCheck { .. } | MisalignedPointerDereference { .. } => { bug!("Unexpected AssertKind") @@ -298,6 +308,18 @@ impl AssertKind { ResumedAfterPanic(CoroutineKind::Desugared(CoroutineDesugaring::Gen, _)) => { write!(f, "\"`gen fn` should just keep returning `None` after panicking\"") } + ResumedAfterDrop(CoroutineKind::Coroutine(_)) => { + write!(f, "\"coroutine resumed after async drop\"") + } + ResumedAfterDrop(CoroutineKind::Desugared(CoroutineDesugaring::Async, _)) => { + write!(f, "\"`async fn` resumed after async drop\"") + } + ResumedAfterDrop(CoroutineKind::Desugared(CoroutineDesugaring::AsyncGen, _)) => { + write!(f, "\"`async gen fn` resumed after async drop\"") + } + ResumedAfterDrop(CoroutineKind::Desugared(CoroutineDesugaring::Gen, _)) => { + write!(f, "\"`gen fn` resumed after drop\"") + } } } @@ -345,6 +367,19 @@ impl AssertKind { middle_assert_coroutine_resume_after_panic } NullPointerDereference => middle_assert_null_ptr_deref, + ResumedAfterDrop(CoroutineKind::Desugared(CoroutineDesugaring::Async, _)) => { + middle_assert_async_resume_after_drop + } + ResumedAfterDrop(CoroutineKind::Desugared(CoroutineDesugaring::AsyncGen, _)) => { + todo!() + } + ResumedAfterDrop(CoroutineKind::Desugared(CoroutineDesugaring::Gen, _)) => { + middle_assert_gen_resume_after_drop + } + ResumedAfterDrop(CoroutineKind::Coroutine(_)) => { + middle_assert_coroutine_resume_after_drop + } + MisalignedPointerDereference { .. } => middle_assert_misaligned_ptr_deref, } } @@ -377,7 +412,10 @@ impl AssertKind { add!("left", format!("{left:#?}")); add!("right", format!("{right:#?}")); } - ResumedAfterReturn(_) | ResumedAfterPanic(_) | NullPointerDereference => {} + ResumedAfterReturn(_) + | ResumedAfterPanic(_) + | NullPointerDereference + | ResumedAfterDrop(_) => {} MisalignedPointerDereference { required, found } => { add!("required", format!("{required:#?}")); add!("found", format!("{found:#?}")); @@ -457,7 +495,7 @@ mod helper { #[define_opaque(Successors)] pub fn successors_for_value(&self, value: u128) -> Successors<'_> { let target = self.target_for_value(value); - (&[]).into_iter().copied().chain(Some(target)) + (&[]).into_iter().copied().chain(Some(target).into_iter().chain(None)) } } @@ -467,13 +505,23 @@ mod helper { pub fn successors(&self) -> Successors<'_> { use self::TerminatorKind::*; match *self { + // 3-successors for async drop: target, unwind, dropline (parent coroutine drop) + Drop { target: ref t, unwind: UnwindAction::Cleanup(u), drop: Some(d), .. } => { + slice::from_ref(t) + .into_iter() + .copied() + .chain(Some(u).into_iter().chain(Some(d))) + } + // 2-successors Call { target: Some(ref t), unwind: UnwindAction::Cleanup(u), .. } | Yield { resume: ref t, drop: Some(u), .. } - | Drop { target: ref t, unwind: UnwindAction::Cleanup(u), .. } + | Drop { target: ref t, unwind: UnwindAction::Cleanup(u), drop: None, .. } + | Drop { target: ref t, unwind: _, drop: Some(u), .. } | Assert { target: ref t, unwind: UnwindAction::Cleanup(u), .. } | FalseUnwind { real_target: ref t, unwind: UnwindAction::Cleanup(u) } => { - slice::from_ref(t).into_iter().copied().chain(Some(u)) + slice::from_ref(t).into_iter().copied().chain(Some(u).into_iter().chain(None)) } + // single successor Goto { target: ref t } | Call { target: None, unwind: UnwindAction::Cleanup(ref t), .. } | Call { target: Some(ref t), unwind: _, .. } @@ -481,23 +529,33 @@ mod helper { | Drop { target: ref t, unwind: _, .. } | Assert { target: ref t, unwind: _, .. } | FalseUnwind { real_target: ref t, unwind: _ } => { - slice::from_ref(t).into_iter().copied().chain(None) + slice::from_ref(t).into_iter().copied().chain(None.into_iter().chain(None)) } + // No successors UnwindResume | UnwindTerminate(_) | CoroutineDrop | Return | Unreachable | TailCall { .. } - | Call { target: None, unwind: _, .. } => (&[]).into_iter().copied().chain(None), + | Call { target: None, unwind: _, .. } => { + (&[]).into_iter().copied().chain(None.into_iter().chain(None)) + } + // Multiple successors InlineAsm { ref targets, unwind: UnwindAction::Cleanup(u), .. } => { - targets.iter().copied().chain(Some(u)) + targets.iter().copied().chain(Some(u).into_iter().chain(None)) + } + InlineAsm { ref targets, unwind: _, .. } => { + targets.iter().copied().chain(None.into_iter().chain(None)) } - InlineAsm { ref targets, unwind: _, .. } => targets.iter().copied().chain(None), - SwitchInt { ref targets, .. } => targets.targets.iter().copied().chain(None), - FalseEdge { ref real_target, imaginary_target } => { - slice::from_ref(real_target).into_iter().copied().chain(Some(imaginary_target)) + SwitchInt { ref targets, .. } => { + targets.targets.iter().copied().chain(None.into_iter().chain(None)) } + // FalseEdge + FalseEdge { ref real_target, imaginary_target } => slice::from_ref(real_target) + .into_iter() + .copied() + .chain(Some(imaginary_target).into_iter().chain(None)), } } @@ -506,16 +564,31 @@ mod helper { pub fn successors_mut(&mut self) -> SuccessorsMut<'_> { use self::TerminatorKind::*; match *self { + // 3-successors for async drop: target, unwind, dropline (parent coroutine drop) + Drop { + target: ref mut t, + unwind: UnwindAction::Cleanup(ref mut u), + drop: Some(ref mut d), + .. + } => slice::from_mut(t).into_iter().chain(Some(u).into_iter().chain(Some(d))), + // 2-successors Call { target: Some(ref mut t), unwind: UnwindAction::Cleanup(ref mut u), .. } | Yield { resume: ref mut t, drop: Some(ref mut u), .. } - | Drop { target: ref mut t, unwind: UnwindAction::Cleanup(ref mut u), .. } + | Drop { + target: ref mut t, + unwind: UnwindAction::Cleanup(ref mut u), + drop: None, + .. + } + | Drop { target: ref mut t, unwind: _, drop: Some(ref mut u), .. } | Assert { target: ref mut t, unwind: UnwindAction::Cleanup(ref mut u), .. } | FalseUnwind { real_target: ref mut t, unwind: UnwindAction::Cleanup(ref mut u), - } => slice::from_mut(t).into_iter().chain(Some(u)), + } => slice::from_mut(t).into_iter().chain(Some(u).into_iter().chain(None)), + // single successor Goto { target: ref mut t } | Call { target: None, unwind: UnwindAction::Cleanup(ref mut t), .. } | Call { target: Some(ref mut t), unwind: _, .. } @@ -523,22 +596,33 @@ mod helper { | Drop { target: ref mut t, unwind: _, .. } | Assert { target: ref mut t, unwind: _, .. } | FalseUnwind { real_target: ref mut t, unwind: _ } => { - slice::from_mut(t).into_iter().chain(None) + slice::from_mut(t).into_iter().chain(None.into_iter().chain(None)) } + // No successors UnwindResume | UnwindTerminate(_) | CoroutineDrop | Return | Unreachable | TailCall { .. } - | Call { target: None, unwind: _, .. } => (&mut []).into_iter().chain(None), + | Call { target: None, unwind: _, .. } => { + (&mut []).into_iter().chain(None.into_iter().chain(None)) + } + // Multiple successors InlineAsm { ref mut targets, unwind: UnwindAction::Cleanup(ref mut u), .. } => { - targets.iter_mut().chain(Some(u)) + targets.iter_mut().chain(Some(u).into_iter().chain(None)) + } + InlineAsm { ref mut targets, unwind: _, .. } => { + targets.iter_mut().chain(None.into_iter().chain(None)) + } + SwitchInt { ref mut targets, .. } => { + targets.targets.iter_mut().chain(None.into_iter().chain(None)) } - InlineAsm { ref mut targets, unwind: _, .. } => targets.iter_mut().chain(None), - SwitchInt { ref mut targets, .. } => targets.targets.iter_mut().chain(None), + // FalseEdge FalseEdge { ref mut real_target, ref mut imaginary_target } => { - slice::from_mut(real_target).into_iter().chain(Some(imaginary_target)) + slice::from_mut(real_target) + .into_iter() + .chain(Some(imaginary_target).into_iter().chain(None)) } } } @@ -671,8 +755,10 @@ impl<'tcx> TerminatorKind<'tcx> { Goto { target } => TerminatorEdges::Single(target), + // FIXME: Maybe we need also TerminatorEdges::Trio for async drop + // (target + unwind + dropline) Assert { target, unwind, expected: _, msg: _, cond: _ } - | Drop { target, unwind, place: _, replace: _ } + | Drop { target, unwind, place: _, replace: _, drop: _, async_fut: _ } | FalseUnwind { real_target: target, unwind } => match unwind { UnwindAction::Cleanup(unwind) => TerminatorEdges::Double(target, unwind), UnwindAction::Continue | UnwindAction::Terminate(_) | UnwindAction::Unreachable => { diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs index de4d5140e85..1777756174b 100644 --- a/compiler/rustc_middle/src/mir/visit.rs +++ b/compiler/rustc_middle/src/mir/visit.rs @@ -353,17 +353,21 @@ macro_rules! make_mir_visitor { coroutine_closure_def_id: _def_id, receiver_by_ref: _, } - | ty::InstanceKind::AsyncDropGlueCtorShim(_def_id, None) | ty::InstanceKind::DropGlue(_def_id, None) => {} ty::InstanceKind::FnPtrShim(_def_id, ty) | ty::InstanceKind::DropGlue(_def_id, Some(ty)) | ty::InstanceKind::CloneShim(_def_id, ty) | ty::InstanceKind::FnPtrAddrShim(_def_id, ty) - | ty::InstanceKind::AsyncDropGlueCtorShim(_def_id, Some(ty)) => { + | ty::InstanceKind::AsyncDropGlue(_def_id, ty) + | ty::InstanceKind::AsyncDropGlueCtorShim(_def_id, ty) => { // FIXME(eddyb) use a better `TyContext` here. self.visit_ty($(& $mutability)? *ty, TyContext::Location(location)); } + ty::InstanceKind::FutureDropPollShim(_def_id, proxy_ty, impl_ty) => { + self.visit_ty($(& $mutability)? *proxy_ty, TyContext::Location(location)); + self.visit_ty($(& $mutability)? *impl_ty, TyContext::Location(location)); + } } self.visit_args(callee_args, location); } @@ -521,7 +525,14 @@ macro_rules! make_mir_visitor { self.visit_operand(discr, location); } - TerminatorKind::Drop { place, target: _, unwind: _, replace: _ } => { + TerminatorKind::Drop { + place, + target: _, + unwind: _, + replace: _, + drop: _, + async_fut: _, + } => { self.visit_place( place, PlaceContext::MutatingUse(MutatingUseContext::Drop), @@ -634,7 +645,7 @@ macro_rules! make_mir_visitor { OverflowNeg(op) | DivisionByZero(op) | RemainderByZero(op) => { self.visit_operand(op, location); } - ResumedAfterReturn(_) | ResumedAfterPanic(_) | NullPointerDereference => { + ResumedAfterReturn(_) | ResumedAfterPanic(_) | NullPointerDereference | ResumedAfterDrop(_) => { // Nothing to visit } MisalignedPointerDereference { required, found } => { diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 3432648feab..293b1552beb 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -1359,7 +1359,11 @@ rustc_queries! { /// Generates a MIR body for the shim. query mir_shims(key: ty::InstanceKind<'tcx>) -> &'tcx mir::Body<'tcx> { arena_cache - desc { |tcx| "generating MIR shim for `{}`", tcx.def_path_str(key.def_id()) } + desc { + |tcx| "generating MIR shim for `{}`, instance={:?}", + tcx.def_path_str(key.def_id()), + key + } } /// The `symbol_name` query provides the symbol name for calling a @@ -1590,6 +1594,10 @@ rustc_queries! { query is_unpin_raw(env: ty::PseudoCanonicalInput<'tcx, Ty<'tcx>>) -> bool { desc { "computing whether `{}` is `Unpin`", env.value } } + /// Query backing `Ty::is_async_drop`. + query is_async_drop_raw(env: ty::PseudoCanonicalInput<'tcx, Ty<'tcx>>) -> bool { + desc { "computing whether `{}` is `AsyncDrop`", env.value } + } /// Query backing `Ty::needs_drop`. query needs_drop_raw(env: ty::PseudoCanonicalInput<'tcx, Ty<'tcx>>) -> bool { desc { "computing whether `{}` needs drop", env.value } @@ -1622,6 +1630,14 @@ rustc_queries! { cache_on_disk_if { true } } + /// A list of types where the ADT requires async drop if and only if any of + /// those types require async drop. If the ADT is known to always need async drop + /// then `Err(AlwaysRequiresDrop)` is returned. + query adt_async_drop_tys(def_id: DefId) -> Result<&'tcx ty::List>, AlwaysRequiresDrop> { + desc { |tcx| "computing when `{}` needs async drop", tcx.def_path_str(def_id) } + cache_on_disk_if { true } + } + /// A list of types where the ADT requires drop if and only if any of those types /// has significant drop. A type marked with the attribute `rustc_insignificant_dtor` /// is considered to not be significant. A drop is significant if it is implemented diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index e8dad1e056c..23ee6514622 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -717,7 +717,6 @@ macro_rules! bidirectional_lang_item_map { bidirectional_lang_item_map! { // tidy-alphabetical-start - AsyncDestruct, AsyncFn, AsyncFnKindHelper, AsyncFnKindUpvars, @@ -1715,6 +1714,10 @@ impl<'tcx> TyCtxt<'tcx> { self.coroutine_kind(def_id).is_some() } + pub fn is_async_drop_in_place_coroutine(self, def_id: DefId) -> bool { + self.is_lang_item(self.parent(def_id), LangItem::AsyncDropInPlace) + } + /// Returns the movability of the coroutine of `def_id`, or panics /// if given a `def_id` that is not a coroutine. pub fn coroutine_movability(self, def_id: DefId) -> hir::Movability { diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs index faad0a82acb..d660e7d0d60 100644 --- a/compiler/rustc_middle/src/ty/instance.rs +++ b/compiler/rustc_middle/src/ty/instance.rs @@ -147,6 +147,9 @@ pub enum InstanceKind<'tcx> { /// native support. ThreadLocalShim(DefId), + /// Proxy shim for async drop of future (def_id, proxy_cor_ty, impl_cor_ty) + FutureDropPollShim(DefId, Ty<'tcx>, Ty<'tcx>), + /// `core::ptr::drop_in_place::`. /// /// The `DefId` is for `core::ptr::drop_in_place`. @@ -173,7 +176,13 @@ pub enum InstanceKind<'tcx> { /// /// The `DefId` is for `core::future::async_drop::async_drop_in_place`, the `Ty` /// is the type `T`. - AsyncDropGlueCtorShim(DefId, Option>), + AsyncDropGlueCtorShim(DefId, Ty<'tcx>), + + /// `core::future::async_drop::async_drop_in_place::<'_, T>::{closure}`. + /// + /// async_drop_in_place poll function implementation (for generated coroutine). + /// `Ty` here is `async_drop_in_place::{closure}` coroutine type, not just `T` + AsyncDropGlue(DefId, Ty<'tcx>), } impl<'tcx> Instance<'tcx> { @@ -221,7 +230,9 @@ impl<'tcx> Instance<'tcx> { .upstream_monomorphizations_for(def) .and_then(|monos| monos.get(&self.args).cloned()), InstanceKind::DropGlue(_, Some(_)) => tcx.upstream_drop_glue_for(self.args), - InstanceKind::AsyncDropGlueCtorShim(_, Some(_)) => { + InstanceKind::AsyncDropGlue(_, _) => None, + InstanceKind::FutureDropPollShim(_, _, _) => None, + InstanceKind::AsyncDropGlueCtorShim(_, _) => { tcx.upstream_async_drop_glue_for(self.args) } _ => None, @@ -248,6 +259,8 @@ impl<'tcx> InstanceKind<'tcx> { | InstanceKind::DropGlue(def_id, _) | InstanceKind::CloneShim(def_id, _) | InstanceKind::FnPtrAddrShim(def_id, _) + | InstanceKind::FutureDropPollShim(def_id, _, _) + | InstanceKind::AsyncDropGlue(def_id, _) | InstanceKind::AsyncDropGlueCtorShim(def_id, _) => def_id, } } @@ -257,7 +270,9 @@ impl<'tcx> InstanceKind<'tcx> { match self { ty::InstanceKind::Item(def) => Some(def), ty::InstanceKind::DropGlue(def_id, Some(_)) - | InstanceKind::AsyncDropGlueCtorShim(def_id, Some(_)) + | InstanceKind::AsyncDropGlueCtorShim(def_id, _) + | InstanceKind::AsyncDropGlue(def_id, _) + | InstanceKind::FutureDropPollShim(def_id, ..) | InstanceKind::ThreadLocalShim(def_id) => Some(def_id), InstanceKind::VTableShim(..) | InstanceKind::ReifyShim(..) @@ -267,7 +282,6 @@ impl<'tcx> InstanceKind<'tcx> { | InstanceKind::ClosureOnceShim { .. } | ty::InstanceKind::ConstructCoroutineInClosureShim { .. } | InstanceKind::DropGlue(..) - | InstanceKind::AsyncDropGlueCtorShim(..) | InstanceKind::CloneShim(..) | InstanceKind::FnPtrAddrShim(..) => None, } @@ -292,7 +306,9 @@ impl<'tcx> InstanceKind<'tcx> { let def_id = match *self { ty::InstanceKind::Item(def) => def, ty::InstanceKind::DropGlue(_, Some(_)) => return false, - ty::InstanceKind::AsyncDropGlueCtorShim(_, Some(_)) => return false, + ty::InstanceKind::AsyncDropGlueCtorShim(_, ty) => return ty.is_coroutine(), + ty::InstanceKind::FutureDropPollShim(_, _, _) => return false, + ty::InstanceKind::AsyncDropGlue(_, _) => return false, ty::InstanceKind::ThreadLocalShim(_) => return false, _ => return true, }; @@ -325,11 +341,12 @@ impl<'tcx> InstanceKind<'tcx> { | InstanceKind::FnPtrAddrShim(..) | InstanceKind::FnPtrShim(..) | InstanceKind::DropGlue(_, Some(_)) - | InstanceKind::AsyncDropGlueCtorShim(_, Some(_)) => false, + | InstanceKind::FutureDropPollShim(..) + | InstanceKind::AsyncDropGlue(_, _) => false, + InstanceKind::AsyncDropGlueCtorShim(_, _) => false, InstanceKind::ClosureOnceShim { .. } | InstanceKind::ConstructCoroutineInClosureShim { .. } | InstanceKind::DropGlue(..) - | InstanceKind::AsyncDropGlueCtorShim(..) | InstanceKind::Item(_) | InstanceKind::Intrinsic(..) | InstanceKind::ReifyShim(..) @@ -406,8 +423,11 @@ pub fn fmt_instance( InstanceKind::DropGlue(_, Some(ty)) => write!(f, " - shim(Some({ty}))"), InstanceKind::CloneShim(_, ty) => write!(f, " - shim({ty})"), InstanceKind::FnPtrAddrShim(_, ty) => write!(f, " - shim({ty})"), - InstanceKind::AsyncDropGlueCtorShim(_, None) => write!(f, " - shim(None)"), - InstanceKind::AsyncDropGlueCtorShim(_, Some(ty)) => write!(f, " - shim(Some({ty}))"), + InstanceKind::FutureDropPollShim(_, proxy_ty, impl_ty) => { + write!(f, " - dropshim({proxy_ty}-{impl_ty})") + } + InstanceKind::AsyncDropGlue(_, ty) => write!(f, " - shim({ty})"), + InstanceKind::AsyncDropGlueCtorShim(_, ty) => write!(f, " - shim(Some({ty}))"), } } @@ -425,6 +445,51 @@ impl<'tcx> fmt::Display for Instance<'tcx> { } } +// async_drop_in_place::coroutine.poll, when T is a standart coroutine, +// should be resolved to this coroutine's future_drop_poll (through FutureDropPollShim proxy). +// async_drop_in_place::coroutine>::coroutine.poll, +// when T is a standart coroutine, should be resolved to this coroutine's future_drop_poll. +// async_drop_in_place::coroutine>::coroutine.poll, +// when T is not a coroutine, should be resolved to the innermost +// async_drop_in_place::coroutine's poll function (through FutureDropPollShim proxy) +fn resolve_async_drop_poll<'tcx>(mut cor_ty: Ty<'tcx>) -> Instance<'tcx> { + let first_cor = cor_ty; + let ty::Coroutine(poll_def_id, proxy_args) = first_cor.kind() else { + bug!(); + }; + let poll_def_id = *poll_def_id; + let mut child_ty = cor_ty; + loop { + if let ty::Coroutine(child_def, child_args) = child_ty.kind() { + cor_ty = child_ty; + if *child_def == poll_def_id { + child_ty = child_args.first().unwrap().expect_ty(); + continue; + } else { + return Instance { + def: ty::InstanceKind::FutureDropPollShim(poll_def_id, first_cor, cor_ty), + args: proxy_args, + }; + } + } else { + let ty::Coroutine(_, child_args) = cor_ty.kind() else { + bug!(); + }; + if first_cor != cor_ty { + return Instance { + def: ty::InstanceKind::FutureDropPollShim(poll_def_id, first_cor, cor_ty), + args: proxy_args, + }; + } else { + return Instance { + def: ty::InstanceKind::AsyncDropGlue(poll_def_id, cor_ty), + args: child_args, + }; + } + } + } +} + impl<'tcx> Instance<'tcx> { pub fn new(def_id: DefId, args: GenericArgsRef<'tcx>) -> Instance<'tcx> { assert!( @@ -736,6 +801,15 @@ impl<'tcx> Instance<'tcx> { ) } + pub fn resolve_async_drop_in_place_poll( + tcx: TyCtxt<'tcx>, + def_id: DefId, + ty: Ty<'tcx>, + ) -> ty::Instance<'tcx> { + let args = tcx.mk_args(&[ty.into()]); + Instance::expect_resolve(tcx, ty::TypingEnv::fully_monomorphized(), def_id, args, DUMMY_SP) + } + #[instrument(level = "debug", skip(tcx), ret)] pub fn fn_once_adapter_instance( tcx: TyCtxt<'tcx>, @@ -800,6 +874,9 @@ impl<'tcx> Instance<'tcx> { }; if tcx.is_lang_item(trait_item_id, coroutine_callable_item) { + if tcx.is_async_drop_in_place_coroutine(coroutine_def_id) { + return Some(resolve_async_drop_poll(rcvr_args.type_at(0))); + } let ty::Coroutine(_, id_args) = *tcx.type_of(coroutine_def_id).skip_binder().kind() else { bug!() diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index be00c0e116d..eba6d61ba7d 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -17,7 +17,7 @@ use std::hash::{Hash, Hasher}; use std::marker::PhantomData; use std::num::NonZero; use std::ptr::NonNull; -use std::{fmt, str}; +use std::{fmt, iter, str}; pub use adt::*; pub use assoc::*; @@ -39,6 +39,7 @@ use rustc_hir::LangItem; use rustc_hir::def::{CtorKind, CtorOf, DefKind, DocLinkResMap, LifetimeRes, Res}; use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LocalDefId, LocalDefIdMap}; use rustc_index::IndexVec; +use rustc_index::bit_set::BitMatrix; use rustc_macros::{ Decodable, Encodable, HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable, extension, @@ -103,7 +104,7 @@ pub use self::visit::*; use crate::error::{OpaqueHiddenTypeMismatch, TypeMismatchReason}; use crate::metadata::ModChild; use crate::middle::privacy::EffectiveVisibilities; -use crate::mir::{Body, CoroutineLayout}; +use crate::mir::{Body, CoroutineLayout, CoroutineSavedLocal, SourceInfo}; use crate::query::{IntoQueryParam, Providers}; use crate::ty; use crate::ty::codec::{TyDecoder, TyEncoder}; @@ -1739,11 +1740,13 @@ impl<'tcx> TyCtxt<'tcx> { | ty::InstanceKind::Virtual(..) | ty::InstanceKind::ClosureOnceShim { .. } | ty::InstanceKind::ConstructCoroutineInClosureShim { .. } + | ty::InstanceKind::FutureDropPollShim(..) | ty::InstanceKind::DropGlue(..) | ty::InstanceKind::CloneShim(..) | ty::InstanceKind::ThreadLocalShim(..) | ty::InstanceKind::FnPtrAddrShim(..) - | ty::InstanceKind::AsyncDropGlueCtorShim(..) => self.mir_shims(instance), + | ty::InstanceKind::AsyncDropGlueCtorShim(..) + | ty::InstanceKind::AsyncDropGlue(..) => self.mir_shims(instance), } } @@ -1859,12 +1862,12 @@ impl<'tcx> TyCtxt<'tcx> { self.def_kind(trait_def_id) == DefKind::TraitAlias } - /// Returns layout of a coroutine. Layout might be unavailable if the + /// Returns layout of a non-async-drop coroutine. Layout might be unavailable if the /// coroutine is tainted by errors. /// /// Takes `coroutine_kind` which can be acquired from the `CoroutineArgs::kind_ty`, /// e.g. `args.as_coroutine().kind_ty()`. - pub fn coroutine_layout( + fn ordinary_coroutine_layout( self, def_id: DefId, coroutine_kind_ty: Ty<'tcx>, @@ -1898,6 +1901,51 @@ impl<'tcx> TyCtxt<'tcx> { } } + /// Returns layout of a `async_drop_in_place::{closure}` coroutine + /// (returned from `async fn async_drop_in_place(..)`). + /// Layout might be unavailable if the coroutine is tainted by errors. + fn async_drop_coroutine_layout( + self, + def_id: DefId, + args: GenericArgsRef<'tcx>, + ) -> Option<&'tcx CoroutineLayout<'tcx>> { + let instance = InstanceKind::AsyncDropGlue(def_id, Ty::new_coroutine(self, def_id, args)); + self.mir_shims(instance).coroutine_layout_raw() + } + + /// Returns layout of a coroutine. Layout might be unavailable if the + /// coroutine is tainted by errors. + pub fn coroutine_layout( + self, + def_id: DefId, + args: GenericArgsRef<'tcx>, + ) -> Option<&'tcx CoroutineLayout<'tcx>> { + if self.is_async_drop_in_place_coroutine(def_id) { + // layout of `async_drop_in_place::{closure}` in case, + // when T is a coroutine, contains this internal coroutine's ptr in upvars + // and doesn't require any locals. Here is an `empty coroutine's layout` + let arg_cor_ty = args.first().unwrap().expect_ty(); + if arg_cor_ty.is_coroutine() { + let span = self.def_span(def_id); + let source_info = SourceInfo::outermost(span); + let variant_fields: IndexVec> = + iter::repeat(IndexVec::new()).take(CoroutineArgs::RESERVED_VARIANTS).collect(); + let proxy_layout = CoroutineLayout { + field_tys: [].into(), + field_names: [].into(), + variant_fields, + variant_source_info: [source_info].into(), + storage_conflicts: BitMatrix::new(0, 0), + }; + return Some(self.arena.alloc(proxy_layout)); + } else { + self.async_drop_coroutine_layout(def_id, args) + } + } else { + self.ordinary_coroutine_layout(def_id, args.as_coroutine().kind_ty()) + } + } + /// Given the `DefId` of an impl, returns the `DefId` of the trait it implements. /// If it implements no trait, returns `None`. pub fn trait_id_of_impl(self, def_id: DefId) -> Option { diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index affb7b31ae1..b6043bc740f 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -4,7 +4,6 @@ use std::assert_matches::debug_assert_matches; use std::borrow::Cow; -use std::iter; use std::ops::{ControlFlow, Range}; use hir::def::{CtorKind, DefKind}; @@ -19,7 +18,7 @@ use rustc_type_ir::TyKind::*; use rustc_type_ir::walk::TypeWalker; use rustc_type_ir::{self as ir, BoundVar, CollectAndApply, DynKind, TypeVisitableExt, elaborate}; use tracing::instrument; -use ty::util::{AsyncDropGlueMorphology, IntTypeExt}; +use ty::util::IntTypeExt; use super::GenericParamDefKind; use crate::infer::canonical::Canonical; @@ -78,8 +77,7 @@ impl<'tcx> ty::CoroutineArgs> { #[inline] fn variant_range(&self, def_id: DefId, tcx: TyCtxt<'tcx>) -> Range { // FIXME requires optimized MIR - FIRST_VARIANT - ..tcx.coroutine_layout(def_id, tcx.types.unit).unwrap().variant_fields.next_index() + FIRST_VARIANT..tcx.coroutine_layout(def_id, self.args).unwrap().variant_fields.next_index() } /// The discriminant for the given variant. Panics if the `variant_index` is @@ -139,10 +137,14 @@ impl<'tcx> ty::CoroutineArgs> { def_id: DefId, tcx: TyCtxt<'tcx>, ) -> impl Iterator>> { - let layout = tcx.coroutine_layout(def_id, self.kind_ty()).unwrap(); + let layout = tcx.coroutine_layout(def_id, self.args).unwrap(); layout.variant_fields.iter().map(move |variant| { variant.iter().map(move |field| { - ty::EarlyBinder::bind(layout.field_tys[*field].ty).instantiate(tcx, self.args) + if tcx.is_async_drop_in_place_coroutine(def_id) { + layout.field_tys[*field].ty + } else { + ty::EarlyBinder::bind(layout.field_tys[*field].ty).instantiate(tcx, self.args) + } }) }) } @@ -1046,10 +1048,6 @@ impl<'tcx> rustc_type_ir::inherent::Ty> for Ty<'tcx> { self.discriminant_ty(interner) } - fn async_destructor_ty(self, interner: TyCtxt<'tcx>) -> Ty<'tcx> { - self.async_destructor_ty(interner) - } - fn has_unsafe_fields(self) -> bool { Ty::has_unsafe_fields(self) } @@ -1419,6 +1417,34 @@ impl<'tcx> Ty<'tcx> { cf.is_break() } + /// Returns the deepest `async_drop_in_place::{closure}` implementation. + /// + /// `async_drop_in_place::{closure}`, when T is a coroutine, is a proxy-impl + /// to call async drop poll from impl coroutine. + pub fn find_async_drop_impl_coroutine)>( + self, + tcx: TyCtxt<'tcx>, + mut f: F, + ) -> Ty<'tcx> { + assert!(self.is_coroutine()); + let mut cor_ty = self; + let mut ty = cor_ty; + loop { + if let ty::Coroutine(def_id, args) = ty.kind() { + cor_ty = ty; + f(ty); + if tcx.is_async_drop_in_place_coroutine(*def_id) { + ty = args.first().unwrap().expect_ty(); + continue; + } else { + return cor_ty; + } + } else { + return cor_ty; + } + } + } + /// Returns the type and mutability of `*ty`. /// /// The parameter `explicit` indicates if this is an *explicit* dereference. @@ -1560,125 +1586,6 @@ impl<'tcx> Ty<'tcx> { } } - /// Returns the type of the async destructor of this type. - pub fn async_destructor_ty(self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> { - match self.async_drop_glue_morphology(tcx) { - AsyncDropGlueMorphology::Noop => { - return Ty::async_destructor_combinator(tcx, LangItem::AsyncDropNoop) - .instantiate_identity(); - } - AsyncDropGlueMorphology::DeferredDropInPlace => { - let drop_in_place = - Ty::async_destructor_combinator(tcx, LangItem::AsyncDropDeferredDropInPlace) - .instantiate(tcx, &[self.into()]); - return Ty::async_destructor_combinator(tcx, LangItem::AsyncDropFuse) - .instantiate(tcx, &[drop_in_place.into()]); - } - AsyncDropGlueMorphology::Custom => (), - } - - match *self.kind() { - ty::Param(_) | ty::Alias(..) | ty::Infer(ty::TyVar(_)) => { - let assoc_items = tcx - .associated_item_def_ids(tcx.require_lang_item(LangItem::AsyncDestruct, None)); - Ty::new_projection(tcx, assoc_items[0], [self]) - } - - ty::Array(elem_ty, _) | ty::Slice(elem_ty) => { - let dtor = Ty::async_destructor_combinator(tcx, LangItem::AsyncDropSlice) - .instantiate(tcx, &[elem_ty.into()]); - Ty::async_destructor_combinator(tcx, LangItem::AsyncDropFuse) - .instantiate(tcx, &[dtor.into()]) - } - - ty::Adt(adt_def, args) if adt_def.is_enum() || adt_def.is_struct() => self - .adt_async_destructor_ty( - tcx, - adt_def.variants().iter().map(|v| v.fields.iter().map(|f| f.ty(tcx, args))), - ), - ty::Tuple(tys) => self.adt_async_destructor_ty(tcx, iter::once(tys)), - ty::Closure(_, args) => { - self.adt_async_destructor_ty(tcx, iter::once(args.as_closure().upvar_tys())) - } - ty::CoroutineClosure(_, args) => self - .adt_async_destructor_ty(tcx, iter::once(args.as_coroutine_closure().upvar_tys())), - - ty::Adt(adt_def, _) => { - assert!(adt_def.is_union()); - - let surface_drop = self.surface_async_dropper_ty(tcx).unwrap(); - - Ty::async_destructor_combinator(tcx, LangItem::AsyncDropFuse) - .instantiate(tcx, &[surface_drop.into()]) - } - - ty::Bound(..) - | ty::Foreign(_) - | ty::Placeholder(_) - | ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => { - bug!("`async_destructor_ty` applied to unexpected type: {self:?}") - } - - _ => bug!("`async_destructor_ty` is not yet implemented for type: {self:?}"), - } - } - - fn adt_async_destructor_ty(self, tcx: TyCtxt<'tcx>, variants: I) -> Ty<'tcx> - where - I: Iterator + ExactSizeIterator, - I::Item: IntoIterator>, - { - debug_assert_eq!(self.async_drop_glue_morphology(tcx), AsyncDropGlueMorphology::Custom); - - let defer = Ty::async_destructor_combinator(tcx, LangItem::AsyncDropDefer); - let chain = Ty::async_destructor_combinator(tcx, LangItem::AsyncDropChain); - - let noop = - Ty::async_destructor_combinator(tcx, LangItem::AsyncDropNoop).instantiate_identity(); - let either = Ty::async_destructor_combinator(tcx, LangItem::AsyncDropEither); - - let variants_dtor = variants - .into_iter() - .map(|variant| { - variant - .into_iter() - .map(|ty| defer.instantiate(tcx, &[ty.into()])) - .reduce(|acc, next| chain.instantiate(tcx, &[acc.into(), next.into()])) - .unwrap_or(noop) - }) - .reduce(|other, matched| { - either.instantiate(tcx, &[other.into(), matched.into(), self.into()]) - }) - .unwrap(); - - let dtor = if let Some(dropper_ty) = self.surface_async_dropper_ty(tcx) { - Ty::async_destructor_combinator(tcx, LangItem::AsyncDropChain) - .instantiate(tcx, &[dropper_ty.into(), variants_dtor.into()]) - } else { - variants_dtor - }; - - Ty::async_destructor_combinator(tcx, LangItem::AsyncDropFuse) - .instantiate(tcx, &[dtor.into()]) - } - - fn surface_async_dropper_ty(self, tcx: TyCtxt<'tcx>) -> Option> { - let adt_def = self.ty_adt_def()?; - let dropper = adt_def - .async_destructor(tcx) - .map(|_| LangItem::SurfaceAsyncDropInPlace) - .or_else(|| adt_def.destructor(tcx).map(|_| LangItem::AsyncDropSurfaceDropInPlace))?; - Some(Ty::async_destructor_combinator(tcx, dropper).instantiate(tcx, &[self.into()])) - } - - fn async_destructor_combinator( - tcx: TyCtxt<'tcx>, - lang_item: LangItem, - ) -> ty::EarlyBinder<'tcx, Ty<'tcx>> { - tcx.fn_sig(tcx.require_lang_item(lang_item, None)) - .map_bound(|fn_sig| fn_sig.output().no_bound_vars().unwrap()) - } - /// Returns the type of metadata for (potentially wide) pointers to this type, /// or the struct tail if the metadata type cannot be determined. pub fn ptr_metadata_ty_or_tail( @@ -2020,6 +1927,13 @@ impl<'tcx> Ty<'tcx> { } } + pub fn is_async_drop_in_place_coroutine(self, tcx: TyCtxt<'_>) -> bool { + match self.kind() { + ty::Coroutine(def, ..) => tcx.is_async_drop_in_place_coroutine(*def), + _ => false, + } + } + /// Returns `true` when the outermost type cannot be further normalized, /// resolved, or instantiated. This includes all primitive types, but also /// things like ADTs and trait objects, since even if their arguments or diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index 08cee1101d0..f46a1d4b22e 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -468,25 +468,6 @@ impl<'tcx> TyCtxt<'tcx> { Some(ty::AsyncDestructor { impl_did: dtor_candidate? }) } - /// Returns async drop glue morphology for a definition. To get async drop - /// glue morphology for a type see [`Ty::async_drop_glue_morphology`]. - // - // FIXME: consider making this a query - pub fn async_drop_glue_morphology(self, did: DefId) -> AsyncDropGlueMorphology { - let ty: Ty<'tcx> = self.type_of(did).instantiate_identity(); - - // Async drop glue morphology is an internal detail, so - // using `TypingMode::PostAnalysis` probably should be fine. - let typing_env = ty::TypingEnv::fully_monomorphized(); - if ty.needs_async_drop(self, typing_env) { - AsyncDropGlueMorphology::Custom - } else if ty.needs_drop(self, typing_env) { - AsyncDropGlueMorphology::DeferredDropInPlace - } else { - AsyncDropGlueMorphology::Noop - } - } - /// Returns the set of types that are required to be alive in /// order to run the destructor of `def` (see RFCs 769 and /// 1238). @@ -1114,18 +1095,6 @@ impl<'tcx> TypeFolder> for WeakAliasTypeExpander<'tcx> { } } -/// Indicates the form of `AsyncDestruct::Destructor`. Used to simplify async -/// drop glue for types not using async drop. -#[derive(Clone, Copy, PartialEq, Eq, Debug)] -pub enum AsyncDropGlueMorphology { - /// Async destructor simply does nothing - Noop, - /// Async destructor simply runs `drop_in_place` - DeferredDropInPlace, - /// Async destructor has custom logic - Custom, -} - impl<'tcx> Ty<'tcx> { /// Returns the `Size` for primitive types (bool, uint, int, char, float). pub fn primitive_size(self, tcx: TyCtxt<'tcx>) -> Size { @@ -1295,16 +1264,17 @@ impl<'tcx> Ty<'tcx> { } } - /// Get morphology of the async drop glue, needed for types which do not - /// use async drop. To get async drop glue morphology for a definition see - /// [`TyCtxt::async_drop_glue_morphology`]. Used for `AsyncDestruct::Destructor` - /// type construction. - // - // FIXME: implement optimization to not instantiate a certain morphology of - // async drop glue too soon to allow per type optimizations, see array case - // for more info. Perhaps then remove this method and use `needs_(async_)drop` - // instead. - pub fn async_drop_glue_morphology(self, tcx: TyCtxt<'tcx>) -> AsyncDropGlueMorphology { + /// Checks whether values of this type `T` implement the `AsyncDrop` trait. + pub fn is_async_drop(self, tcx: TyCtxt<'tcx>, typing_env: ty::TypingEnv<'tcx>) -> bool { + !self.is_trivially_not_async_drop() + && tcx.is_async_drop_raw(typing_env.as_query_input(self)) + } + + /// Fast path helper for testing if a type is `AsyncDrop`. + /// + /// Returning true means the type is known to be `!AsyncDrop`. Returning + /// `false` means nothing -- could be `AsyncDrop`, might not be. + fn is_trivially_not_async_drop(self) -> bool { match self.kind() { ty::Int(_) | ty::Uint(_) @@ -1316,46 +1286,26 @@ impl<'tcx> Ty<'tcx> { | ty::Ref(..) | ty::RawPtr(..) | ty::FnDef(..) - | ty::FnPtr(..) - | ty::Infer(ty::FreshIntTy(_)) - | ty::Infer(ty::FreshFloatTy(_)) => AsyncDropGlueMorphology::Noop, - + | ty::Error(_) + | ty::FnPtr(..) => true, // FIXME(unsafe_binders): ty::UnsafeBinder(_) => todo!(), - - ty::Tuple(tys) if tys.is_empty() => AsyncDropGlueMorphology::Noop, - ty::Adt(adt_def, _) if adt_def.is_manually_drop() => AsyncDropGlueMorphology::Noop, - - // Foreign types can never have destructors. - ty::Foreign(_) => AsyncDropGlueMorphology::Noop, - - // FIXME: implement dynamic types async drops - ty::Error(_) | ty::Dynamic(..) => AsyncDropGlueMorphology::DeferredDropInPlace, - - ty::Tuple(_) | ty::Array(_, _) | ty::Slice(_) => { - // Assume worst-case scenario, because we can instantiate async - // destructors in different orders: - // - // 1. Instantiate [T; N] with T = String and N = 0 - // 2. Instantiate <[String; 0] as AsyncDestruct>::Destructor - // - // And viceversa, thus we cannot rely on String not using async - // drop or array having zero (0) elements - AsyncDropGlueMorphology::Custom - } - ty::Pat(ty, _) => ty.async_drop_glue_morphology(tcx), - - ty::Adt(adt_def, _) => tcx.async_drop_glue_morphology(adt_def.did()), - - ty::Closure(did, _) - | ty::CoroutineClosure(did, _) - | ty::Coroutine(did, _) - | ty::CoroutineWitness(did, _) => tcx.async_drop_glue_morphology(*did), - - ty::Alias(..) | ty::Param(_) | ty::Bound(..) | ty::Placeholder(..) | ty::Infer(_) => { - // No specifics, but would usually mean forwarding async drop glue - AsyncDropGlueMorphology::Custom + ty::Tuple(fields) => fields.iter().all(Self::is_trivially_not_async_drop), + ty::Pat(elem_ty, _) | ty::Slice(elem_ty) | ty::Array(elem_ty, _) => { + elem_ty.is_trivially_not_async_drop() } + ty::Adt(..) + | ty::Bound(..) + | ty::Closure(..) + | ty::CoroutineClosure(..) + | ty::Dynamic(..) + | ty::Foreign(_) + | ty::Coroutine(..) + | ty::CoroutineWitness(..) + | ty::Infer(_) + | ty::Alias(..) + | ty::Param(_) + | ty::Placeholder(_) => false, } } @@ -1401,9 +1351,6 @@ impl<'tcx> Ty<'tcx> { /// (Note that this implies that if `ty` has an async destructor attached, /// then `needs_async_drop` will definitely return `true` for `ty`.) /// - /// When constructing `AsyncDestruct::Destructor` type, use - /// [`Ty::async_drop_glue_morphology`] instead. - // // FIXME(zetanumbers): Note that this method is used to check eligible types // in unions. #[inline] diff --git a/compiler/rustc_mir_build/src/builder/custom/parse/instruction.rs b/compiler/rustc_mir_build/src/builder/custom/parse/instruction.rs index 5918498f239..494ee33fd8b 100644 --- a/compiler/rustc_mir_build/src/builder/custom/parse/instruction.rs +++ b/compiler/rustc_mir_build/src/builder/custom/parse/instruction.rs @@ -69,6 +69,8 @@ impl<'a, 'tcx> ParseCtxt<'a, 'tcx> { target: self.parse_return_to(args[1])?, unwind: self.parse_unwind_action(args[2])?, replace: false, + drop: None, + async_fut: None, }) }, @call(mir_call, args) => { diff --git a/compiler/rustc_mir_build/src/builder/expr/as_rvalue.rs b/compiler/rustc_mir_build/src/builder/expr/as_rvalue.rs index f9791776f71..5a97b08db28 100644 --- a/compiler/rustc_mir_build/src/builder/expr/as_rvalue.rs +++ b/compiler/rustc_mir_build/src/builder/expr/as_rvalue.rs @@ -762,6 +762,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { target: success, unwind: UnwindAction::Continue, replace: false, + drop: None, + async_fut: None, }, ); this.diverge_from(block); diff --git a/compiler/rustc_mir_build/src/builder/scope.rs b/compiler/rustc_mir_build/src/builder/scope.rs index 4e4b11b8fa6..7c287129820 100644 --- a/compiler/rustc_mir_build/src/builder/scope.rs +++ b/compiler/rustc_mir_build/src/builder/scope.rs @@ -89,6 +89,7 @@ use rustc_index::{IndexSlice, IndexVec}; use rustc_middle::middle::region; use rustc_middle::mir::*; use rustc_middle::thir::{ExprId, LintLevel}; +use rustc_middle::ty::{self, TyCtxt}; use rustc_middle::{bug, span_bug}; use rustc_session::lint::Level; use rustc_span::source_map::Spanned; @@ -405,6 +406,8 @@ impl DropTree { unwind: UnwindAction::Terminate(UnwindTerminateReason::InCleanup), place: drop_node.data.local.into(), replace: false, + drop: None, + async_fut: None, }; cfg.terminate(block, drop_node.data.source_info, terminator); } @@ -848,6 +851,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { target: next, unwind: UnwindAction::Continue, replace: false, + drop: None, + async_fut: None, }, ); block = next; @@ -879,6 +884,22 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { block.unit() } + fn is_async_drop_impl( + tcx: TyCtxt<'tcx>, + local_decls: &IndexVec>, + typing_env: ty::TypingEnv<'tcx>, + local: Local, + ) -> bool { + let ty = local_decls[local].ty; + if ty.is_async_drop(tcx, typing_env) || ty.is_coroutine() { + return true; + } + ty.needs_async_drop(tcx, typing_env) + } + fn is_async_drop(&self, local: Local) -> bool { + Self::is_async_drop_impl(self.tcx, &self.local_decls, self.typing_env(), local) + } + fn leave_top_scope(&mut self, block: BasicBlock) -> BasicBlock { // If we are emitting a `drop` statement, we need to have the cached // diverge cleanup pads ready in case that drop panics. @@ -887,14 +908,22 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let unwind_to = if needs_cleanup { self.diverge_cleanup() } else { DropIdx::MAX }; let scope = self.scopes.scopes.last().expect("leave_top_scope called with no scopes"); + let has_async_drops = is_coroutine + && scope.drops.iter().any(|v| v.kind == DropKind::Value && self.is_async_drop(v.local)); + let dropline_to = if has_async_drops { Some(self.diverge_dropline()) } else { None }; + let scope = self.scopes.scopes.last().expect("leave_top_scope called with no scopes"); + let typing_env = self.typing_env(); build_scope_drops( &mut self.cfg, &mut self.scopes.unwind_drops, + &mut self.scopes.coroutine_drops, scope, block, unwind_to, + dropline_to, is_coroutine && needs_cleanup, self.arg_count, + |v: Local| Self::is_async_drop_impl(self.tcx, &self.local_decls, typing_env, v), ) .into_block() } @@ -1310,22 +1339,22 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { self.scopes.unwind_drops.add_entry_point(start, next_drop); } - /// Sets up a path that performs all required cleanup for dropping a - /// coroutine, starting from the given block that ends in - /// [TerminatorKind::Yield]. - /// - /// This path terminates in CoroutineDrop. - pub(crate) fn coroutine_drop_cleanup(&mut self, yield_block: BasicBlock) { + /// Returns the [DropIdx] for the innermost drop for dropline (coroutine drop path). + /// The `DropIdx` will be created if it doesn't already exist. + fn diverge_dropline(&mut self) -> DropIdx { + // It is okay to use dummy span because the getting scope index on the topmost scope + // must always succeed. + self.diverge_dropline_target(self.scopes.topmost(), DUMMY_SP) + } + + /// Similar to diverge_cleanup_target, but for dropline (coroutine drop path) + fn diverge_dropline_target(&mut self, target_scope: region::Scope, span: Span) -> DropIdx { debug_assert!( - matches!( - self.cfg.block_data(yield_block).terminator().kind, - TerminatorKind::Yield { .. } - ), - "coroutine_drop_cleanup called on block with non-yield terminator." + self.coroutine.is_some(), + "diverge_dropline_target is valid only for coroutine" ); - let (uncached_scope, mut cached_drop) = self - .scopes - .scopes + let target = self.scopes.scope_index(target_scope, span); + let (uncached_scope, mut cached_drop) = self.scopes.scopes[..=target] .iter() .enumerate() .rev() @@ -1334,13 +1363,34 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { }) .unwrap_or((0, ROOT_NODE)); - for scope in &mut self.scopes.scopes[uncached_scope..] { + if uncached_scope > target { + return cached_drop; + } + + for scope in &mut self.scopes.scopes[uncached_scope..=target] { for drop in &scope.drops { cached_drop = self.scopes.coroutine_drops.add_drop(*drop, cached_drop); } scope.cached_coroutine_drop_block = Some(cached_drop); } + cached_drop + } + + /// Sets up a path that performs all required cleanup for dropping a + /// coroutine, starting from the given block that ends in + /// [TerminatorKind::Yield]. + /// + /// This path terminates in CoroutineDrop. + pub(crate) fn coroutine_drop_cleanup(&mut self, yield_block: BasicBlock) { + debug_assert!( + matches!( + self.cfg.block_data(yield_block).terminator().kind, + TerminatorKind::Yield { .. } + ), + "coroutine_drop_cleanup called on block with non-yield terminator." + ); + let cached_drop = self.diverge_dropline(); self.scopes.coroutine_drops.add_entry_point(yield_block, cached_drop); } @@ -1371,6 +1421,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { target: assign, unwind: UnwindAction::Cleanup(assign_unwind), replace: true, + drop: None, + async_fut: None, }, ); self.diverge_from(block); @@ -1432,18 +1484,26 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { /// * `unwind_to`, describes the drops that would occur at this point in the code if a /// panic occurred (a subset of the drops in `scope`, since we sometimes elide StorageDead and other /// instructions on unwinding) +/// * `dropline_to`, describes the drops that would occur at this point in the code if a +/// coroutine drop occured. /// * `storage_dead_on_unwind`, if true, then we should emit `StorageDead` even when unwinding /// * `arg_count`, number of MIR local variables corresponding to fn arguments (used to assert that we don't drop those) -fn build_scope_drops<'tcx>( +fn build_scope_drops<'tcx, F>( cfg: &mut CFG<'tcx>, unwind_drops: &mut DropTree, + coroutine_drops: &mut DropTree, scope: &Scope, block: BasicBlock, unwind_to: DropIdx, + dropline_to: Option, storage_dead_on_unwind: bool, arg_count: usize, -) -> BlockAnd<()> { - debug!("build_scope_drops({:?} -> {:?})", block, scope); + is_async_drop: F, +) -> BlockAnd<()> +where + F: Fn(Local) -> bool, +{ + debug!("build_scope_drops({:?} -> {:?}), dropline_to={:?}", block, scope, dropline_to); // Build up the drops in evaluation order. The end result will // look like: @@ -1476,6 +1536,9 @@ fn build_scope_drops<'tcx>( // will branch to `drops[n]`. let mut block = block; + // `dropline_to` indicates what needs to be dropped should coroutine drop occur. + let mut dropline_to = dropline_to; + for drop_data in scope.drops.iter().rev() { let source_info = drop_data.source_info; let local = drop_data.local; @@ -1492,6 +1555,12 @@ fn build_scope_drops<'tcx>( debug_assert_eq!(unwind_drops.drops[unwind_to].data.kind, drop_data.kind); unwind_to = unwind_drops.drops[unwind_to].next; + if let Some(idx) = dropline_to { + debug_assert_eq!(coroutine_drops.drops[idx].data.local, drop_data.local); + debug_assert_eq!(coroutine_drops.drops[idx].data.kind, drop_data.kind); + dropline_to = Some(coroutine_drops.drops[idx].next); + } + // If the operand has been moved, and we are not on an unwind // path, then don't generate the drop. (We only take this into // account for non-unwind paths so as not to disturb the @@ -1501,6 +1570,12 @@ fn build_scope_drops<'tcx>( } unwind_drops.add_entry_point(block, unwind_to); + if let Some(to) = dropline_to + && is_async_drop(local) + { + coroutine_drops.add_entry_point(block, to); + } + let next = cfg.start_new_block(); cfg.terminate( block, @@ -1510,6 +1585,8 @@ fn build_scope_drops<'tcx>( target: next, unwind: UnwindAction::Continue, replace: false, + drop: None, + async_fut: None, }, ); block = next; @@ -1556,6 +1633,11 @@ fn build_scope_drops<'tcx>( debug_assert_eq!(unwind_drops.drops[unwind_to].data.kind, drop_data.kind); unwind_to = unwind_drops.drops[unwind_to].next; } + if let Some(idx) = dropline_to { + debug_assert_eq!(coroutine_drops.drops[idx].data.local, drop_data.local); + debug_assert_eq!(coroutine_drops.drops[idx].data.kind, drop_data.kind); + dropline_to = Some(coroutine_drops.drops[idx].next); + } // Only temps and vars need their storage dead. assert!(local.index() > arg_count); cfg.push(block, Statement { source_info, kind: StatementKind::StorageDead(local) }); @@ -1611,6 +1693,39 @@ impl<'a, 'tcx: 'a> Builder<'a, 'tcx> { } } } + // Link the exit drop tree to dropline drop tree (coroutine drop path) for async drops + if is_coroutine + && drops.drops.iter().any(|DropNode { data, next: _ }| { + data.kind == DropKind::Value && self.is_async_drop(data.local) + }) + { + let dropline_target = self.diverge_dropline_target(else_scope, span); + let mut dropline_indices = IndexVec::from_elem_n(dropline_target, 1); + for (drop_idx, drop_data) in drops.drops.iter_enumerated().skip(1) { + match drop_data.data.kind { + DropKind::Storage | DropKind::ForLint => { + let coroutine_drop = self + .scopes + .coroutine_drops + .add_drop(drop_data.data, dropline_indices[drop_data.next]); + dropline_indices.push(coroutine_drop); + } + DropKind::Value => { + let coroutine_drop = self + .scopes + .coroutine_drops + .add_drop(drop_data.data, dropline_indices[drop_data.next]); + if self.is_async_drop(drop_data.data.local) { + self.scopes.coroutine_drops.add_entry_point( + blocks[drop_idx].unwrap(), + dropline_indices[drop_data.next], + ); + } + dropline_indices.push(coroutine_drop); + } + } + } + } blocks[ROOT_NODE].map(BasicBlock::unit) } @@ -1655,9 +1770,11 @@ impl<'a, 'tcx: 'a> Builder<'a, 'tcx> { // to be captured by the coroutine. I'm not sure how important this // optimization is, but it is here. for (drop_idx, drop_node) in drops.drops.iter_enumerated() { - if let DropKind::Value = drop_node.data.kind { + if let DropKind::Value = drop_node.data.kind + && let Some(bb) = blocks[drop_idx] + { debug_assert!(drop_node.next < drops.drops.next_index()); - drops.entry_points.push((drop_node.next, blocks[drop_idx].unwrap())); + drops.entry_points.push((drop_node.next, bb)); } } Self::build_unwind_tree(cfg, drops, fn_span, resume_block); @@ -1709,6 +1826,8 @@ impl<'tcx> DropTreeBuilder<'tcx> for CoroutineDrop { let term = cfg.block_data_mut(from).terminator_mut(); if let TerminatorKind::Yield { ref mut drop, .. } = term.kind { *drop = Some(to); + } else if let TerminatorKind::Drop { ref mut drop, .. } = term.kind { + *drop = Some(to); } else { span_bug!( term.source_info.span, diff --git a/compiler/rustc_mir_dataflow/src/impls/initialized.rs b/compiler/rustc_mir_dataflow/src/impls/initialized.rs index f5ffc42d52a..18165b0b9bd 100644 --- a/compiler/rustc_mir_dataflow/src/impls/initialized.rs +++ b/compiler/rustc_mir_dataflow/src/impls/initialized.rs @@ -376,7 +376,14 @@ impl<'tcx> Analysis<'tcx> for MaybeInitializedPlaces<'_, 'tcx> { // the result of `is_unwind_dead`. let mut edges = terminator.edges(); if self.skip_unreachable_unwind - && let mir::TerminatorKind::Drop { target, unwind, place, replace: _ } = terminator.kind + && let mir::TerminatorKind::Drop { + target, + unwind, + place, + replace: _, + drop: _, + async_fut: _, + } = terminator.kind && matches!(unwind, mir::UnwindAction::Cleanup(_)) && self.is_unwind_dead(place, state) { diff --git a/compiler/rustc_mir_dataflow/src/value_analysis.rs b/compiler/rustc_mir_dataflow/src/value_analysis.rs index 36fb1c2b36d..83fd8ccba60 100644 --- a/compiler/rustc_mir_dataflow/src/value_analysis.rs +++ b/compiler/rustc_mir_dataflow/src/value_analysis.rs @@ -405,6 +405,9 @@ impl<'tcx> Map<'tcx> { if exclude.contains(local) { continue; } + if decl.ty.is_async_drop_in_place_coroutine(tcx) { + continue; + } // Create a place for the local. debug_assert!(self.locals[local].is_none()); diff --git a/compiler/rustc_mir_transform/src/add_moves_for_packed_drops.rs b/compiler/rustc_mir_transform/src/add_moves_for_packed_drops.rs index b33326cb873..a414d120e68 100644 --- a/compiler/rustc_mir_transform/src/add_moves_for_packed_drops.rs +++ b/compiler/rustc_mir_transform/src/add_moves_for_packed_drops.rs @@ -83,7 +83,9 @@ fn add_move_for_packed_drop<'tcx>( is_cleanup: bool, ) { debug!("add_move_for_packed_drop({:?} @ {:?})", terminator, loc); - let TerminatorKind::Drop { ref place, target, unwind, replace } = terminator.kind else { + let TerminatorKind::Drop { ref place, target, unwind, replace, drop, async_fut } = + terminator.kind + else { unreachable!(); }; @@ -106,6 +108,8 @@ fn add_move_for_packed_drop<'tcx>( target: storage_dead_block, unwind, replace, + drop, + async_fut, }, ); } diff --git a/compiler/rustc_mir_transform/src/coroutine.rs b/compiler/rustc_mir_transform/src/coroutine.rs index 0eed46c72f9..263f0c40f5a 100644 --- a/compiler/rustc_mir_transform/src/coroutine.rs +++ b/compiler/rustc_mir_transform/src/coroutine.rs @@ -51,9 +51,15 @@ //! Otherwise it drops all the values in scope at the last suspension point. mod by_move_body; +mod drop; use std::{iter, ops}; pub(super) use by_move_body::coroutine_by_move_body_def_id; +use drop::{ + cleanup_async_drops, create_coroutine_drop_shim, create_coroutine_drop_shim_async, + create_coroutine_drop_shim_proxy_async, elaborate_coroutine_drops, expand_async_drops, + has_expandable_async_drops, insert_clean_drop, +}; use rustc_abi::{FieldIdx, VariantIdx}; use rustc_data_structures::fx::FxHashSet; use rustc_errors::pluralize; @@ -64,6 +70,7 @@ use rustc_index::bit_set::{BitMatrix, DenseBitSet, GrowableBitSet}; use rustc_index::{Idx, IndexVec}; use rustc_middle::mir::visit::{MutVisitor, PlaceContext, Visitor}; use rustc_middle::mir::*; +use rustc_middle::ty::util::Discr; use rustc_middle::ty::{ self, CoroutineArgs, CoroutineArgsExt, GenericArgsRef, InstanceKind, Ty, TyCtxt, TypingMode, }; @@ -74,7 +81,9 @@ use rustc_mir_dataflow::impls::{ }; use rustc_mir_dataflow::{Analysis, Results, ResultsVisitor}; use rustc_span::def_id::{DefId, LocalDefId}; -use rustc_span::{Span, sym}; +use rustc_span::source_map::dummy_spanned; +use rustc_span::symbol::sym; +use rustc_span::{DUMMY_SP, Span}; use rustc_target::spec::PanicStrategy; use rustc_trait_selection::error_reporting::InferCtxtErrorExt; use rustc_trait_selection::infer::TyCtxtInferExt as _; @@ -159,6 +168,7 @@ fn replace_base<'tcx>(place: &mut Place<'tcx>, new_base: Place<'tcx>, tcx: TyCtx } const SELF_ARG: Local = Local::from_u32(1); +const CTX_ARG: Local = Local::from_u32(2); /// A `yield` point in the coroutine. struct SuspensionPoint<'tcx> { @@ -539,11 +549,11 @@ fn replace_local<'tcx>( /// The async lowering step and the type / lifetime inference / checking are /// still using the `ResumeTy` indirection for the time being, and that indirection /// is removed here. After this transform, the coroutine body only knows about `&mut Context<'_>`. -fn transform_async_context<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { +fn transform_async_context<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) -> Ty<'tcx> { let context_mut_ref = Ty::new_task_context(tcx); // replace the type of the `resume` argument - replace_resume_ty_local(tcx, body, Local::new(2), context_mut_ref); + replace_resume_ty_local(tcx, body, CTX_ARG, context_mut_ref); let get_context_def_id = tcx.require_lang_item(LangItem::GetContext, None); @@ -569,6 +579,7 @@ fn transform_async_context<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { _ => {} } } + context_mut_ref } fn eliminate_get_context_call<'tcx>(bb_data: &mut BasicBlockData<'tcx>) -> Local { @@ -1036,9 +1047,8 @@ fn insert_switch<'tcx>( body: &mut Body<'tcx>, cases: Vec<(usize, BasicBlock)>, transform: &TransformVisitor<'tcx>, - default: TerminatorKind<'tcx>, + default_block: BasicBlock, ) { - let default_block = insert_term_block(body, default); let (assign, discr) = transform.get_discr(body); let switch_targets = SwitchTargets::new(cases.iter().map(|(i, bb)| ((*i) as u128, *bb)), default_block); @@ -1061,129 +1071,39 @@ fn insert_switch<'tcx>( } } -fn elaborate_coroutine_drops<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { - use crate::elaborate_drop::{Unwind, elaborate_drop}; - use crate::patch::MirPatch; - use crate::shim::DropShimElaborator; - - // Note that `elaborate_drops` only drops the upvars of a coroutine, and - // this is ok because `open_drop` can only be reached within that own - // coroutine's resume function. - let typing_env = body.typing_env(tcx); - - let mut elaborator = DropShimElaborator { body, patch: MirPatch::new(body), tcx, typing_env }; - - for (block, block_data) in body.basic_blocks.iter_enumerated() { - let (target, unwind, source_info) = match block_data.terminator() { - Terminator { - source_info, - kind: TerminatorKind::Drop { place, target, unwind, replace: _ }, - } => { - if let Some(local) = place.as_local() - && local == SELF_ARG - { - (target, unwind, source_info) - } else { - continue; - } - } - _ => continue, - }; - let unwind = if block_data.is_cleanup { - Unwind::InCleanup - } else { - Unwind::To(match *unwind { - UnwindAction::Cleanup(tgt) => tgt, - UnwindAction::Continue => elaborator.patch.resume_block(), - UnwindAction::Unreachable => elaborator.patch.unreachable_cleanup_block(), - UnwindAction::Terminate(reason) => elaborator.patch.terminate_block(reason), - }) - }; - elaborate_drop( - &mut elaborator, - *source_info, - Place::from(SELF_ARG), - (), - *target, - unwind, - block, - ); - } - elaborator.patch.apply(body); -} - -fn create_coroutine_drop_shim<'tcx>( - tcx: TyCtxt<'tcx>, - transform: &TransformVisitor<'tcx>, - coroutine_ty: Ty<'tcx>, - body: &Body<'tcx>, - drop_clean: BasicBlock, -) -> Body<'tcx> { - let mut body = body.clone(); - // Take the coroutine info out of the body, since the drop shim is - // not a coroutine body itself; it just has its drop built out of it. - let _ = body.coroutine.take(); - // Make sure the resume argument is not included here, since we're - // building a body for `drop_in_place`. - body.arg_count = 1; - +fn insert_term_block<'tcx>(body: &mut Body<'tcx>, kind: TerminatorKind<'tcx>) -> BasicBlock { let source_info = SourceInfo::outermost(body.span); + body.basic_blocks_mut().push(BasicBlockData { + statements: Vec::new(), + terminator: Some(Terminator { source_info, kind }), + is_cleanup: false, + }) +} - let mut cases = create_cases(&mut body, transform, Operation::Drop); - - cases.insert(0, (CoroutineArgs::UNRESUMED, drop_clean)); - - // The returned state and the poisoned state fall through to the default - // case which is just to return - - insert_switch(&mut body, cases, transform, TerminatorKind::Return); - - for block in body.basic_blocks_mut() { - let kind = &mut block.terminator_mut().kind; - if let TerminatorKind::CoroutineDrop = *kind { - *kind = TerminatorKind::Return; - } +fn return_poll_ready_assign<'tcx>(tcx: TyCtxt<'tcx>, source_info: SourceInfo) -> Statement<'tcx> { + // Poll::Ready(()) + let poll_def_id = tcx.require_lang_item(LangItem::Poll, None); + let args = tcx.mk_args(&[tcx.types.unit.into()]); + let val = Operand::Constant(Box::new(ConstOperand { + span: source_info.span, + user_ty: None, + const_: Const::zero_sized(tcx.types.unit), + })); + let ready_val = Rvalue::Aggregate( + Box::new(AggregateKind::Adt(poll_def_id, VariantIdx::from_usize(0), args, None, None)), + IndexVec::from_raw(vec![val]), + ); + Statement { + kind: StatementKind::Assign(Box::new((Place::return_place(), ready_val))), + source_info, } - - // Replace the return variable - body.local_decls[RETURN_PLACE] = LocalDecl::with_source_info(tcx.types.unit, source_info); - - make_coroutine_state_argument_indirect(tcx, &mut body); - - // Change the coroutine argument from &mut to *mut - body.local_decls[SELF_ARG] = - LocalDecl::with_source_info(Ty::new_mut_ptr(tcx, coroutine_ty), source_info); - - // Make sure we remove dead blocks to remove - // unrelated code from the resume part of the function - simplify::remove_dead_blocks(&mut body); - - // Update the body's def to become the drop glue. - let coroutine_instance = body.source.instance; - let drop_in_place = tcx.require_lang_item(LangItem::DropInPlace, None); - let drop_instance = InstanceKind::DropGlue(drop_in_place, Some(coroutine_ty)); - - // Temporary change MirSource to coroutine's instance so that dump_mir produces more sensible - // filename. - body.source.instance = coroutine_instance; - dump_mir(tcx, false, "coroutine_drop", &0, &body, |_, _| Ok(())); - body.source.instance = drop_instance; - - // Creating a coroutine drop shim happens on `Analysis(PostCleanup) -> Runtime(Initial)` - // but the pass manager doesn't update the phase of the coroutine drop shim. Update the - // phase of the drop shim so that later on when we run the pass manager on the shim, in - // the `mir_shims` query, we don't ICE on the intra-pass validation before we've updated - // the phase of the body from analysis. - body.phase = MirPhase::Runtime(RuntimePhase::Initial); - - body } -fn insert_term_block<'tcx>(body: &mut Body<'tcx>, kind: TerminatorKind<'tcx>) -> BasicBlock { +fn insert_poll_ready_block<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) -> BasicBlock { let source_info = SourceInfo::outermost(body.span); body.basic_blocks_mut().push(BasicBlockData { - statements: Vec::new(), - terminator: Some(Terminator { source_info, kind }), + statements: [return_poll_ready_assign(tcx, source_info)].to_vec(), + terminator: Some(Terminator { source_info, kind: TerminatorKind::Return }), is_cleanup: false, }) } @@ -1263,45 +1183,50 @@ fn can_unwind<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>) -> bool { false } +// Poison the coroutine when it unwinds +fn generate_poison_block_and_redirect_unwinds_there<'tcx>( + transform: &TransformVisitor<'tcx>, + body: &mut Body<'tcx>, +) { + let source_info = SourceInfo::outermost(body.span); + let poison_block = body.basic_blocks_mut().push(BasicBlockData { + statements: vec![ + transform.set_discr(VariantIdx::new(CoroutineArgs::POISONED), source_info), + ], + terminator: Some(Terminator { source_info, kind: TerminatorKind::UnwindResume }), + is_cleanup: true, + }); + + for (idx, block) in body.basic_blocks_mut().iter_enumerated_mut() { + let source_info = block.terminator().source_info; + + if let TerminatorKind::UnwindResume = block.terminator().kind { + // An existing `Resume` terminator is redirected to jump to our dedicated + // "poisoning block" above. + if idx != poison_block { + *block.terminator_mut() = + Terminator { source_info, kind: TerminatorKind::Goto { target: poison_block } }; + } + } else if !block.is_cleanup + // Any terminators that *can* unwind but don't have an unwind target set are also + // pointed at our poisoning block (unless they're part of the cleanup path). + && let Some(unwind @ UnwindAction::Continue) = block.terminator_mut().unwind_mut() + { + *unwind = UnwindAction::Cleanup(poison_block); + } + } +} + fn create_coroutine_resume_function<'tcx>( tcx: TyCtxt<'tcx>, transform: TransformVisitor<'tcx>, body: &mut Body<'tcx>, can_return: bool, + can_unwind: bool, ) { - let can_unwind = can_unwind(tcx, body); - // Poison the coroutine when it unwinds if can_unwind { - let source_info = SourceInfo::outermost(body.span); - let poison_block = body.basic_blocks_mut().push(BasicBlockData { - statements: vec![ - transform.set_discr(VariantIdx::new(CoroutineArgs::POISONED), source_info), - ], - terminator: Some(Terminator { source_info, kind: TerminatorKind::UnwindResume }), - is_cleanup: true, - }); - - for (idx, block) in body.basic_blocks_mut().iter_enumerated_mut() { - let source_info = block.terminator().source_info; - - if let TerminatorKind::UnwindResume = block.terminator().kind { - // An existing `Resume` terminator is redirected to jump to our dedicated - // "poisoning block" above. - if idx != poison_block { - *block.terminator_mut() = Terminator { - source_info, - kind: TerminatorKind::Goto { target: poison_block }, - }; - } - } else if !block.is_cleanup - // Any terminators that *can* unwind but don't have an unwind target set are also - // pointed at our poisoning block (unless they're part of the cleanup path). - && let Some(unwind @ UnwindAction::Continue) = block.terminator_mut().unwind_mut() - { - *unwind = UnwindAction::Cleanup(poison_block); - } - } + generate_poison_block_and_redirect_unwinds_there(&transform, body); } let mut cases = create_cases(body, &transform, Operation::Resume); @@ -1326,7 +1251,13 @@ fn create_coroutine_resume_function<'tcx>( let block = match transform.coroutine_kind { CoroutineKind::Desugared(CoroutineDesugaring::Async, _) | CoroutineKind::Coroutine(_) => { - insert_panic_block(tcx, body, ResumedAfterReturn(transform.coroutine_kind)) + // For `async_drop_in_place::{closure}` we just keep return Poll::Ready, + // because async drop of such coroutine keeps polling original coroutine + if tcx.is_async_drop_in_place_coroutine(body.source.def_id()) { + insert_poll_ready_block(tcx, body) + } else { + insert_panic_block(tcx, body, ResumedAfterReturn(transform.coroutine_kind)) + } } CoroutineKind::Desugared(CoroutineDesugaring::AsyncGen, _) | CoroutineKind::Desugared(CoroutineDesugaring::Gen, _) => { @@ -1336,7 +1267,8 @@ fn create_coroutine_resume_function<'tcx>( cases.insert(1, (CoroutineArgs::RETURNED, block)); } - insert_switch(body, cases, &transform, TerminatorKind::Unreachable); + let default_block = insert_term_block(body, TerminatorKind::Unreachable); + insert_switch(body, cases, &transform, default_block); make_coroutine_state_argument_indirect(tcx, body); @@ -1360,25 +1292,6 @@ fn create_coroutine_resume_function<'tcx>( dump_mir(tcx, false, "coroutine_resume", &0, body, |_, _| Ok(())); } -fn insert_clean_drop(body: &mut Body<'_>) -> BasicBlock { - let return_block = insert_term_block(body, TerminatorKind::Return); - - let term = TerminatorKind::Drop { - place: Place::from(SELF_ARG), - target: return_block, - unwind: UnwindAction::Continue, - replace: false, - }; - let source_info = SourceInfo::outermost(body.span); - - // Create a block to destroy an unresumed coroutines. This can only destroy upvars. - body.basic_blocks_mut().push(BasicBlockData { - statements: Vec::new(), - terminator: Some(Terminator { source_info, kind: term }), - is_cleanup: false, - }) -} - /// An operation that can be performed on a coroutine. #[derive(PartialEq, Copy, Clone)] enum Operation { @@ -1423,7 +1336,7 @@ fn create_cases<'tcx>( if operation == Operation::Resume { // Move the resume argument to the destination place of the `Yield` terminator - let resume_arg = Local::new(2); // 0 = return, 1 = self + let resume_arg = CTX_ARG; statements.push(Statement { source_info, kind: StatementKind::Assign(Box::new(( @@ -1530,7 +1443,9 @@ impl<'tcx> crate::MirPass<'tcx> for StateTransform { }; let old_ret_ty = body.return_ty(); - assert!(body.coroutine_drop().is_none()); + assert!(body.coroutine_drop().is_none() && body.coroutine_drop_async().is_none()); + + dump_mir(tcx, false, "coroutine_before", &0, body, |_, _| Ok(())); // The first argument is the coroutine type passed by value let coroutine_ty = body.local_decls.raw[1].ty; @@ -1574,19 +1489,32 @@ impl<'tcx> crate::MirPass<'tcx> for StateTransform { // RETURN_PLACE then is a fresh unused local with type ret_ty. let old_ret_local = replace_local(RETURN_PLACE, new_ret_ty, body, tcx); + // We need to insert clean drop for unresumed state and perform drop elaboration + // (finally in open_drop_for_tuple) before async drop expansion. + // Async drops, produced by this drop elaboration, will be expanded, + // and corresponding futures kept in layout. + let has_async_drops = matches!( + coroutine_kind, + CoroutineKind::Desugared(CoroutineDesugaring::Async | CoroutineDesugaring::AsyncGen, _) + ) && has_expandable_async_drops(tcx, body, coroutine_ty); + // Replace all occurrences of `ResumeTy` with `&mut Context<'_>` within async bodies. if matches!( coroutine_kind, CoroutineKind::Desugared(CoroutineDesugaring::Async | CoroutineDesugaring::AsyncGen, _) ) { - transform_async_context(tcx, body); + let context_mut_ref = transform_async_context(tcx, body); + expand_async_drops(tcx, body, context_mut_ref, coroutine_kind, coroutine_ty); + dump_mir(tcx, false, "coroutine_async_drop_expand", &0, body, |_, _| Ok(())); + } else { + cleanup_async_drops(body); } // We also replace the resume argument and insert an `Assign`. // This is needed because the resume argument `_2` might be live across a `yield`, in which // case there is no `Assign` to it that the transform can turn into a store to the coroutine // state. After the yield the slot in the coroutine state would then be uninitialized. - let resume_local = Local::new(2); + let resume_local = CTX_ARG; let resume_ty = body.local_decls[resume_local].ty; let old_resume_local = replace_local(resume_local, resume_ty, body, tcx); @@ -1667,10 +1595,14 @@ impl<'tcx> crate::MirPass<'tcx> for StateTransform { body.coroutine.as_mut().unwrap().resume_ty = None; body.coroutine.as_mut().unwrap().coroutine_layout = Some(layout); + // FIXME: Drops, produced by insert_clean_drop + elaborate_coroutine_drops, + // are currently sync only. To allow async for them, we need to move those calls + // before expand_async_drops, and fix the related problems. + // // Insert `drop(coroutine_struct)` which is used to drop upvars for coroutines in // the unresumed state. // This is expanded to a drop ladder in `elaborate_coroutine_drops`. - let drop_clean = insert_clean_drop(body); + let drop_clean = insert_clean_drop(tcx, body, has_async_drops); dump_mir(tcx, false, "coroutine_pre-elab", &0, body, |_, _| Ok(())); @@ -1681,13 +1613,32 @@ impl<'tcx> crate::MirPass<'tcx> for StateTransform { dump_mir(tcx, false, "coroutine_post-transform", &0, body, |_, _| Ok(())); - // Create a copy of our MIR and use it to create the drop shim for the coroutine - let drop_shim = create_coroutine_drop_shim(tcx, &transform, coroutine_ty, body, drop_clean); + let can_unwind = can_unwind(tcx, body); - body.coroutine.as_mut().unwrap().coroutine_drop = Some(drop_shim); + // Create a copy of our MIR and use it to create the drop shim for the coroutine + if has_async_drops { + // If coroutine has async drops, generating async drop shim + let mut drop_shim = + create_coroutine_drop_shim_async(tcx, &transform, body, drop_clean, can_unwind); + // Run derefer to fix Derefs that are not in the first place + deref_finder(tcx, &mut drop_shim); + body.coroutine.as_mut().unwrap().coroutine_drop_async = Some(drop_shim); + } else { + // If coroutine has no async drops, generating sync drop shim + let mut drop_shim = + create_coroutine_drop_shim(tcx, &transform, coroutine_ty, body, drop_clean); + // Run derefer to fix Derefs that are not in the first place + deref_finder(tcx, &mut drop_shim); + body.coroutine.as_mut().unwrap().coroutine_drop = Some(drop_shim); + + // For coroutine with sync drop, generating async proxy for `future_drop_poll` call + let mut proxy_shim = create_coroutine_drop_shim_proxy_async(tcx, body); + deref_finder(tcx, &mut proxy_shim); + body.coroutine.as_mut().unwrap().coroutine_drop_proxy_async = Some(proxy_shim); + } // Create the Coroutine::resume / Future::poll function - create_coroutine_resume_function(tcx, transform, body, can_return); + create_coroutine_resume_function(tcx, transform, body, can_return, can_unwind); // Run derefer to fix Derefs that are not in the first place deref_finder(tcx, body); diff --git a/compiler/rustc_mir_transform/src/coroutine/drop.rs b/compiler/rustc_mir_transform/src/coroutine/drop.rs new file mode 100644 index 00000000000..6b266da5a69 --- /dev/null +++ b/compiler/rustc_mir_transform/src/coroutine/drop.rs @@ -0,0 +1,725 @@ +//! Drops and async drops related logic for coroutine transformation pass + +use super::*; + +// Fix return Poll::Pending statement into Poll<()>::Pending for async drop function +struct FixReturnPendingVisitor<'tcx> { + tcx: TyCtxt<'tcx>, +} + +impl<'tcx> MutVisitor<'tcx> for FixReturnPendingVisitor<'tcx> { + fn tcx(&self) -> TyCtxt<'tcx> { + self.tcx + } + + fn visit_assign( + &mut self, + place: &mut Place<'tcx>, + rvalue: &mut Rvalue<'tcx>, + _location: Location, + ) { + if place.local != RETURN_PLACE { + return; + } + + // Converting `_0 = Poll::::Pending` to `_0 = Poll::<()>::Pending` + if let Rvalue::Aggregate(kind, _) = rvalue { + if let AggregateKind::Adt(_, _, ref mut args, _, _) = **kind { + *args = self.tcx.mk_args(&[self.tcx.types.unit.into()]); + } + } + } +} + +// rv = call fut.poll() +fn build_poll_call<'tcx>( + tcx: TyCtxt<'tcx>, + body: &mut Body<'tcx>, + poll_unit_place: &Place<'tcx>, + switch_block: BasicBlock, + fut_pin_place: &Place<'tcx>, + fut_ty: Ty<'tcx>, + context_ref_place: &Place<'tcx>, + unwind: UnwindAction, +) -> BasicBlock { + let poll_fn = tcx.require_lang_item(LangItem::FuturePoll, None); + let poll_fn = Ty::new_fn_def(tcx, poll_fn, [fut_ty]); + let poll_fn = Operand::Constant(Box::new(ConstOperand { + span: DUMMY_SP, + user_ty: None, + const_: Const::zero_sized(poll_fn), + })); + let call = TerminatorKind::Call { + func: poll_fn.clone(), + args: [ + dummy_spanned(Operand::Move(*fut_pin_place)), + dummy_spanned(Operand::Move(*context_ref_place)), + ] + .into(), + destination: *poll_unit_place, + target: Some(switch_block), + unwind, + call_source: CallSource::Misc, + fn_span: DUMMY_SP, + }; + insert_term_block(body, call) +} + +// pin_fut = Pin::new_unchecked(&mut fut) +fn build_pin_fut<'tcx>( + tcx: TyCtxt<'tcx>, + body: &mut Body<'tcx>, + fut_place: Place<'tcx>, + unwind: UnwindAction, +) -> (BasicBlock, Place<'tcx>) { + let span = body.span; + let source_info = SourceInfo::outermost(span); + let fut_ty = fut_place.ty(&body.local_decls, tcx).ty; + let fut_ref_ty = Ty::new_mut_ref(tcx, tcx.lifetimes.re_erased, fut_ty); + let fut_ref_place = Place::from(body.local_decls.push(LocalDecl::new(fut_ref_ty, span))); + let pin_fut_new_unchecked_fn = Ty::new_fn_def( + tcx, + tcx.require_lang_item(LangItem::PinNewUnchecked, Some(span)), + [fut_ref_ty], + ); + let fut_pin_ty = pin_fut_new_unchecked_fn.fn_sig(tcx).output().skip_binder(); + let fut_pin_place = Place::from(body.local_decls.push(LocalDecl::new(fut_pin_ty, span))); + let pin_fut_new_unchecked_fn = Operand::Constant(Box::new(ConstOperand { + span, + user_ty: None, + const_: Const::zero_sized(pin_fut_new_unchecked_fn), + })); + + let storage_live = + Statement { source_info, kind: StatementKind::StorageLive(fut_pin_place.local) }; + + let fut_ref_assign = Statement { + source_info, + kind: StatementKind::Assign(Box::new(( + fut_ref_place, + Rvalue::Ref( + tcx.lifetimes.re_erased, + BorrowKind::Mut { kind: MutBorrowKind::Default }, + fut_place, + ), + ))), + }; + + // call Pin::new_unchecked(&mut fut) + let pin_fut_bb = body.basic_blocks_mut().push(BasicBlockData { + statements: [storage_live, fut_ref_assign].to_vec(), + terminator: Some(Terminator { + source_info, + kind: TerminatorKind::Call { + func: pin_fut_new_unchecked_fn, + args: [dummy_spanned(Operand::Move(fut_ref_place))].into(), + destination: fut_pin_place, + target: None, // will be fixed later + unwind, + call_source: CallSource::Misc, + fn_span: span, + }, + }), + is_cleanup: false, + }); + (pin_fut_bb, fut_pin_place) +} + +// Build Poll switch for async drop +// match rv { +// Ready() => ready_block +// Pending => yield_block +//} +fn build_poll_switch<'tcx>( + tcx: TyCtxt<'tcx>, + body: &mut Body<'tcx>, + poll_enum: Ty<'tcx>, + poll_unit_place: &Place<'tcx>, + ready_block: BasicBlock, + yield_block: BasicBlock, +) -> BasicBlock { + let poll_enum_adt = poll_enum.ty_adt_def().unwrap(); + + let Discr { val: poll_ready_discr, ty: poll_discr_ty } = poll_enum + .discriminant_for_variant( + tcx, + poll_enum_adt.variant_index_with_id(tcx.require_lang_item(LangItem::PollReady, None)), + ) + .unwrap(); + let poll_pending_discr = poll_enum + .discriminant_for_variant( + tcx, + poll_enum_adt.variant_index_with_id(tcx.require_lang_item(LangItem::PollPending, None)), + ) + .unwrap() + .val; + let source_info = SourceInfo::outermost(body.span); + let poll_discr_place = + Place::from(body.local_decls.push(LocalDecl::new(poll_discr_ty, source_info.span))); + let discr_assign = Statement { + source_info, + kind: StatementKind::Assign(Box::new(( + poll_discr_place, + Rvalue::Discriminant(*poll_unit_place), + ))), + }; + let unreachable_block = insert_term_block(body, TerminatorKind::Unreachable); + body.basic_blocks_mut().push(BasicBlockData { + statements: [discr_assign].to_vec(), + terminator: Some(Terminator { + source_info, + kind: TerminatorKind::SwitchInt { + discr: Operand::Move(poll_discr_place), + targets: SwitchTargets::new( + [(poll_ready_discr, ready_block), (poll_pending_discr, yield_block)] + .into_iter(), + unreachable_block, + ), + }, + }), + is_cleanup: false, + }) +} + +// Gather blocks, reachable through 'drop' targets of Yield and Drop terminators (chained) +fn gather_dropline_blocks<'tcx>(body: &mut Body<'tcx>) -> DenseBitSet { + let mut dropline: DenseBitSet = DenseBitSet::new_empty(body.basic_blocks.len()); + for (bb, data) in traversal::reverse_postorder(body) { + if dropline.contains(bb) { + data.terminator().successors().for_each(|v| { + dropline.insert(v); + }); + } else { + match data.terminator().kind { + TerminatorKind::Yield { drop: Some(v), .. } => { + dropline.insert(v); + } + TerminatorKind::Drop { drop: Some(v), .. } => { + dropline.insert(v); + } + _ => (), + } + } + } + dropline +} + +/// Cleanup all async drops (reset to sync) +pub(super) fn cleanup_async_drops<'tcx>(body: &mut Body<'tcx>) { + for block in body.basic_blocks_mut() { + if let TerminatorKind::Drop { + place: _, + target: _, + unwind: _, + replace: _, + ref mut drop, + ref mut async_fut, + } = block.terminator_mut().kind + { + if drop.is_some() || async_fut.is_some() { + *drop = None; + *async_fut = None; + } + } + } +} + +pub(super) fn has_expandable_async_drops<'tcx>( + tcx: TyCtxt<'tcx>, + body: &mut Body<'tcx>, + coroutine_ty: Ty<'tcx>, +) -> bool { + for bb in START_BLOCK..body.basic_blocks.next_index() { + // Drops in unwind path (cleanup blocks) are not expanded to async drops, only sync drops in unwind path + if body[bb].is_cleanup { + continue; + } + let TerminatorKind::Drop { place, target: _, unwind: _, replace: _, drop: _, async_fut } = + body[bb].terminator().kind + else { + continue; + }; + let place_ty = place.ty(&body.local_decls, tcx).ty; + if place_ty == coroutine_ty { + continue; + } + if async_fut.is_none() { + continue; + } + return true; + } + return false; +} + +/// Expand Drop terminator for async drops into mainline poll-switch and dropline poll-switch +pub(super) fn expand_async_drops<'tcx>( + tcx: TyCtxt<'tcx>, + body: &mut Body<'tcx>, + context_mut_ref: Ty<'tcx>, + coroutine_kind: hir::CoroutineKind, + coroutine_ty: Ty<'tcx>, +) { + let dropline = gather_dropline_blocks(body); + // Clean drop and async_fut fields if potentially async drop is not expanded (stays sync) + let remove_asyncness = |block: &mut BasicBlockData<'tcx>| { + if let TerminatorKind::Drop { + place: _, + target: _, + unwind: _, + replace: _, + ref mut drop, + ref mut async_fut, + } = block.terminator_mut().kind + { + *drop = None; + *async_fut = None; + } + }; + for bb in START_BLOCK..body.basic_blocks.next_index() { + // Drops in unwind path (cleanup blocks) are not expanded to async drops, only sync drops in unwind path + if body[bb].is_cleanup { + remove_asyncness(&mut body[bb]); + continue; + } + let TerminatorKind::Drop { place, target, unwind, replace: _, drop, async_fut } = + body[bb].terminator().kind + else { + continue; + }; + + let place_ty = place.ty(&body.local_decls, tcx).ty; + if place_ty == coroutine_ty { + remove_asyncness(&mut body[bb]); + continue; + } + + let Some(fut_local) = async_fut else { + remove_asyncness(&mut body[bb]); + continue; + }; + + let is_dropline_bb = dropline.contains(bb); + + if !is_dropline_bb && drop.is_none() { + remove_asyncness(&mut body[bb]); + continue; + } + + let fut_place = Place::from(fut_local); + let fut_ty = fut_place.ty(&body.local_decls, tcx).ty; + + // poll-code: + // state_call_drop: + // #bb_pin: fut_pin = Pin::new_unchecked(&mut fut) + // #bb_call: rv = call fut.poll() (or future_drop_poll(fut) for internal future drops) + // #bb_check: match (rv) + // pending => return rv (yield) + // ready => *continue_bb|drop_bb* + + // Compute Poll<> (aka Poll with void return) + let poll_adt_ref = tcx.adt_def(tcx.require_lang_item(LangItem::Poll, None)); + let poll_enum = Ty::new_adt(tcx, poll_adt_ref, tcx.mk_args(&[tcx.types.unit.into()])); + let poll_decl = LocalDecl::new(poll_enum, body.span); + let poll_unit_place = Place::from(body.local_decls.push(poll_decl)); + + // First state-loop yield for mainline + let context_ref_place = + Place::from(body.local_decls.push(LocalDecl::new(context_mut_ref, body.span))); + let source_info = body[bb].terminator.as_ref().unwrap().source_info; + let arg = Rvalue::Use(Operand::Move(Place::from(CTX_ARG))); + body[bb].statements.push(Statement { + source_info, + kind: StatementKind::Assign(Box::new((context_ref_place, arg))), + }); + let yield_block = insert_term_block(body, TerminatorKind::Unreachable); // `kind` replaced later to yield + let switch_block = + build_poll_switch(tcx, body, poll_enum, &poll_unit_place, target, yield_block); + let (pin_bb, fut_pin_place) = + build_pin_fut(tcx, body, fut_place.clone(), UnwindAction::Continue); + let call_bb = build_poll_call( + tcx, + body, + &poll_unit_place, + switch_block, + &fut_pin_place, + fut_ty, + &context_ref_place, + unwind, + ); + + // Second state-loop yield for transition to dropline (when coroutine async drop started) + let mut dropline_transition_bb: Option = None; + let mut dropline_yield_bb: Option = None; + let mut dropline_context_ref: Option> = None; + let mut dropline_call_bb: Option = None; + if !is_dropline_bb { + let context_ref_place2: Place<'_> = + Place::from(body.local_decls.push(LocalDecl::new(context_mut_ref, body.span))); + let drop_yield_block = insert_term_block(body, TerminatorKind::Unreachable); // `kind` replaced later to yield + let drop_switch_block = build_poll_switch( + tcx, + body, + poll_enum, + &poll_unit_place, + drop.unwrap(), + drop_yield_block, + ); + let (pin_bb2, fut_pin_place2) = + build_pin_fut(tcx, body, fut_place, UnwindAction::Continue); + let drop_call_bb = build_poll_call( + tcx, + body, + &poll_unit_place, + drop_switch_block, + &fut_pin_place2, + fut_ty, + &context_ref_place2, + unwind, + ); + dropline_transition_bb = Some(pin_bb2); + dropline_yield_bb = Some(drop_yield_block); + dropline_context_ref = Some(context_ref_place2); + dropline_call_bb = Some(drop_call_bb); + } + + // value needed only for return-yields or gen-coroutines, so just const here + let value = Operand::Constant(Box::new(ConstOperand { + span: body.span, + user_ty: None, + const_: Const::from_bool(tcx, false), + })); + use rustc_middle::mir::AssertKind::ResumedAfterDrop; + let panic_bb = insert_panic_block(tcx, body, ResumedAfterDrop(coroutine_kind)); + + if is_dropline_bb { + body[yield_block].terminator_mut().kind = TerminatorKind::Yield { + value: value.clone(), + resume: panic_bb, + resume_arg: context_ref_place, + drop: Some(pin_bb), + }; + } else { + body[yield_block].terminator_mut().kind = TerminatorKind::Yield { + value: value.clone(), + resume: pin_bb, + resume_arg: context_ref_place, + drop: dropline_transition_bb, + }; + body[dropline_yield_bb.unwrap()].terminator_mut().kind = TerminatorKind::Yield { + value, + resume: panic_bb, + resume_arg: dropline_context_ref.unwrap(), + drop: dropline_transition_bb, + }; + } + + if let TerminatorKind::Call { ref mut target, .. } = body[pin_bb].terminator_mut().kind { + *target = Some(call_bb); + } else { + bug!() + } + if !is_dropline_bb { + if let TerminatorKind::Call { ref mut target, .. } = + body[dropline_transition_bb.unwrap()].terminator_mut().kind + { + *target = dropline_call_bb; + } else { + bug!() + } + } + + body[bb].terminator_mut().kind = TerminatorKind::Goto { target: pin_bb }; + } +} + +pub(super) fn elaborate_coroutine_drops<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { + use crate::elaborate_drop::{Unwind, elaborate_drop}; + use crate::patch::MirPatch; + use crate::shim::DropShimElaborator; + + // Note that `elaborate_drops` only drops the upvars of a coroutine, and + // this is ok because `open_drop` can only be reached within that own + // coroutine's resume function. + let typing_env = body.typing_env(tcx); + + let mut elaborator = DropShimElaborator { + body, + patch: MirPatch::new(body), + tcx, + typing_env, + produce_async_drops: false, + }; + + for (block, block_data) in body.basic_blocks.iter_enumerated() { + let (target, unwind, source_info, dropline) = match block_data.terminator() { + Terminator { + source_info, + kind: TerminatorKind::Drop { place, target, unwind, replace: _, drop, async_fut: _ }, + } => { + if let Some(local) = place.as_local() + && local == SELF_ARG + { + (target, unwind, source_info, *drop) + } else { + continue; + } + } + _ => continue, + }; + let unwind = if block_data.is_cleanup { + Unwind::InCleanup + } else { + Unwind::To(match *unwind { + UnwindAction::Cleanup(tgt) => tgt, + UnwindAction::Continue => elaborator.patch.resume_block(), + UnwindAction::Unreachable => elaborator.patch.unreachable_cleanup_block(), + UnwindAction::Terminate(reason) => elaborator.patch.terminate_block(reason), + }) + }; + elaborate_drop( + &mut elaborator, + *source_info, + Place::from(SELF_ARG), + (), + *target, + unwind, + block, + dropline, + ); + } + elaborator.patch.apply(body); +} + +pub(super) fn insert_clean_drop<'tcx>( + tcx: TyCtxt<'tcx>, + body: &mut Body<'tcx>, + has_async_drops: bool, +) -> BasicBlock { + let source_info = SourceInfo::outermost(body.span); + let return_block = if has_async_drops { + insert_poll_ready_block(tcx, body) + } else { + insert_term_block(body, TerminatorKind::Return) + }; + + // FIXME: When move insert_clean_drop + elaborate_coroutine_drops before async drops expand, + // also set dropline here: + // let dropline = if has_async_drops { Some(return_block) } else { None }; + let dropline = None; + + let term = TerminatorKind::Drop { + place: Place::from(SELF_ARG), + target: return_block, + unwind: UnwindAction::Continue, + replace: false, + drop: dropline, + async_fut: None, + }; + + // Create a block to destroy an unresumed coroutines. This can only destroy upvars. + body.basic_blocks_mut().push(BasicBlockData { + statements: Vec::new(), + terminator: Some(Terminator { source_info, kind: term }), + is_cleanup: false, + }) +} + +pub(super) fn create_coroutine_drop_shim<'tcx>( + tcx: TyCtxt<'tcx>, + transform: &TransformVisitor<'tcx>, + coroutine_ty: Ty<'tcx>, + body: &Body<'tcx>, + drop_clean: BasicBlock, +) -> Body<'tcx> { + let mut body = body.clone(); + // Take the coroutine info out of the body, since the drop shim is + // not a coroutine body itself; it just has its drop built out of it. + let _ = body.coroutine.take(); + // Make sure the resume argument is not included here, since we're + // building a body for `drop_in_place`. + body.arg_count = 1; + + let source_info = SourceInfo::outermost(body.span); + + let mut cases = create_cases(&mut body, transform, Operation::Drop); + + cases.insert(0, (CoroutineArgs::UNRESUMED, drop_clean)); + + // The returned state and the poisoned state fall through to the default + // case which is just to return + + let default_block = insert_term_block(&mut body, TerminatorKind::Return); + insert_switch(&mut body, cases, transform, default_block); + + for block in body.basic_blocks_mut() { + let kind = &mut block.terminator_mut().kind; + if let TerminatorKind::CoroutineDrop = *kind { + *kind = TerminatorKind::Return; + } + } + + // Replace the return variable + body.local_decls[RETURN_PLACE] = LocalDecl::with_source_info(tcx.types.unit, source_info); + + make_coroutine_state_argument_indirect(tcx, &mut body); + + // Change the coroutine argument from &mut to *mut + body.local_decls[SELF_ARG] = + LocalDecl::with_source_info(Ty::new_mut_ptr(tcx, coroutine_ty), source_info); + + // Make sure we remove dead blocks to remove + // unrelated code from the resume part of the function + simplify::remove_dead_blocks(&mut body); + + // Update the body's def to become the drop glue. + let coroutine_instance = body.source.instance; + let drop_in_place = tcx.require_lang_item(LangItem::DropInPlace, None); + let drop_instance = InstanceKind::DropGlue(drop_in_place, Some(coroutine_ty)); + + // Temporary change MirSource to coroutine's instance so that dump_mir produces more sensible + // filename. + body.source.instance = coroutine_instance; + dump_mir(tcx, false, "coroutine_drop", &0, &body, |_, _| Ok(())); + body.source.instance = drop_instance; + + // Creating a coroutine drop shim happens on `Analysis(PostCleanup) -> Runtime(Initial)` + // but the pass manager doesn't update the phase of the coroutine drop shim. Update the + // phase of the drop shim so that later on when we run the pass manager on the shim, in + // the `mir_shims` query, we don't ICE on the intra-pass validation before we've updated + // the phase of the body from analysis. + body.phase = MirPhase::Runtime(RuntimePhase::Initial); + + body +} + +// Create async drop shim function to drop coroutine itself +pub(super) fn create_coroutine_drop_shim_async<'tcx>( + tcx: TyCtxt<'tcx>, + transform: &TransformVisitor<'tcx>, + body: &Body<'tcx>, + drop_clean: BasicBlock, + can_unwind: bool, +) -> Body<'tcx> { + let mut body = body.clone(); + // Take the coroutine info out of the body, since the drop shim is + // not a coroutine body itself; it just has its drop built out of it. + let _ = body.coroutine.take(); + + FixReturnPendingVisitor { tcx }.visit_body(&mut body); + + // Poison the coroutine when it unwinds + if can_unwind { + generate_poison_block_and_redirect_unwinds_there(transform, &mut body); + } + + let source_info = SourceInfo::outermost(body.span); + + let mut cases = create_cases(&mut body, transform, Operation::Drop); + + cases.insert(0, (CoroutineArgs::UNRESUMED, drop_clean)); + + use rustc_middle::mir::AssertKind::ResumedAfterPanic; + // Panic when resumed on the returned or poisoned state + if can_unwind { + cases.insert( + 1, + ( + CoroutineArgs::POISONED, + insert_panic_block(tcx, &mut body, ResumedAfterPanic(transform.coroutine_kind)), + ), + ); + } + + // RETURNED state also goes to default_block with `return Ready<()>`. + // For fully-polled coroutine, async drop has nothing to do. + let default_block = insert_poll_ready_block(tcx, &mut body); + insert_switch(&mut body, cases, transform, default_block); + + for block in body.basic_blocks_mut() { + let kind = &mut block.terminator_mut().kind; + if let TerminatorKind::CoroutineDrop = *kind { + *kind = TerminatorKind::Return; + block.statements.push(return_poll_ready_assign(tcx, source_info)); + } + } + + // Replace the return variable: Poll to Poll<()> + let poll_adt_ref = tcx.adt_def(tcx.require_lang_item(LangItem::Poll, None)); + let poll_enum = Ty::new_adt(tcx, poll_adt_ref, tcx.mk_args(&[tcx.types.unit.into()])); + body.local_decls[RETURN_PLACE] = LocalDecl::with_source_info(poll_enum, source_info); + + make_coroutine_state_argument_indirect(tcx, &mut body); + + match transform.coroutine_kind { + // Iterator::next doesn't accept a pinned argument, + // unlike for all other coroutine kinds. + CoroutineKind::Desugared(CoroutineDesugaring::Gen, _) => {} + _ => { + make_coroutine_state_argument_pinned(tcx, &mut body); + } + } + + // Make sure we remove dead blocks to remove + // unrelated code from the resume part of the function + simplify::remove_dead_blocks(&mut body); + + pm::run_passes_no_validate( + tcx, + &mut body, + &[&abort_unwinding_calls::AbortUnwindingCalls], + None, + ); + + dump_mir(tcx, false, "coroutine_drop_async", &0, &body, |_, _| Ok(())); + + body +} + +// Create async drop shim proxy function for future_drop_poll +// It is just { call coroutine_drop(); return Poll::Ready(); } +pub(super) fn create_coroutine_drop_shim_proxy_async<'tcx>( + tcx: TyCtxt<'tcx>, + body: &Body<'tcx>, +) -> Body<'tcx> { + let mut body = body.clone(); + // Take the coroutine info out of the body, since the drop shim is + // not a coroutine body itself; it just has its drop built out of it. + let _ = body.coroutine.take(); + let basic_blocks: IndexVec> = IndexVec::new(); + body.basic_blocks = BasicBlocks::new(basic_blocks); + body.var_debug_info.clear(); + + // Keeping return value and args + body.local_decls.truncate(1 + body.arg_count); + + let source_info = SourceInfo::outermost(body.span); + + // Replace the return variable: Poll to Poll<()> + let poll_adt_ref = tcx.adt_def(tcx.require_lang_item(LangItem::Poll, None)); + let poll_enum = Ty::new_adt(tcx, poll_adt_ref, tcx.mk_args(&[tcx.types.unit.into()])); + body.local_decls[RETURN_PLACE] = LocalDecl::with_source_info(poll_enum, source_info); + + // call coroutine_drop() + let call_bb = body.basic_blocks_mut().push(BasicBlockData { + statements: Vec::new(), + terminator: None, + is_cleanup: false, + }); + + // return Poll::Ready() + let ret_bb = insert_poll_ready_block(tcx, &mut body); + + let kind = TerminatorKind::Drop { + place: Place::from(SELF_ARG), + target: ret_bb, + unwind: UnwindAction::Continue, + replace: false, + drop: None, + async_fut: None, + }; + body.basic_blocks_mut()[call_bb].terminator = Some(Terminator { source_info, kind }); + + dump_mir(tcx, false, "coroutine_drop_proxy_async", &0, &body, |_, _| Ok(())); + + body +} diff --git a/compiler/rustc_mir_transform/src/elaborate_drop.rs b/compiler/rustc_mir_transform/src/elaborate_drop.rs index e3057a2f648..6f867f8105d 100644 --- a/compiler/rustc_mir_transform/src/elaborate_drop.rs +++ b/compiler/rustc_mir_transform/src/elaborate_drop.rs @@ -4,12 +4,12 @@ use rustc_abi::{FIRST_VARIANT, FieldIdx, VariantIdx}; use rustc_hir::lang_items::LangItem; use rustc_index::Idx; use rustc_middle::mir::*; -use rustc_middle::span_bug; use rustc_middle::ty::adjustment::PointerCoercion; use rustc_middle::ty::util::IntTypeExt; -use rustc_middle::ty::{self, GenericArgsRef, Ty, TyCtxt}; +use rustc_middle::ty::{self, GenericArg, GenericArgsRef, Ty, TyCtxt}; +use rustc_middle::{bug, span_bug, traits}; use rustc_span::DUMMY_SP; -use rustc_span::source_map::Spanned; +use rustc_span::source_map::{Spanned, dummy_spanned}; use tracing::{debug, instrument}; use crate::patch::MirPatch; @@ -94,6 +94,9 @@ pub(crate) trait DropElaborator<'a, 'tcx>: fmt::Debug { fn body(&self) -> &'a Body<'tcx>; fn tcx(&self) -> TyCtxt<'tcx>; fn typing_env(&self) -> ty::TypingEnv<'tcx>; + fn allow_async_drops(&self) -> bool; + + fn terminator_loc(&self, bb: BasicBlock) -> Location; // Drop logic @@ -149,6 +152,7 @@ where path: D::Path, succ: BasicBlock, unwind: Unwind, + dropline: Option, } /// "Elaborates" a drop of `place`/`path` and patches `bb`'s terminator to execute it. @@ -167,11 +171,12 @@ pub(crate) fn elaborate_drop<'b, 'tcx, D>( succ: BasicBlock, unwind: Unwind, bb: BasicBlock, + dropline: Option, ) where D: DropElaborator<'b, 'tcx>, 'tcx: 'b, { - DropCtxt { elaborator, source_info, place, path, succ, unwind }.elaborate_drop(bb) + DropCtxt { elaborator, source_info, place, path, succ, unwind, dropline }.elaborate_drop(bb) } impl<'a, 'b, 'tcx, D> DropCtxt<'a, 'b, 'tcx, D> @@ -195,6 +200,209 @@ where self.elaborator.tcx() } + // Generates three blocks: + // * #1:pin_obj_bb: call Pin::new_unchecked(&mut obj) + // * #2:call_drop_bb: fut = call obj.() OR call async_drop_in_place(obj) + // * #3:drop_term_bb: drop (obj, fut, ...) + // We keep async drop unexpanded to poll-loop here, to expand it later, at StateTransform - + // into states expand. + // call_destructor_only - to call only AsyncDrop::drop, not full async_drop_in_place glue + fn build_async_drop( + &mut self, + place: Place<'tcx>, + drop_ty: Ty<'tcx>, + bb: Option, + succ: BasicBlock, + unwind: Unwind, + dropline: Option, + call_destructor_only: bool, + ) -> BasicBlock { + let tcx = self.tcx(); + let span = self.source_info.span; + + let pin_obj_bb = bb.unwrap_or_else(|| { + self.elaborator.patch().new_block(BasicBlockData { + statements: vec![], + terminator: Some(Terminator { + // Temporary terminator, will be replaced by patch + source_info: self.source_info, + kind: TerminatorKind::Return, + }), + is_cleanup: false, + }) + }); + + let (fut_ty, drop_fn_def_id, trait_args) = if call_destructor_only { + // Resolving obj.() + let trait_ref = ty::TraitRef::new( + tcx, + tcx.require_lang_item(LangItem::AsyncDrop, Some(span)), + [drop_ty], + ); + let (drop_trait, trait_args) = match tcx.codegen_select_candidate( + ty::TypingEnv::fully_monomorphized().as_query_input(trait_ref), + ) { + Ok(traits::ImplSource::UserDefined(traits::ImplSourceUserDefinedData { + impl_def_id, + args, + .. + })) => (*impl_def_id, *args), + impl_source => { + span_bug!(span, "invalid `AsyncDrop` impl_source: {:?}", impl_source); + } + }; + let drop_fn_def_id = tcx.associated_item_def_ids(drop_trait)[0]; + let drop_fn = Ty::new_fn_def(tcx, drop_fn_def_id, trait_args); + let sig = drop_fn.fn_sig(tcx); + let sig = tcx.instantiate_bound_regions_with_erased(sig); + (sig.output(), drop_fn_def_id, trait_args) + } else { + // Resolving async_drop_in_place function for drop_ty + let drop_fn_def_id = tcx.require_lang_item(LangItem::AsyncDropInPlace, Some(span)); + let trait_args = tcx.mk_args(&[drop_ty.into()]); + let sig = tcx.fn_sig(drop_fn_def_id).instantiate(tcx, trait_args); + let sig = tcx.instantiate_bound_regions_with_erased(sig); + (sig.output(), drop_fn_def_id, trait_args) + }; + + let fut = Place::from(self.new_temp(fut_ty)); + + // #1:pin_obj_bb >>> obj_ref = &mut obj + let obj_ref_ty = Ty::new_mut_ref(tcx, tcx.lifetimes.re_erased, drop_ty); + let obj_ref_place = Place::from(self.new_temp(obj_ref_ty)); + + let term_loc = self.elaborator.terminator_loc(pin_obj_bb); + self.elaborator.patch().add_assign( + term_loc, + obj_ref_place, + Rvalue::Ref( + tcx.lifetimes.re_erased, + BorrowKind::Mut { kind: MutBorrowKind::Default }, + place, + ), + ); + + // pin_obj_place preparation + let pin_obj_new_unchecked_fn = Ty::new_fn_def( + tcx, + tcx.require_lang_item(LangItem::PinNewUnchecked, Some(span)), + [GenericArg::from(obj_ref_ty)], + ); + let pin_obj_ty = pin_obj_new_unchecked_fn.fn_sig(tcx).output().no_bound_vars().unwrap(); + let pin_obj_place = Place::from(self.new_temp(pin_obj_ty)); + let pin_obj_new_unchecked_fn = Operand::Constant(Box::new(ConstOperand { + span, + user_ty: None, + const_: Const::zero_sized(pin_obj_new_unchecked_fn), + })); + + // #3:drop_term_bb + let drop_term_bb = self.new_block( + unwind, + TerminatorKind::Drop { + place, + target: succ, + unwind: unwind.into_action(), + replace: false, + drop: dropline, + async_fut: Some(fut.local), + }, + ); + + // #2:call_drop_bb + let mut call_statements = Vec::new(); + let drop_arg = if call_destructor_only { + pin_obj_place + } else { + let ty::Adt(adt_def, adt_args) = pin_obj_ty.kind() else { + bug!(); + }; + let obj_ptr_ty = Ty::new_mut_ptr(tcx, drop_ty); + let obj_ptr_place = Place::from(self.new_temp(obj_ptr_ty)); + let unwrap_ty = adt_def.non_enum_variant().fields[FieldIdx::ZERO].ty(tcx, adt_args); + let addr = Rvalue::RawPtr( + RawPtrKind::Mut, + pin_obj_place.project_deeper( + &[ProjectionElem::Field(FieldIdx::ZERO, unwrap_ty), ProjectionElem::Deref], + tcx, + ), + ); + call_statements.push(self.assign(obj_ptr_place, addr)); + obj_ptr_place + }; + call_statements.push(Statement { + source_info: self.source_info, + kind: StatementKind::StorageLive(fut.local), + }); + + let call_drop_bb = self.new_block_with_statements( + unwind, + call_statements, + TerminatorKind::Call { + func: Operand::function_handle(tcx, drop_fn_def_id, trait_args, span), + args: [Spanned { node: Operand::Move(drop_arg), span: DUMMY_SP }].into(), + destination: fut, + target: Some(drop_term_bb), + unwind: unwind.into_action(), + call_source: CallSource::Misc, + fn_span: self.source_info.span, + }, + ); + + // StorageDead(fut) in self.succ block (at the begin) + self.elaborator.patch().add_statement( + Location { block: self.succ, statement_index: 0 }, + StatementKind::StorageDead(fut.local), + ); + + // #1:pin_obj_bb >>> call Pin::new_unchecked(&mut obj) + self.elaborator.patch().patch_terminator( + pin_obj_bb, + TerminatorKind::Call { + func: pin_obj_new_unchecked_fn, + args: [dummy_spanned(Operand::Move(obj_ref_place))].into(), + destination: pin_obj_place, + target: Some(call_drop_bb), + unwind: unwind.into_action(), + call_source: CallSource::Misc, + fn_span: span, + }, + ); + pin_obj_bb + } + + fn build_drop(&mut self, bb: BasicBlock) { + let drop_ty = self.place_ty(self.place); + if self.tcx().features().async_drop() + && self.elaborator.body().coroutine.is_some() + && self.elaborator.allow_async_drops() + && !self.elaborator.body()[bb].is_cleanup + && drop_ty.needs_async_drop(self.tcx(), self.elaborator.typing_env()) + { + self.build_async_drop( + self.place, + drop_ty, + Some(bb), + self.succ, + self.unwind, + self.dropline, + false, + ); + } else { + self.elaborator.patch().patch_terminator( + bb, + TerminatorKind::Drop { + place: self.place, + target: self.succ, + unwind: self.unwind.into_action(), + replace: false, + drop: None, + async_fut: None, + }, + ); + } + } + /// This elaborates a single drop instruction, located at `bb`, and /// patches over it. /// @@ -222,15 +430,7 @@ where .patch_terminator(bb, TerminatorKind::Goto { target: self.succ }); } DropStyle::Static => { - self.elaborator.patch().patch_terminator( - bb, - TerminatorKind::Drop { - place: self.place, - target: self.succ, - unwind: self.unwind.into_action(), - replace: false, - }, - ); + self.build_drop(bb); } DropStyle::Conditional => { let drop_bb = self.complete_drop(self.succ, self.unwind); @@ -289,6 +489,7 @@ where path: Option, succ: BasicBlock, unwind: Unwind, + dropline: Option, ) -> BasicBlock { if let Some(path) = path { debug!("drop_subpath: for std field {:?}", place); @@ -300,6 +501,7 @@ where place, succ, unwind, + dropline, } .elaborated_drop_block() } else { @@ -311,6 +513,7 @@ where place, succ, unwind, + dropline, // Using `self.path` here to condition the drop on // our own drop flag. path: self.path, @@ -325,25 +528,36 @@ where /// /// `unwind_ladder` is such a list of steps in reverse order, /// which is called if the matching step of the drop glue panics. + /// + /// `dropline_ladder` is a similar list of steps in reverse order, + /// which is called if the matching step of the drop glue will contain async drop + /// (expanded later to Yield) and the containing coroutine will be dropped at this point. fn drop_halfladder( &mut self, unwind_ladder: &[Unwind], + dropline_ladder: &[Option], mut succ: BasicBlock, fields: &[(Place<'tcx>, Option)], ) -> Vec { iter::once(succ) - .chain(fields.iter().rev().zip(unwind_ladder).map(|(&(place, path), &unwind_succ)| { - succ = self.drop_subpath(place, path, succ, unwind_succ); - succ - })) + .chain(itertools::izip!(fields.iter().rev(), unwind_ladder, dropline_ladder).map( + |(&(place, path), &unwind_succ, &dropline_to)| { + succ = self.drop_subpath(place, path, succ, unwind_succ, dropline_to); + succ + }, + )) .collect() } - fn drop_ladder_bottom(&mut self) -> (BasicBlock, Unwind) { + fn drop_ladder_bottom(&mut self) -> (BasicBlock, Unwind, Option) { // Clear the "master" drop flag at the end. This is needed // because the "master" drop protects the ADT's discriminant, // which is invalidated after the ADT is dropped. - (self.drop_flag_reset_block(DropFlagMode::Shallow, self.succ, self.unwind), self.unwind) + ( + self.drop_flag_reset_block(DropFlagMode::Shallow, self.succ, self.unwind), + self.unwind, + self.dropline, + ) } /// Creates a full drop ladder, consisting of 2 connected half-drop-ladders @@ -361,6 +575,22 @@ where /// .c2: /// ELAB(drop location.2 [target=`self.unwind`]) /// + /// For possible-async drops in coroutines we also need dropline ladder + /// .d0 (mainline): + /// ELAB(drop location.0 [target=.d1, unwind=.c1, drop=.e1]) + /// .d1 (mainline): + /// ELAB(drop location.1 [target=.d2, unwind=.c2, drop=.e2]) + /// .d2 (mainline): + /// ELAB(drop location.2 [target=`self.succ`, unwind=`self.unwind`, drop=`self.drop`]) + /// .c1 (unwind): + /// ELAB(drop location.1 [target=.c2]) + /// .c2 (unwind): + /// ELAB(drop location.2 [target=`self.unwind`]) + /// .e1 (dropline): + /// ELAB(drop location.1 [target=.e2, unwind=.c2]) + /// .e2 (dropline): + /// ELAB(drop location.2 [target=`self.drop`, unwind=`self.unwind`]) + /// /// NOTE: this does not clear the master drop flag, so you need /// to point succ/unwind on a `drop_ladder_bottom`. fn drop_ladder( @@ -368,8 +598,13 @@ where fields: Vec<(Place<'tcx>, Option)>, succ: BasicBlock, unwind: Unwind, - ) -> (BasicBlock, Unwind) { + dropline: Option, + ) -> (BasicBlock, Unwind, Option) { debug!("drop_ladder({:?}, {:?})", self, fields); + assert!( + if unwind.is_cleanup() { dropline.is_none() } else { true }, + "Dropline is set for cleanup drop ladder" + ); let mut fields = fields; fields.retain(|&(place, _)| { @@ -378,17 +613,28 @@ where debug!("drop_ladder - fields needing drop: {:?}", fields); + let dropline_ladder: Vec> = vec![None; fields.len() + 1]; let unwind_ladder = vec![Unwind::InCleanup; fields.len() + 1]; - let unwind_ladder: Vec<_> = if let Unwind::To(target) = unwind { - let halfladder = self.drop_halfladder(&unwind_ladder, target, &fields); + let unwind_ladder: Vec<_> = if let Unwind::To(succ) = unwind { + let halfladder = self.drop_halfladder(&unwind_ladder, &dropline_ladder, succ, &fields); halfladder.into_iter().map(Unwind::To).collect() } else { unwind_ladder }; + let dropline_ladder: Vec<_> = if let Some(succ) = dropline { + let halfladder = self.drop_halfladder(&unwind_ladder, &dropline_ladder, succ, &fields); + halfladder.into_iter().map(Some).collect() + } else { + dropline_ladder + }; - let normal_ladder = self.drop_halfladder(&unwind_ladder, succ, &fields); + let normal_ladder = self.drop_halfladder(&unwind_ladder, &dropline_ladder, succ, &fields); - (*normal_ladder.last().unwrap(), *unwind_ladder.last().unwrap()) + ( + *normal_ladder.last().unwrap(), + *unwind_ladder.last().unwrap(), + *dropline_ladder.last().unwrap(), + ) } fn open_drop_for_tuple(&mut self, tys: &[Ty<'tcx>]) -> BasicBlock { @@ -405,8 +651,8 @@ where }) .collect(); - let (succ, unwind) = self.drop_ladder_bottom(); - self.drop_ladder(fields, succ, unwind).0 + let (succ, unwind, dropline) = self.drop_ladder_bottom(); + self.drop_ladder(fields, succ, unwind, dropline).0 } /// Drops the T contained in a `Box` if it has not been moved out of @@ -417,6 +663,7 @@ where args: GenericArgsRef<'tcx>, succ: BasicBlock, unwind: Unwind, + dropline: Option, ) -> BasicBlock { // drop glue is sent straight to codegen // box cannot be directly dereferenced @@ -433,7 +680,7 @@ where let interior = self.tcx().mk_place_deref(Place::from(ptr_local)); let interior_path = self.elaborator.deref_subpath(self.path); - let do_drop_bb = self.drop_subpath(interior, interior_path, succ, unwind); + let do_drop_bb = self.drop_subpath(interior, interior_path, succ, unwind, dropline); let setup_bbd = BasicBlockData { statements: vec![self.assign( @@ -468,19 +715,22 @@ where let skip_contents = adt.is_union() || adt.is_manually_drop(); let contents_drop = if skip_contents { - (self.succ, self.unwind) + (self.succ, self.unwind, self.dropline) } else { self.open_drop_for_adt_contents(adt, args) }; if adt.is_box() { // we need to drop the inside of the box before running the destructor - let succ = self.destructor_call_block(contents_drop); + let succ = self.destructor_call_block_sync((contents_drop.0, contents_drop.1)); let unwind = contents_drop .1 - .map(|unwind| self.destructor_call_block((unwind, Unwind::InCleanup))); + .map(|unwind| self.destructor_call_block_sync((unwind, Unwind::InCleanup))); + let dropline = contents_drop + .2 + .map(|dropline| self.destructor_call_block_sync((dropline, contents_drop.1))); - self.open_drop_for_box_contents(adt, args, succ, unwind) + self.open_drop_for_box_contents(adt, args, succ, unwind, dropline) } else if adt.has_dtor(self.tcx()) { self.destructor_call_block(contents_drop) } else { @@ -492,14 +742,14 @@ where &mut self, adt: ty::AdtDef<'tcx>, args: GenericArgsRef<'tcx>, - ) -> (BasicBlock, Unwind) { - let (succ, unwind) = self.drop_ladder_bottom(); + ) -> (BasicBlock, Unwind, Option) { + let (succ, unwind, dropline) = self.drop_ladder_bottom(); if !adt.is_enum() { let fields = self.move_paths_for_fields(self.place, self.path, adt.variant(FIRST_VARIANT), args); - self.drop_ladder(fields, succ, unwind) + self.drop_ladder(fields, succ, unwind, dropline) } else { - self.open_drop_for_multivariant(adt, args, succ, unwind) + self.open_drop_for_multivariant(adt, args, succ, unwind, dropline) } } @@ -509,11 +759,14 @@ where args: GenericArgsRef<'tcx>, succ: BasicBlock, unwind: Unwind, - ) -> (BasicBlock, Unwind) { + dropline: Option, + ) -> (BasicBlock, Unwind, Option) { let mut values = Vec::with_capacity(adt.variants().len()); let mut normal_blocks = Vec::with_capacity(adt.variants().len()); let mut unwind_blocks = if unwind.is_cleanup() { None } else { Some(Vec::with_capacity(adt.variants().len())) }; + let mut dropline_blocks = + if dropline.is_none() { None } else { Some(Vec::with_capacity(adt.variants().len())) }; let mut have_otherwise_with_drop_glue = false; let mut have_otherwise = false; @@ -551,11 +804,16 @@ where let unwind_blocks = unwind_blocks.as_mut().unwrap(); let unwind_ladder = vec![Unwind::InCleanup; fields.len() + 1]; - let halfladder = self.drop_halfladder(&unwind_ladder, unwind, &fields); + let dropline_ladder: Vec> = vec![None; fields.len() + 1]; + let halfladder = + self.drop_halfladder(&unwind_ladder, &dropline_ladder, unwind, &fields); unwind_blocks.push(halfladder.last().cloned().unwrap()); } - let (normal, _) = self.drop_ladder(fields, succ, unwind); + let (normal, _, drop_bb) = self.drop_ladder(fields, succ, unwind, dropline); normal_blocks.push(normal); + if dropline.is_some() { + dropline_blocks.as_mut().unwrap().push(drop_bb.unwrap()); + } } else { have_otherwise = true; @@ -595,6 +853,9 @@ where Unwind::InCleanup, ) }), + dropline.map(|dropline| { + self.adt_switch_block(adt, dropline_blocks.unwrap(), &values, dropline, unwind) + }), ) } @@ -634,8 +895,8 @@ where self.drop_flag_test_block(switch_block, succ, unwind) } - fn destructor_call_block(&mut self, (succ, unwind): (BasicBlock, Unwind)) -> BasicBlock { - debug!("destructor_call_block({:?}, {:?})", self, succ); + fn destructor_call_block_sync(&mut self, (succ, unwind): (BasicBlock, Unwind)) -> BasicBlock { + debug!("destructor_call_block_sync({:?}, {:?})", self, succ); let tcx = self.tcx(); let drop_trait = tcx.require_lang_item(LangItem::Drop, None); let drop_fn = tcx.associated_item_def_ids(drop_trait)[0]; @@ -683,6 +944,30 @@ where self.drop_flag_test_block(destructor_block, succ, unwind) } + fn destructor_call_block( + &mut self, + (succ, unwind, dropline): (BasicBlock, Unwind, Option), + ) -> BasicBlock { + debug!("destructor_call_block({:?}, {:?})", self, succ); + let ty = self.place_ty(self.place); + if self.tcx().features().async_drop() + && self.elaborator.body().coroutine.is_some() + && self.elaborator.allow_async_drops() + && !unwind.is_cleanup() + && ty.is_async_drop(self.tcx(), self.elaborator.typing_env()) + { + let destructor_block = + self.build_async_drop(self.place, ty, None, succ, unwind, dropline, true); + + let block_start = Location { block: destructor_block, statement_index: 0 }; + self.elaborator.clear_drop_flag(block_start, self.path, DropFlagMode::Shallow); + + self.drop_flag_test_block(destructor_block, succ, unwind) + } else { + self.destructor_call_block_sync((succ, unwind)) + } + } + /// Create a loop that drops an array: /// /// ```text @@ -701,6 +986,7 @@ where len: Local, ety: Ty<'tcx>, unwind: Unwind, + dropline: Option, ) -> BasicBlock { let copy = |place: Place<'tcx>| Operand::Copy(place); let move_ = |place: Place<'tcx>| Operand::Move(place); @@ -744,16 +1030,35 @@ where }; let loop_block = self.elaborator.patch().new_block(loop_block); - self.elaborator.patch().patch_terminator( - drop_block, - TerminatorKind::Drop { - place: tcx.mk_place_deref(ptr), - target: loop_block, - unwind: unwind.into_action(), - replace: false, - }, - ); - + let place = tcx.mk_place_deref(ptr); + if self.tcx().features().async_drop() + && self.elaborator.body().coroutine.is_some() + && self.elaborator.allow_async_drops() + && !unwind.is_cleanup() + && ety.needs_async_drop(self.tcx(), self.elaborator.typing_env()) + { + self.build_async_drop( + place, + ety, + Some(drop_block), + loop_block, + unwind, + dropline, + false, + ); + } else { + self.elaborator.patch().patch_terminator( + drop_block, + TerminatorKind::Drop { + place, + target: loop_block, + unwind: unwind.into_action(), + replace: false, + drop: None, + async_fut: None, + }, + ); + } loop_block } @@ -820,8 +1125,8 @@ where (tcx.mk_place_elem(self.place, project), path) }) .collect::>(); - let (succ, unwind) = self.drop_ladder_bottom(); - return self.drop_ladder(fields, succ, unwind).0; + let (succ, unwind, dropline) = self.drop_ladder_bottom(); + return self.drop_ladder(fields, succ, unwind, dropline).0; } } @@ -855,7 +1160,7 @@ where &mut self.place, Place::from(slice_ptr).project_deeper(&[PlaceElem::Deref], tcx), ); - let slice_block = self.drop_loop_pair_for_slice(ety); + let slice_block = self.drop_loop_trio_for_slice(ety); self.place = array_place; delegate_block.terminator = Some(Terminator { @@ -865,18 +1170,22 @@ where self.elaborator.patch().new_block(delegate_block) } - /// Creates a pair of drop-loops of `place`, which drops its contents, even - /// in the case of 1 panic. - fn drop_loop_pair_for_slice(&mut self, ety: Ty<'tcx>) -> BasicBlock { - debug!("drop_loop_pair_for_slice({:?})", ety); + /// Creates a trio of drop-loops of `place`, which drops its contents, even + /// in the case of 1 panic or in the case of coroutine drop + fn drop_loop_trio_for_slice(&mut self, ety: Ty<'tcx>) -> BasicBlock { + debug!("drop_loop_trio_for_slice({:?})", ety); let tcx = self.tcx(); let len = self.new_temp(tcx.types.usize); let cur = self.new_temp(tcx.types.usize); - let unwind = - self.unwind.map(|unwind| self.drop_loop(unwind, cur, len, ety, Unwind::InCleanup)); + let unwind = self + .unwind + .map(|unwind| self.drop_loop(unwind, cur, len, ety, Unwind::InCleanup, None)); - let loop_block = self.drop_loop(self.succ, cur, len, ety, unwind); + let dropline = + self.dropline.map(|dropline| self.drop_loop(dropline, cur, len, ety, unwind, None)); + + let loop_block = self.drop_loop(self.succ, cur, len, ety, unwind, dropline); let [PlaceElem::Deref] = self.place.projection.as_slice() else { span_bug!( @@ -940,7 +1249,7 @@ where let size = size.try_to_target_usize(self.tcx()); self.open_drop_for_array(ty, *ety, size) } - ty::Slice(ety) => self.drop_loop_pair_for_slice(*ety), + ty::Slice(ety) => self.drop_loop_trio_for_slice(*ety), _ => span_bug!(self.source_info.span, "open drop from non-ADT `{:?}`", ty), } @@ -977,21 +1286,53 @@ where fn elaborated_drop_block(&mut self) -> BasicBlock { debug!("elaborated_drop_block({:?})", self); - let blk = self.drop_block(self.succ, self.unwind); + let blk = self.drop_block_simple(self.succ, self.unwind); self.elaborate_drop(blk); blk } - fn drop_block(&mut self, target: BasicBlock, unwind: Unwind) -> BasicBlock { + fn drop_block_simple(&mut self, target: BasicBlock, unwind: Unwind) -> BasicBlock { let block = TerminatorKind::Drop { place: self.place, target, unwind: unwind.into_action(), replace: false, + drop: self.dropline, + async_fut: None, }; self.new_block(unwind, block) } + fn drop_block(&mut self, target: BasicBlock, unwind: Unwind) -> BasicBlock { + let drop_ty = self.place_ty(self.place); + if self.tcx().features().async_drop() + && self.elaborator.body().coroutine.is_some() + && self.elaborator.allow_async_drops() + && !unwind.is_cleanup() + && drop_ty.needs_async_drop(self.tcx(), self.elaborator.typing_env()) + { + self.build_async_drop( + self.place, + drop_ty, + None, + self.succ, + unwind, + self.dropline, + false, + ) + } else { + let block = TerminatorKind::Drop { + place: self.place, + target, + unwind: unwind.into_action(), + replace: false, + drop: None, + async_fut: None, + }; + self.new_block(unwind, block) + } + } + fn goto_block(&mut self, target: BasicBlock, unwind: Unwind) -> BasicBlock { let block = TerminatorKind::Goto { target }; self.new_block(unwind, block) @@ -1033,6 +1374,19 @@ where }) } + fn new_block_with_statements( + &mut self, + unwind: Unwind, + statements: Vec>, + k: TerminatorKind<'tcx>, + ) -> BasicBlock { + self.elaborator.patch().new_block(BasicBlockData { + statements, + terminator: Some(Terminator { source_info: self.source_info, kind: k }), + is_cleanup: unwind.is_cleanup(), + }) + } + fn new_temp(&mut self, ty: Ty<'tcx>) -> Local { self.elaborator.patch().new_temp(ty, self.source_info.span) } diff --git a/compiler/rustc_mir_transform/src/elaborate_drops.rs b/compiler/rustc_mir_transform/src/elaborate_drops.rs index 530c72ca549..42c8cb0b906 100644 --- a/compiler/rustc_mir_transform/src/elaborate_drops.rs +++ b/compiler/rustc_mir_transform/src/elaborate_drops.rs @@ -158,6 +158,14 @@ impl<'a, 'tcx> DropElaborator<'a, 'tcx> for ElaborateDropsCtxt<'a, 'tcx> { self.env.typing_env } + fn allow_async_drops(&self) -> bool { + true + } + + fn terminator_loc(&self, bb: BasicBlock) -> Location { + self.patch.terminator_loc(self.body, bb) + } + #[instrument(level = "debug", skip(self), ret)] fn drop_style(&self, path: Self::Path, mode: DropFlagMode) -> DropStyle { let ((maybe_init, maybe_uninit), multipart) = match mode { @@ -328,7 +336,9 @@ impl<'a, 'tcx> ElaborateDropsCtxt<'a, 'tcx> { // This function should mirror what `collect_drop_flags` does. for (bb, data) in self.body.basic_blocks.iter_enumerated() { let terminator = data.terminator(); - let TerminatorKind::Drop { place, target, unwind, replace } = terminator.kind else { + let TerminatorKind::Drop { place, target, unwind, replace, drop, async_fut: _ } = + terminator.kind + else { continue; }; @@ -364,7 +374,16 @@ impl<'a, 'tcx> ElaborateDropsCtxt<'a, 'tcx> { } }; self.init_data.seek_before(self.body.terminator_loc(bb)); - elaborate_drop(self, terminator.source_info, place, path, target, unwind, bb) + elaborate_drop( + self, + terminator.source_info, + place, + path, + target, + unwind, + bb, + drop, + ) } LookupResult::Parent(None) => {} LookupResult::Parent(Some(_)) => { diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs index c5732194424..9785c039d53 100644 --- a/compiler/rustc_mir_transform/src/inline.rs +++ b/compiler/rustc_mir_transform/src/inline.rs @@ -413,7 +413,15 @@ impl<'tcx> Inliner<'tcx> for NormalInliner<'tcx> { let term = blk.terminator(); let caller_attrs = tcx.codegen_fn_attrs(self.caller_def_id()); - if let TerminatorKind::Drop { ref place, target, unwind, replace: _ } = term.kind { + if let TerminatorKind::Drop { + ref place, + target, + unwind, + replace: _, + drop: _, + async_fut: _, + } = term.kind + { work_list.push(target); // If the place doesn't actually need dropping, treat it like a regular goto. @@ -726,6 +734,20 @@ fn check_mir_is_available<'tcx, I: Inliner<'tcx>>( debug!("still needs substitution"); return Err("implementation limitation -- HACK for dropping polymorphic type"); } + InstanceKind::AsyncDropGlue(_, ty) | InstanceKind::AsyncDropGlueCtorShim(_, ty) => { + return if ty.still_further_specializable() { + Err("still needs substitution") + } else { + Ok(()) + }; + } + InstanceKind::FutureDropPollShim(_, ty, ty2) => { + return if ty.still_further_specializable() || ty2.still_further_specializable() { + Err("still needs substitution") + } else { + Ok(()) + }; + } // This cannot result in an immediate cycle since the callee MIR is a shim, which does // not get any optimizations run on it. Any subsequent inlining may cause cycles, but we @@ -739,8 +761,7 @@ fn check_mir_is_available<'tcx, I: Inliner<'tcx>>( | InstanceKind::DropGlue(..) | InstanceKind::CloneShim(..) | InstanceKind::ThreadLocalShim(..) - | InstanceKind::FnPtrAddrShim(..) - | InstanceKind::AsyncDropGlueCtorShim(..) => return Ok(()), + | InstanceKind::FnPtrAddrShim(..) => return Ok(()), } if inliner.tcx().is_constructor(callee_def_id) { @@ -1345,8 +1366,8 @@ fn try_instance_mir<'tcx>( tcx: TyCtxt<'tcx>, instance: InstanceKind<'tcx>, ) -> Result<&'tcx Body<'tcx>, &'static str> { - if let ty::InstanceKind::DropGlue(_, Some(ty)) - | ty::InstanceKind::AsyncDropGlueCtorShim(_, Some(ty)) = instance + if let ty::InstanceKind::DropGlue(_, Some(ty)) | ty::InstanceKind::AsyncDropGlueCtorShim(_, ty) = + instance && let ty::Adt(def, args) = ty.kind() { let fields = def.all_fields(); diff --git a/compiler/rustc_mir_transform/src/inline/cycle.rs b/compiler/rustc_mir_transform/src/inline/cycle.rs index a40768300f5..292278800f8 100644 --- a/compiler/rustc_mir_transform/src/inline/cycle.rs +++ b/compiler/rustc_mir_transform/src/inline/cycle.rs @@ -95,7 +95,10 @@ pub(crate) fn mir_callgraph_reachable<'tcx>( InstanceKind::FnPtrAddrShim(..) => { continue; } - InstanceKind::DropGlue(..) | InstanceKind::AsyncDropGlueCtorShim(..) => { + InstanceKind::DropGlue(..) + | InstanceKind::FutureDropPollShim(..) + | InstanceKind::AsyncDropGlue(..) + | InstanceKind::AsyncDropGlueCtorShim(..) => { // FIXME: A not fully instantiated drop shim can cause ICEs if one attempts to // have its MIR built. Likely oli-obk just screwed up the `ParamEnv`s, so this // needs some more analysis. diff --git a/compiler/rustc_mir_transform/src/known_panics_lint.rs b/compiler/rustc_mir_transform/src/known_panics_lint.rs index f8db8de4e82..481c7941909 100644 --- a/compiler/rustc_mir_transform/src/known_panics_lint.rs +++ b/compiler/rustc_mir_transform/src/known_panics_lint.rs @@ -888,7 +888,14 @@ impl CanConstProp { }; for (local, val) in cpv.can_const_prop.iter_enumerated_mut() { let ty = body.local_decls[local].ty; - if ty.is_union() { + if ty.is_async_drop_in_place_coroutine(tcx) { + // No const propagation for async drop coroutine (AsyncDropGlue). + // Otherwise, tcx.layout_of(typing_env.as_query_input(ty)) will be called + // (early layout request for async drop coroutine) to calculate layout size. + // Layout for `async_drop_in_place::{closure}` may only be known with known T. + *val = ConstPropMode::NoPropagation; + continue; + } else if ty.is_union() { // Unions are incompatible with the current implementation of // const prop because Rust has no concept of an active // variant of a union diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index 5db62b7e902..24f4c11a66d 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -652,7 +652,7 @@ fn run_runtime_cleanup_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { } } -fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { +pub(crate) fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { fn o1(x: T) -> WithMinOptLevel { WithMinOptLevel(1, x) } diff --git a/compiler/rustc_mir_transform/src/lint_tail_expr_drop_order.rs b/compiler/rustc_mir_transform/src/lint_tail_expr_drop_order.rs index 537f152938e..b8cb101f93c 100644 --- a/compiler/rustc_mir_transform/src/lint_tail_expr_drop_order.rs +++ b/compiler/rustc_mir_transform/src/lint_tail_expr_drop_order.rs @@ -134,6 +134,8 @@ impl<'a, 'mir, 'tcx> DropsReachable<'a, 'mir, 'tcx> { target: _, unwind: _, replace: _, + drop: _, + async_fut: _, } = &terminator.kind && place_has_common_prefix(dropped_place, self.place) { diff --git a/compiler/rustc_mir_transform/src/patch.rs b/compiler/rustc_mir_transform/src/patch.rs index 12ace04c5e2..c7eb2a921c7 100644 --- a/compiler/rustc_mir_transform/src/patch.rs +++ b/compiler/rustc_mir_transform/src/patch.rs @@ -148,6 +148,14 @@ impl<'tcx> MirPatch<'tcx> { self.term_patch_map[bb].is_some() } + pub(crate) fn terminator_loc(&self, body: &Body<'tcx>, bb: BasicBlock) -> Location { + let offset = match bb.index().checked_sub(body.basic_blocks.len()) { + Some(index) => self.new_blocks[index].statements.len(), + None => body[bb].statements.len(), + }; + Location { block: bb, statement_index: offset } + } + /// Queues the addition of a new temporary with additional local info. pub(crate) fn new_local_with_info( &mut self, diff --git a/compiler/rustc_mir_transform/src/remove_zsts.rs b/compiler/rustc_mir_transform/src/remove_zsts.rs index 78d94a03867..c4dc8638b26 100644 --- a/compiler/rustc_mir_transform/src/remove_zsts.rs +++ b/compiler/rustc_mir_transform/src/remove_zsts.rs @@ -59,6 +59,11 @@ fn trivially_zst<'tcx>(ty: Ty<'tcx>, tcx: TyCtxt<'tcx>) -> Option { | ty::RawPtr(..) | ty::Ref(..) | ty::FnPtr(..) => Some(false), + ty::Coroutine(def_id, _) => { + // For async_drop_in_place::{closure} this is load bearing, not just a perf fix, + // because we don't want to compute the layout before mir analysis is done + if tcx.is_async_drop_in_place_coroutine(*def_id) { Some(false) } else { None } + } // check `layout_of` to see (including unreachable things we won't actually see) _ => None, } diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs index 2c92b4a752c..0d9a04b760a 100644 --- a/compiler/rustc_mir_transform/src/shim.rs +++ b/compiler/rustc_mir_transform/src/shim.rs @@ -6,13 +6,14 @@ use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_hir::lang_items::LangItem; use rustc_index::{Idx, IndexVec}; +use rustc_middle::mir::visit::{MutVisitor, PlaceContext}; use rustc_middle::mir::*; use rustc_middle::query::Providers; use rustc_middle::ty::{ self, CoroutineArgs, CoroutineArgsExt, EarlyBinder, GenericArgs, Ty, TyCtxt, }; use rustc_middle::{bug, span_bug}; -use rustc_span::source_map::Spanned; +use rustc_span::source_map::{Spanned, dummy_spanned}; use rustc_span::{DUMMY_SP, Span}; use tracing::{debug, instrument}; @@ -20,7 +21,8 @@ use crate::elaborate_drop::{DropElaborator, DropFlagMode, DropStyle, Unwind, ela use crate::patch::MirPatch; use crate::{ abort_unwinding_calls, add_call_guards, add_moves_for_packed_drops, deref_separator, inline, - instsimplify, mentioned_items, pass_manager as pm, remove_noop_landing_pads, simplify, + instsimplify, mentioned_items, pass_manager as pm, remove_noop_landing_pads, + run_optimization_passes, simplify, }; mod async_destructor_ctor; @@ -29,6 +31,40 @@ pub(super) fn provide(providers: &mut Providers) { providers.mir_shims = make_shim; } +// Replace Pin<&mut ImplCoroutine> accesses (_1.0) into Pin<&mut ProxyCoroutine> acceses +struct FixProxyFutureDropVisitor<'tcx> { + tcx: TyCtxt<'tcx>, + replace_to: Local, +} + +impl<'tcx> MutVisitor<'tcx> for FixProxyFutureDropVisitor<'tcx> { + fn tcx(&self) -> TyCtxt<'tcx> { + self.tcx + } + + fn visit_place( + &mut self, + place: &mut Place<'tcx>, + _context: PlaceContext, + _location: Location, + ) { + if place.local == Local::from_u32(1) { + if place.projection.len() == 1 { + assert!(matches!( + place.projection.first(), + Some(ProjectionElem::Field(FieldIdx::ZERO, _)) + )); + *place = Place::from(self.replace_to); + } else if place.projection.len() == 2 { + assert!(matches!(place.projection[0], ProjectionElem::Field(FieldIdx::ZERO, _))); + assert!(matches!(place.projection[1], ProjectionElem::Deref)); + *place = + Place::from(self.replace_to).project_deeper(&[ProjectionElem::Deref], self.tcx); + } + } + } +} + fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceKind<'tcx>) -> Body<'tcx> { debug!("make_shim({:?})", instance); @@ -129,8 +165,53 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceKind<'tcx>) -> Body< ty::InstanceKind::ThreadLocalShim(..) => build_thread_local_shim(tcx, instance), ty::InstanceKind::CloneShim(def_id, ty) => build_clone_shim(tcx, def_id, ty), ty::InstanceKind::FnPtrAddrShim(def_id, ty) => build_fn_ptr_addr_shim(tcx, def_id, ty), + ty::InstanceKind::FutureDropPollShim(def_id, proxy_ty, impl_ty) => { + let mut body = + async_destructor_ctor::build_future_drop_poll_shim(tcx, def_id, proxy_ty, impl_ty); + + pm::run_passes( + tcx, + &mut body, + &[ + &mentioned_items::MentionedItems, + &abort_unwinding_calls::AbortUnwindingCalls, + &add_call_guards::CriticalCallEdges, + ], + Some(MirPhase::Runtime(RuntimePhase::PostCleanup)), + pm::Optimizations::Allowed, + ); + run_optimization_passes(tcx, &mut body); + debug!("make_shim({:?}) = {:?}", instance, body); + return body; + } + ty::InstanceKind::AsyncDropGlue(def_id, ty) => { + let mut body = async_destructor_ctor::build_async_drop_shim(tcx, def_id, ty); + + // Main pass required here is StateTransform to convert sync drop ladder + // into coroutine. + // Others are minimal passes as for sync drop glue shim + pm::run_passes( + tcx, + &mut body, + &[ + &mentioned_items::MentionedItems, + &abort_unwinding_calls::AbortUnwindingCalls, + &add_call_guards::CriticalCallEdges, + &simplify::SimplifyCfg::MakeShim, + &crate::coroutine::StateTransform, + ], + Some(MirPhase::Runtime(RuntimePhase::PostCleanup)), + pm::Optimizations::Allowed, + ); + run_optimization_passes(tcx, &mut body); + debug!("make_shim({:?}) = {:?}", instance, body); + return body; + } + ty::InstanceKind::AsyncDropGlueCtorShim(def_id, ty) => { - async_destructor_ctor::build_async_destructor_ctor_shim(tcx, def_id, ty) + let body = async_destructor_ctor::build_async_destructor_ctor_shim(tcx, def_id, ty); + debug!("make_shim({:?}) = {:?}", instance, body); + return body; } ty::InstanceKind::Virtual(..) => { bug!("InstanceKind::Virtual ({:?}) is for direct calls only", instance) @@ -290,8 +371,13 @@ fn build_drop_shim<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, ty: Option>) if ty.is_some() { let patch = { let typing_env = ty::TypingEnv::post_analysis(tcx, def_id); - let mut elaborator = - DropShimElaborator { body: &body, patch: MirPatch::new(&body), tcx, typing_env }; + let mut elaborator = DropShimElaborator { + body: &body, + patch: MirPatch::new(&body), + tcx, + typing_env, + produce_async_drops: false, + }; let dropee = tcx.mk_place_deref(dropee_ptr); let resume_block = elaborator.patch.resume_block(); elaborate_drop( @@ -302,6 +388,7 @@ fn build_drop_shim<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, ty: Option>) return_block, Unwind::To(resume_block), START_BLOCK, + None, ); elaborator.patch }; @@ -350,6 +437,7 @@ pub(super) struct DropShimElaborator<'a, 'tcx> { pub patch: MirPatch<'tcx>, pub tcx: TyCtxt<'tcx>, pub typing_env: ty::TypingEnv<'tcx>, + pub produce_async_drops: bool, } impl fmt::Debug for DropShimElaborator<'_, '_> { @@ -377,6 +465,13 @@ impl<'a, 'tcx> DropElaborator<'a, 'tcx> for DropShimElaborator<'a, 'tcx> { self.typing_env } + fn terminator_loc(&self, bb: BasicBlock) -> Location { + self.patch.terminator_loc(self.body, bb) + } + fn allow_async_drops(&self) -> bool { + self.produce_async_drops + } + fn drop_style(&self, _path: Self::Path, mode: DropFlagMode) -> DropStyle { match mode { DropFlagMode::Shallow => { @@ -633,6 +728,8 @@ impl<'tcx> CloneShimBuilder<'tcx> { target: unwind, unwind: UnwindAction::Terminate(UnwindTerminateReason::InCleanup), replace: false, + drop: None, + async_fut: None, }, /* is_cleanup */ true, ); @@ -898,6 +995,8 @@ fn build_call_shim<'tcx>( target: BasicBlock::new(2), unwind: UnwindAction::Continue, replace: false, + drop: None, + async_fut: None, }, false, ); @@ -915,6 +1014,8 @@ fn build_call_shim<'tcx>( target: BasicBlock::new(4), unwind: UnwindAction::Terminate(UnwindTerminateReason::InCleanup), replace: false, + drop: None, + async_fut: None, }, /* is_cleanup */ true, ); 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 94b1b4b1855..7976b65aae7 100644 --- a/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs +++ b/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs @@ -1,639 +1,430 @@ -use std::iter; - -use itertools::Itertools; -use rustc_abi::{FieldIdx, VariantIdx}; -use rustc_const_eval::interpret; use rustc_hir::def_id::DefId; use rustc_hir::lang_items::LangItem; +use rustc_hir::{CoroutineDesugaring, CoroutineKind, CoroutineSource, Safety}; use rustc_index::{Idx, IndexVec}; -use rustc_middle::mir::*; -use rustc_middle::ty::adjustment::PointerCoercion; -use rustc_middle::ty::util::{AsyncDropGlueMorphology, 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::spec::PanicStrategy; -use tracing::debug; - -use super::{local_decls_for_sig, new_body}; +use rustc_middle::mir::{ + BasicBlock, BasicBlockData, Body, Local, LocalDecl, MirSource, Operand, Place, Rvalue, + SourceInfo, Statement, StatementKind, Terminator, TerminatorKind, +}; +use rustc_middle::ty::{self, EarlyBinder, Ty, TyCtxt}; + +use super::*; +use crate::patch::MirPatch; pub(super) fn build_async_destructor_ctor_shim<'tcx>( tcx: TyCtxt<'tcx>, def_id: DefId, - ty: Option>, + ty: Ty<'tcx>, ) -> Body<'tcx> { - debug!("build_drop_shim(def_id={:?}, ty={:?})", def_id, ty); - - AsyncDestructorCtorShimBuilder::new(tcx, def_id, ty).build() + debug!("build_async_destructor_ctor_shim(def_id={:?}, ty={:?})", def_id, ty); + debug_assert_eq!(Some(def_id), tcx.lang_items().async_drop_in_place_fn()); + let generic_body = tcx.optimized_mir(def_id); + let args = tcx.mk_args(&[ty.into()]); + let mut body = EarlyBinder::bind(generic_body.clone()).instantiate(tcx, args); + + // Minimal shim passes except MentionedItems, + // it causes error "mentioned_items for DefId(...async_drop_in_place...) have already been set + pm::run_passes( + tcx, + &mut body, + &[ + &simplify::SimplifyCfg::MakeShim, + &abort_unwinding_calls::AbortUnwindingCalls, + &add_call_guards::CriticalCallEdges, + ], + None, + pm::Optimizations::Allowed, + ); + body } -/// Builder for async_drop_in_place shim. Functions as a stack machine -/// to build up an expression using combinators. Stack contains pairs -/// of locals and types. Combinator is a not yet instantiated pair of a -/// function and a type, is considered to be an operator which consumes -/// operands from the stack by instantiating its function and its type -/// with operand types and moving locals into the function call. Top -/// pair is considered to be the last operand. -// FIXME: add mir-opt tests -struct AsyncDestructorCtorShimBuilder<'tcx> { +// build_drop_shim analog for async drop glue (for generated coroutine poll function) +pub(super) fn build_async_drop_shim<'tcx>( tcx: TyCtxt<'tcx>, def_id: DefId, - self_ty: Option>, - span: Span, - source_info: SourceInfo, - typing_env: ty::TypingEnv<'tcx>, - - stack: Vec>, - last_bb: BasicBlock, - top_cleanup_bb: Option, - - locals: IndexVec>, - bbs: IndexVec>, -} - -#[derive(Clone, Copy)] -enum SurfaceDropKind { - Async, - Sync, -} - -impl<'tcx> AsyncDestructorCtorShimBuilder<'tcx> { - const SELF_PTR: Local = Local::from_u32(1); - const INPUT_COUNT: usize = 1; - const MAX_STACK_LEN: usize = 2; - - fn new(tcx: TyCtxt<'tcx>, def_id: DefId, self_ty: Option>) -> Self { - let args = if let Some(ty) = self_ty { - tcx.mk_args(&[ty.into()]) + ty: Ty<'tcx>, +) -> Body<'tcx> { + debug!("build_async_drop_shim(def_id={:?}, ty={:?})", def_id, ty); + let ty::Coroutine(_, parent_args) = ty.kind() else { + bug!(); + }; + let typing_env = ty::TypingEnv::fully_monomorphized(); + + let drop_ty = parent_args.first().unwrap().expect_ty(); + let drop_ptr_ty = Ty::new_mut_ptr(tcx, drop_ty); + + assert!(tcx.is_coroutine(def_id)); + let coroutine_kind = tcx.coroutine_kind(def_id).unwrap(); + + assert!(matches!( + coroutine_kind, + CoroutineKind::Desugared(CoroutineDesugaring::Async, CoroutineSource::Fn) + )); + + let needs_async_drop = drop_ty.needs_async_drop(tcx, typing_env); + let needs_sync_drop = !needs_async_drop && drop_ty.needs_drop(tcx, typing_env); + + let resume_adt = tcx.adt_def(tcx.require_lang_item(LangItem::ResumeTy, None)); + let resume_ty = Ty::new_adt(tcx, resume_adt, ty::List::empty()); + + let fn_sig = ty::Binder::dummy(tcx.mk_fn_sig( + [ty, resume_ty], + tcx.types.unit, + false, + Safety::Safe, + ExternAbi::Rust, + )); + let sig = tcx.instantiate_bound_regions_with_erased(fn_sig); + + assert!(!drop_ty.is_coroutine()); + let span = tcx.def_span(def_id); + let source_info = SourceInfo::outermost(span); + + // The first argument (index 0), but add 1 for the return value. + let coroutine_layout = Place::from(Local::new(1 + 0)); + let coroutine_layout_dropee = + tcx.mk_place_field(coroutine_layout, FieldIdx::new(0), drop_ptr_ty); + + let return_block = BasicBlock::new(1); + let mut blocks = IndexVec::with_capacity(2); + let block = |blocks: &mut IndexVec<_, _>, kind| { + blocks.push(BasicBlockData { + statements: vec![], + terminator: Some(Terminator { source_info, kind }), + is_cleanup: false, + }) + }; + block( + &mut blocks, + if needs_sync_drop { + TerminatorKind::Drop { + place: tcx.mk_place_deref(coroutine_layout_dropee), + target: return_block, + unwind: UnwindAction::Continue, + replace: false, + drop: None, + async_fut: None, + } } else { - ty::GenericArgs::identity_for_item(tcx, def_id) - }; - let sig = tcx.fn_sig(def_id).instantiate(tcx, args); - let sig = tcx.instantiate_bound_regions_with_erased(sig); - let span = tcx.def_span(def_id); + TerminatorKind::Goto { target: return_block } + }, + ); + block(&mut blocks, TerminatorKind::Return); + + let source = MirSource::from_instance(ty::InstanceKind::AsyncDropGlue(def_id, ty)); + let mut body = + new_body(source, blocks, local_decls_for_sig(&sig, span), sig.inputs().len(), span); + + body.coroutine = Some(Box::new(CoroutineInfo::initial( + coroutine_kind, + parent_args.as_coroutine().yield_ty(), + parent_args.as_coroutine().resume_ty(), + ))); + body.phase = MirPhase::Runtime(RuntimePhase::Initial); + if !needs_async_drop { + // Returning noop body for types without `need async drop` + // (or sync Drop in case of !`need async drop` && `need drop`) + return body; + } - let source_info = SourceInfo::outermost(span); + let mut dropee_ptr = Place::from(body.local_decls.push(LocalDecl::new(drop_ptr_ty, span))); + let st_kind = StatementKind::Assign(Box::new(( + dropee_ptr, + Rvalue::Use(Operand::Move(coroutine_layout_dropee)), + ))); + body.basic_blocks_mut()[START_BLOCK].statements.push(Statement { source_info, kind: st_kind }); + dropee_ptr = dropee_emit_retag(tcx, &mut body, dropee_ptr, span); - debug_assert_eq!(sig.inputs().len(), Self::INPUT_COUNT); - let locals = local_decls_for_sig(&sig, span); + let dropline = body.basic_blocks.last_index(); - // Usual case: noop() + unwind resume + return - let mut bbs = IndexVec::with_capacity(3); - let typing_env = ty::TypingEnv::post_analysis(tcx, def_id); - AsyncDestructorCtorShimBuilder { + let patch = { + let mut elaborator = DropShimElaborator { + body: &body, + patch: MirPatch::new(&body), tcx, - def_id, - self_ty, - span, - source_info, typing_env, - - stack: Vec::with_capacity(Self::MAX_STACK_LEN), - last_bb: bbs.push(BasicBlockData::new(None, false)), - top_cleanup_bb: match tcx.sess.panic_strategy() { - PanicStrategy::Unwind => { - // Don't drop input arg because it's just a pointer - Some(bbs.push(BasicBlockData { - statements: Vec::new(), - terminator: Some(Terminator { - source_info, - kind: TerminatorKind::UnwindResume, - }), - is_cleanup: true, - })) - } - PanicStrategy::Abort => None, - }, - - locals, - bbs, - } - } - - fn build(self) -> Body<'tcx> { - let (tcx, Some(self_ty)) = (self.tcx, self.self_ty) else { - return self.build_zst_output(); - }; - match self_ty.async_drop_glue_morphology(tcx) { - AsyncDropGlueMorphology::Noop => span_bug!( - self.span, - "async drop glue shim generator encountered type with noop async drop glue morphology" - ), - AsyncDropGlueMorphology::DeferredDropInPlace => { - return self.build_deferred_drop_in_place(); - } - AsyncDropGlueMorphology::Custom => (), - } - - let surface_drop_kind = || { - let adt_def = self_ty.ty_adt_def()?; - if adt_def.async_destructor(tcx).is_some() { - Some(SurfaceDropKind::Async) - } else if adt_def.destructor(tcx).is_some() { - Some(SurfaceDropKind::Sync) - } else { - None - } + produce_async_drops: true, }; + let dropee = tcx.mk_place_deref(dropee_ptr); + let resume_block = elaborator.patch.resume_block(); + elaborate_drop( + &mut elaborator, + source_info, + dropee, + (), + return_block, + Unwind::To(resume_block), + START_BLOCK, + dropline, + ); + elaborator.patch + }; + patch.apply(&mut body); - match self_ty.kind() { - ty::Array(elem_ty, _) => self.build_slice(true, *elem_ty), - ty::Slice(elem_ty) => self.build_slice(false, *elem_ty), - - ty::Tuple(elem_tys) => self.build_chain(None, elem_tys.iter()), - ty::Adt(adt_def, args) if adt_def.is_struct() => { - let field_tys = adt_def.non_enum_variant().fields.iter().map(|f| f.ty(tcx, args)); - self.build_chain(surface_drop_kind(), field_tys) - } - ty::Closure(_, args) => self.build_chain(None, args.as_closure().upvar_tys().iter()), - ty::CoroutineClosure(_, args) => { - self.build_chain(None, args.as_coroutine_closure().upvar_tys().iter()) - } + body +} - ty::Adt(adt_def, args) if adt_def.is_enum() => { - self.build_enum(*adt_def, *args, surface_drop_kind()) - } +// * For async drop a "normal" coroutine: +// `async_drop_in_place::{closure}.poll()` is converted into `T.future_drop_poll()`. +// Every coroutine has its `poll` (calculate yourself a little further) +// and its `future_drop_poll` (drop yourself a little further). +// +// * For async drop of "async drop coroutine" (`async_drop_in_place::{closure}`): +// Correct drop of such coroutine means normal execution of nested async drop. +// async_drop(async_drop(T))::future_drop_poll() => async_drop(T)::poll(). +pub(super) fn build_future_drop_poll_shim<'tcx>( + tcx: TyCtxt<'tcx>, + def_id: DefId, + proxy_ty: Ty<'tcx>, + impl_ty: Ty<'tcx>, +) -> Body<'tcx> { + let instance = ty::InstanceKind::FutureDropPollShim(def_id, proxy_ty, impl_ty); + let ty::Coroutine(coroutine_def_id, _) = impl_ty.kind() else { + bug!("build_future_drop_poll_shim not for coroutine impl type: ({:?})", instance); + }; - ty::Adt(adt_def, _) => { - assert!(adt_def.is_union()); - match surface_drop_kind().unwrap() { - SurfaceDropKind::Async => self.build_fused_async_surface(), - SurfaceDropKind::Sync => self.build_fused_sync_surface(), - } - } + let span = tcx.def_span(def_id); - ty::Bound(..) - | ty::Foreign(_) - | ty::Placeholder(_) - | ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_) | ty::TyVar(_)) - | ty::Param(_) - | ty::Alias(..) => { - bug!("Building async destructor for unexpected type: {self_ty:?}") - } - - _ => { - bug!( - "Building async destructor constructor shim is not yet implemented for type: {self_ty:?}" - ) - } - } + if tcx.is_async_drop_in_place_coroutine(*coroutine_def_id) { + build_adrop_for_adrop_shim(tcx, proxy_ty, impl_ty, span, instance) + } else { + build_adrop_for_coroutine_shim(tcx, proxy_ty, impl_ty, span, instance) } +} - fn build_enum( - mut self, - adt_def: ty::AdtDef<'tcx>, - args: ty::GenericArgsRef<'tcx>, - surface_drop: Option, - ) -> Body<'tcx> { - let tcx = self.tcx; - - let surface = match surface_drop { - None => None, - Some(kind) => { - self.put_self(); - Some(match kind { - SurfaceDropKind::Async => self.combine_async_surface(), - SurfaceDropKind::Sync => self.combine_sync_surface(), - }) - } - }; - - let mut other = None; - for (variant_idx, discr) in adt_def.discriminants(tcx) { - let variant = adt_def.variant(variant_idx); - - let mut chain = None; - for (field_idx, field) in variant.fields.iter_enumerated() { - let field_ty = field.ty(tcx, args); - self.put_variant_field(variant.name, variant_idx, field_idx, field_ty); - let defer = self.combine_defer(field_ty); - chain = Some(match chain { - None => defer, - Some(chain) => self.combine_chain(chain, defer), - }) - } - let variant_dtor = chain.unwrap_or_else(|| self.put_noop()); - - other = Some(match other { - None => variant_dtor, - Some(other) => { - self.put_self(); - self.put_discr(discr); - self.combine_either(other, variant_dtor) - } - }); - } - let variants_dtor = other.unwrap_or_else(|| self.put_noop()); - - let dtor = match surface { - None => variants_dtor, - Some(surface) => self.combine_chain(surface, variants_dtor), - }; - self.combine_fuse(dtor); - self.return_() - } +// For async drop a "normal" coroutine: +// `async_drop_in_place::{closure}.poll()` is converted into `T.future_drop_poll()`. +// Every coroutine has its `poll` (calculate yourself a little further) +// and its `future_drop_poll` (drop yourself a little further). +fn build_adrop_for_coroutine_shim<'tcx>( + tcx: TyCtxt<'tcx>, + proxy_ty: Ty<'tcx>, + impl_ty: Ty<'tcx>, + span: Span, + instance: ty::InstanceKind<'tcx>, +) -> Body<'tcx> { + let ty::Coroutine(coroutine_def_id, impl_args) = impl_ty.kind() else { + bug!("build_adrop_for_coroutine_shim not for coroutine impl type: ({:?})", instance); + }; + let proxy_ref = Ty::new_mut_ref(tcx, tcx.lifetimes.re_erased, proxy_ty); + // taking _1.0 (impl from Pin) + let pin_proxy_layout_local = Local::new(1); + let source_info = SourceInfo::outermost(span); + // converting `(_1: Pin<&mut CorLayout>, _2: &mut Context<'_>) -> Poll<()>` + // into `(_1: Pin<&mut ProxyLayout>, _2: &mut Context<'_>) -> Poll<()>` + // let mut _x: &mut CorLayout = &*_1.0.0; + // Replace old _1.0 accesses into _x accesses; + let body = tcx.optimized_mir(*coroutine_def_id).future_drop_poll().unwrap(); + let mut body: Body<'tcx> = EarlyBinder::bind(body.clone()).instantiate(tcx, impl_args); + body.source.instance = instance; + body.phase = MirPhase::Runtime(RuntimePhase::Initial); + body.var_debug_info.clear(); + let pin_adt_ref = tcx.adt_def(tcx.require_lang_item(LangItem::Pin, Some(span))); + let args = tcx.mk_args(&[proxy_ref.into()]); + let pin_proxy_ref = Ty::new_adt(tcx, pin_adt_ref, args); + + let cor_ref = Ty::new_mut_ref(tcx, tcx.lifetimes.re_erased, impl_ty); + + let proxy_ref_local = body.local_decls.push(LocalDecl::new(proxy_ref, span)); + let cor_ref_local = body.local_decls.push(LocalDecl::new(cor_ref, span)); + + FixProxyFutureDropVisitor { tcx, replace_to: cor_ref_local }.visit_body(&mut body); + // Now changing first arg from Pin<&mut ImplCoroutine> to Pin<&mut ProxyCoroutine> + body.local_decls[pin_proxy_layout_local] = LocalDecl::new(pin_proxy_ref, span); - fn build_chain(mut self, surface_drop: Option, elem_tys: I) -> Body<'tcx> - where - I: Iterator> + ExactSizeIterator, { - let surface = match surface_drop { - None => None, - Some(kind) => { - self.put_self(); - Some(match kind { - SurfaceDropKind::Async => self.combine_async_surface(), - SurfaceDropKind::Sync => self.combine_sync_surface(), - }) - } - }; - - let mut chain = None; - for (field_idx, field_ty) in elem_tys.enumerate().map(|(i, ty)| (FieldIdx::new(i), ty)) { - self.put_field(field_idx, field_ty); - let defer = self.combine_defer(field_ty); - chain = Some(match chain { - None => defer, - Some(chain) => self.combine_chain(chain, defer), - }) - } - let chain = chain.unwrap_or_else(|| self.put_noop()); - - let dtor = match surface { - None => chain, - Some(surface) => self.combine_chain(surface, chain), - }; - self.combine_fuse(dtor); - self.return_() - } - - fn build_zst_output(mut self) -> Body<'tcx> { - self.put_zst_output(); - self.return_() - } - - fn build_deferred_drop_in_place(mut self) -> Body<'tcx> { - self.put_self(); - let deferred = self.combine_deferred_drop_in_place(); - self.combine_fuse(deferred); - self.return_() - } - - fn build_fused_async_surface(mut self) -> Body<'tcx> { - self.put_self(); - let surface = self.combine_async_surface(); - self.combine_fuse(surface); - self.return_() - } - - fn build_fused_sync_surface(mut self) -> Body<'tcx> { - self.put_self(); - let surface = self.combine_sync_surface(); - self.combine_fuse(surface); - self.return_() - } - - fn build_slice(mut self, is_array: bool, elem_ty: Ty<'tcx>) -> Body<'tcx> { - if is_array { - self.put_array_as_slice(elem_ty) - } else { - self.put_self() - } - let dtor = self.combine_slice(elem_ty); - self.combine_fuse(dtor); - self.return_() - } - - fn put_zst_output(&mut self) { - let return_ty = self.locals[RETURN_PLACE].ty; - self.put_operand(Operand::Constant(Box::new(ConstOperand { - span: self.span, - user_ty: None, - const_: Const::zero_sized(return_ty), - }))); - } - - /// Puts `to_drop: *mut Self` on top of the stack. - fn put_self(&mut self) { - self.put_operand(Operand::Copy(Self::SELF_PTR.into())) - } - - /// Given that `Self is [ElemTy; N]` puts `to_drop: *mut [ElemTy]` - /// on top of the stack. - fn put_array_as_slice(&mut self, elem_ty: Ty<'tcx>) { - let slice_ptr_ty = Ty::new_mut_ptr(self.tcx, Ty::new_slice(self.tcx, elem_ty)); - self.put_temp_rvalue(Rvalue::Cast( - CastKind::PointerCoercion(PointerCoercion::Unsize, CoercionSource::Implicit), - Operand::Copy(Self::SELF_PTR.into()), - slice_ptr_ty, - )) - } - - /// If given Self is a struct puts `to_drop: *mut FieldTy` on top - /// of the stack. - fn put_field(&mut self, field: FieldIdx, field_ty: Ty<'tcx>) { - let place = Place { - local: Self::SELF_PTR, - projection: self - .tcx - .mk_place_elems(&[PlaceElem::Deref, PlaceElem::Field(field, field_ty)]), - }; - self.put_temp_rvalue(Rvalue::RawPtr(RawPtrKind::Mut, place)) - } - - /// If given Self is an enum puts `to_drop: *mut FieldTy` on top of - /// the stack. - fn put_variant_field( - &mut self, - variant_sym: Symbol, - variant: VariantIdx, - field: FieldIdx, - field_ty: Ty<'tcx>, - ) { - let place = Place { - local: Self::SELF_PTR, - projection: self.tcx.mk_place_elems(&[ - PlaceElem::Deref, - PlaceElem::Downcast(Some(variant_sym), variant), - PlaceElem::Field(field, field_ty), - ]), - }; - self.put_temp_rvalue(Rvalue::RawPtr(RawPtrKind::Mut, place)) - } - - /// If given Self is an enum puts `to_drop: *mut FieldTy` on top of - /// the stack. - fn put_discr(&mut self, discr: Discr<'tcx>) { - let (size, _) = discr.ty.int_size_and_signed(self.tcx); - self.put_operand(Operand::const_from_scalar( - self.tcx, - discr.ty, - interpret::Scalar::from_uint(discr.val, size), - self.span, - )); - } - - /// Puts `x: RvalueType` on top of the stack. - fn put_temp_rvalue(&mut self, rvalue: Rvalue<'tcx>) { - let last_bb = &mut self.bbs[self.last_bb]; - debug_assert!(last_bb.terminator.is_none()); - let source_info = self.source_info; - - let local_ty = rvalue.ty(&self.locals, self.tcx); - // We need to create a new local to be able to "consume" it with - // a combinator - let local = self.locals.push(LocalDecl::with_source_info(local_ty, source_info)); - last_bb.statements.extend_from_slice(&[ - Statement { source_info, kind: StatementKind::StorageLive(local) }, + let mut idx: usize = 0; + // _proxy = _1.0 : Pin<&ProxyLayout> ==> &ProxyLayout + let proxy_ref_place = Place::from(pin_proxy_layout_local) + .project_deeper(&[PlaceElem::Field(FieldIdx::ZERO, proxy_ref)], tcx); + body.basic_blocks_mut()[START_BLOCK].statements.insert( + idx, Statement { source_info, - kind: StatementKind::Assign(Box::new((local.into(), rvalue))), + kind: StatementKind::Assign(Box::new(( + Place::from(proxy_ref_local), + Rvalue::CopyForDeref(proxy_ref_place), + ))), }, - ]); - - self.put_operand(Operand::Move(local.into())); - } - - /// Puts operand on top of the stack. - fn put_operand(&mut self, operand: Operand<'tcx>) { - if let Some(top_cleanup_bb) = &mut self.top_cleanup_bb { - let source_info = self.source_info; - match &operand { - Operand::Copy(_) | Operand::Constant(_) => { - *top_cleanup_bb = self.bbs.push(BasicBlockData { - statements: Vec::new(), - terminator: Some(Terminator { - source_info, - kind: TerminatorKind::Goto { target: *top_cleanup_bb }, - }), - is_cleanup: true, - }); - } - Operand::Move(place) => { - let local = place.as_local().unwrap(); - *top_cleanup_bb = self.bbs.push(BasicBlockData { - statements: Vec::new(), - terminator: Some(Terminator { - source_info, - kind: if self.locals[local].ty.needs_drop(self.tcx, self.typing_env) { - TerminatorKind::Drop { - place: local.into(), - target: *top_cleanup_bb, - unwind: UnwindAction::Terminate( - UnwindTerminateReason::InCleanup, - ), - replace: false, - } - } else { - TerminatorKind::Goto { target: *top_cleanup_bb } - }, - }), - is_cleanup: true, - }); - } - }; - } - self.stack.push(operand); - } - - /// Puts `noop: async_drop::Noop` on top of the stack - fn put_noop(&mut self) -> Ty<'tcx> { - self.apply_combinator(0, LangItem::AsyncDropNoop, &[]) - } - - fn combine_async_surface(&mut self) -> Ty<'tcx> { - self.apply_combinator(1, LangItem::SurfaceAsyncDropInPlace, &[self.self_ty.unwrap().into()]) - } - - fn combine_sync_surface(&mut self) -> Ty<'tcx> { - self.apply_combinator( - 1, - LangItem::AsyncDropSurfaceDropInPlace, - &[self.self_ty.unwrap().into()], - ) - } - - fn combine_deferred_drop_in_place(&mut self) -> Ty<'tcx> { - self.apply_combinator( - 1, - LangItem::AsyncDropDeferredDropInPlace, - &[self.self_ty.unwrap().into()], - ) - } - - fn combine_fuse(&mut self, inner_future_ty: Ty<'tcx>) -> Ty<'tcx> { - self.apply_combinator(1, LangItem::AsyncDropFuse, &[inner_future_ty.into()]) - } - - fn combine_slice(&mut self, elem_ty: Ty<'tcx>) -> Ty<'tcx> { - self.apply_combinator(1, LangItem::AsyncDropSlice, &[elem_ty.into()]) - } - - fn combine_defer(&mut self, to_drop_ty: Ty<'tcx>) -> Ty<'tcx> { - self.apply_combinator(1, LangItem::AsyncDropDefer, &[to_drop_ty.into()]) - } - - fn combine_chain(&mut self, first: Ty<'tcx>, second: Ty<'tcx>) -> Ty<'tcx> { - self.apply_combinator(2, LangItem::AsyncDropChain, &[first.into(), second.into()]) - } - - fn combine_either(&mut self, other: Ty<'tcx>, matched: Ty<'tcx>) -> Ty<'tcx> { - self.apply_combinator( - 4, - LangItem::AsyncDropEither, - &[other.into(), matched.into(), self.self_ty.unwrap().into()], - ) - } - - fn return_(mut self) -> Body<'tcx> { - let last_bb = &mut self.bbs[self.last_bb]; - debug_assert!(last_bb.terminator.is_none()); - let source_info = self.source_info; - - let (1, Some(output)) = (self.stack.len(), self.stack.pop()) else { - span_bug!( - self.span, - "async destructor ctor shim builder finished with invalid number of stack items: expected 1 found {}", - self.stack.len(), - ) - }; - #[cfg(debug_assertions)] - if let Some(ty) = self.self_ty { - debug_assert_eq!( - output.ty(&self.locals, self.tcx), - ty.async_destructor_ty(self.tcx), - "output async destructor types did not match for type: {ty:?}", - ); - } - - let dead_storage = match &output { - Operand::Move(place) => Some(Statement { - source_info, - kind: StatementKind::StorageDead(place.as_local().unwrap()), - }), - _ => None, - }; - - last_bb.statements.extend( - iter::once(Statement { - source_info, - kind: StatementKind::Assign(Box::new((RETURN_PLACE.into(), Rvalue::Use(output)))), - }) - .chain(dead_storage), ); - - last_bb.terminator = Some(Terminator { source_info, kind: TerminatorKind::Return }); - - let source = MirSource::from_instance(ty::InstanceKind::AsyncDropGlueCtorShim( - self.def_id, - self.self_ty, - )); - new_body(source, self.bbs, self.locals, Self::INPUT_COUNT, self.span) - } - - fn apply_combinator( - &mut self, - arity: usize, - function: LangItem, - args: &[ty::GenericArg<'tcx>], - ) -> Ty<'tcx> { - let function = self.tcx.require_lang_item(function, Some(self.span)); - let operands_split = self - .stack - .len() - .checked_sub(arity) - .expect("async destructor ctor shim combinator tried to consume too many items"); - let operands = &self.stack[operands_split..]; - - let func_ty = Ty::new_fn_def(self.tcx, function, args.iter().copied()); - let func_sig = func_ty.fn_sig(self.tcx).no_bound_vars().unwrap(); - #[cfg(debug_assertions)] - operands.iter().zip(func_sig.inputs()).for_each(|(operand, expected_ty)| { - let operand_ty = operand.ty(&self.locals, self.tcx); - if operand_ty == *expected_ty { - return; - } - - // If projection of Discriminant then compare with `Ty::discriminant_ty` - if let ty::Alias(ty::Projection, ty::AliasTy { args, def_id, .. }) = expected_ty.kind() - && self.tcx.is_lang_item(*def_id, LangItem::Discriminant) - && args.first().unwrap().as_type().unwrap().discriminant_ty(self.tcx) == operand_ty - { - return; + idx += 1; + let mut cor_ptr_local = proxy_ref_local; + proxy_ty.find_async_drop_impl_coroutine(tcx, |ty| { + if ty != proxy_ty { + let ty_ptr = Ty::new_mut_ptr(tcx, ty); + let impl_ptr_place = Place::from(cor_ptr_local).project_deeper( + &[PlaceElem::Deref, PlaceElem::Field(FieldIdx::ZERO, ty_ptr)], + tcx, + ); + cor_ptr_local = body.local_decls.push(LocalDecl::new(ty_ptr, span)); + // _cor_ptr = _proxy.0.0 (... .0) + body.basic_blocks_mut()[START_BLOCK].statements.insert( + idx, + Statement { + source_info, + kind: StatementKind::Assign(Box::new(( + Place::from(cor_ptr_local), + Rvalue::CopyForDeref(impl_ptr_place), + ))), + }, + ); + idx += 1; } - - span_bug!( - self.span, - "Operand type and combinator argument type are not equal. - operand_ty: {:?} - argument_ty: {:?} -", - operand_ty, - expected_ty - ); - }); - - let target = self.bbs.push(BasicBlockData { - statements: operands - .iter() - .rev() - .filter_map(|o| { - if let Operand::Move(Place { local, projection }) = o { - assert!(projection.is_empty()); - Some(Statement { - source_info: self.source_info, - kind: StatementKind::StorageDead(*local), - }) - } else { - None - } - }) - .collect(), - terminator: None, - is_cleanup: false, }); - let dest_ty = func_sig.output(); - let dest = - self.locals.push(LocalDecl::with_source_info(dest_ty, self.source_info).immutable()); - - let unwind = if let Some(top_cleanup_bb) = &mut self.top_cleanup_bb { - for _ in 0..arity { - *top_cleanup_bb = - self.bbs[*top_cleanup_bb].terminator().successors().exactly_one().ok().unwrap(); - } - UnwindAction::Cleanup(*top_cleanup_bb) - } else { - UnwindAction::Unreachable - }; + // _cor_ref = &*cor_ptr + let reborrow = Rvalue::Ref( + tcx.lifetimes.re_erased, + BorrowKind::Mut { kind: MutBorrowKind::Default }, + tcx.mk_place_deref(Place::from(cor_ptr_local)), + ); + body.basic_blocks_mut()[START_BLOCK].statements.insert( + idx, + Statement { + source_info, + kind: StatementKind::Assign(Box::new((Place::from(cor_ref_local), reborrow))), + }, + ); + } + body +} - let last_bb = &mut self.bbs[self.last_bb]; - debug_assert!(last_bb.terminator.is_none()); - last_bb.statements.push(Statement { - source_info: self.source_info, - kind: StatementKind::StorageLive(dest), - }); - last_bb.terminator = Some(Terminator { - source_info: self.source_info, +// When dropping async drop coroutine, we continue its execution. +// async_drop(async_drop(T))::future_drop_poll() => async_drop(T)::poll() +fn build_adrop_for_adrop_shim<'tcx>( + tcx: TyCtxt<'tcx>, + proxy_ty: Ty<'tcx>, + impl_ty: Ty<'tcx>, + span: Span, + instance: ty::InstanceKind<'tcx>, +) -> Body<'tcx> { + let source_info = SourceInfo::outermost(span); + let proxy_ref = Ty::new_mut_ref(tcx, tcx.lifetimes.re_erased, proxy_ty); + // taking _1.0 (impl from Pin) + let pin_proxy_layout_local = Local::new(1); + let proxy_ref_place = Place::from(pin_proxy_layout_local) + .project_deeper(&[PlaceElem::Field(FieldIdx::ZERO, proxy_ref)], tcx); + let cor_ref = Ty::new_mut_ref(tcx, tcx.lifetimes.re_erased, impl_ty); + + // ret_ty = `Poll<()>` + let poll_adt_ref = tcx.adt_def(tcx.require_lang_item(LangItem::Poll, None)); + let ret_ty = Ty::new_adt(tcx, poll_adt_ref, tcx.mk_args(&[tcx.types.unit.into()])); + // env_ty = `Pin<&mut proxy_ty>` + let pin_adt_ref = tcx.adt_def(tcx.require_lang_item(LangItem::Pin, None)); + let env_ty = Ty::new_adt(tcx, pin_adt_ref, tcx.mk_args(&[proxy_ref.into()])); + // sig = `fn (Pin<&mut proxy_ty>, &mut Context) -> Poll<()>` + let sig = tcx.mk_fn_sig( + [env_ty, Ty::new_task_context(tcx)], + ret_ty, + false, + hir::Safety::Safe, + ExternAbi::Rust, + ); + // This function will be called with pinned proxy coroutine layout. + // We need to extract `Arg0.0` to get proxy layout, and then get `.0` + // further to receive impl coroutine (may be needed) + let mut locals = local_decls_for_sig(&sig, span); + let mut blocks = IndexVec::with_capacity(3); + + let proxy_ref_local = locals.push(LocalDecl::new(proxy_ref, span)); + + let call_bb = BasicBlock::new(1); + let return_bb = BasicBlock::new(2); + + let mut statements = Vec::new(); + + statements.push(Statement { + source_info, + kind: StatementKind::Assign(Box::new(( + Place::from(proxy_ref_local), + Rvalue::CopyForDeref(proxy_ref_place), + ))), + }); + + let mut cor_ptr_local = proxy_ref_local; + proxy_ty.find_async_drop_impl_coroutine(tcx, |ty| { + if ty != proxy_ty { + let ty_ptr = Ty::new_mut_ptr(tcx, ty); + let impl_ptr_place = Place::from(cor_ptr_local) + .project_deeper(&[PlaceElem::Deref, PlaceElem::Field(FieldIdx::ZERO, ty_ptr)], tcx); + cor_ptr_local = locals.push(LocalDecl::new(ty_ptr, span)); + // _cor_ptr = _proxy.0.0 (... .0) + statements.push(Statement { + source_info, + kind: StatementKind::Assign(Box::new(( + Place::from(cor_ptr_local), + Rvalue::CopyForDeref(impl_ptr_place), + ))), + }); + } + }); + + // convert impl coroutine ptr into ref + let reborrow = Rvalue::Ref( + tcx.lifetimes.re_erased, + BorrowKind::Mut { kind: MutBorrowKind::Default }, + tcx.mk_place_deref(Place::from(cor_ptr_local)), + ); + let cor_ref_place = Place::from(locals.push(LocalDecl::new(cor_ref, span))); + statements.push(Statement { + source_info, + kind: StatementKind::Assign(Box::new((cor_ref_place, reborrow))), + }); + + // cor_pin_ty = `Pin<&mut cor_ref>` + let cor_pin_ty = Ty::new_adt(tcx, pin_adt_ref, tcx.mk_args(&[cor_ref.into()])); + let cor_pin_place = Place::from(locals.push(LocalDecl::new(cor_pin_ty, span))); + + let pin_fn = tcx.require_lang_item(LangItem::PinNewUnchecked, Some(span)); + // call Pin::new_unchecked(&mut impl_cor) + blocks.push(BasicBlockData { + statements, + terminator: Some(Terminator { + source_info, kind: TerminatorKind::Call { - func: Operand::Constant(Box::new(ConstOperand { - span: self.span, - user_ty: None, - const_: Const::Val(ConstValue::ZeroSized, func_ty), - })), - destination: dest.into(), - target: Some(target), - unwind, + func: Operand::function_handle(tcx, pin_fn, [cor_ref.into()], span), + args: [dummy_spanned(Operand::Move(cor_ref_place))].into(), + destination: cor_pin_place, + target: Some(call_bb), + unwind: UnwindAction::Continue, call_source: CallSource::Misc, - fn_span: self.span, - args: self.stack.drain(operands_split..).map(|o| respan(self.span, o)).collect(), + fn_span: span, }, - }); - - self.put_operand(Operand::Move(dest.into())); - self.last_bb = target; - - dest_ty - } + }), + is_cleanup: false, + }); + // When dropping async drop coroutine, we continue its execution: + // we call impl::poll (impl_layout, ctx) + let poll_fn = tcx.require_lang_item(LangItem::FuturePoll, None); + let resume_ctx = Place::from(Local::new(2)); + blocks.push(BasicBlockData { + statements: vec![], + terminator: Some(Terminator { + source_info, + kind: TerminatorKind::Call { + func: Operand::function_handle(tcx, poll_fn, [impl_ty.into()], span), + args: [ + dummy_spanned(Operand::Move(cor_pin_place)), + dummy_spanned(Operand::Move(resume_ctx)), + ] + .into(), + destination: Place::return_place(), + target: Some(return_bb), + unwind: UnwindAction::Continue, + call_source: CallSource::Misc, + fn_span: span, + }, + }), + is_cleanup: false, + }); + blocks.push(BasicBlockData { + statements: vec![], + terminator: Some(Terminator { source_info, kind: TerminatorKind::Return }), + is_cleanup: false, + }); + + let source = MirSource::from_instance(instance); + let mut body = new_body(source, blocks, locals, sig.inputs().len(), span); + body.phase = MirPhase::Runtime(RuntimePhase::Initial); + return body; } diff --git a/compiler/rustc_mir_transform/src/validate.rs b/compiler/rustc_mir_transform/src/validate.rs index 66fe3ef4141..f541a32cd26 100644 --- a/compiler/rustc_mir_transform/src/validate.rs +++ b/compiler/rustc_mir_transform/src/validate.rs @@ -372,9 +372,12 @@ impl<'a, 'tcx> Visitor<'tcx> for CfgChecker<'a, 'tcx> { ); } } - TerminatorKind::Drop { target, unwind, .. } => { + TerminatorKind::Drop { target, unwind, drop, .. } => { self.check_edge(location, *target, EdgeKind::Normal); self.check_unwind_edge(location, *unwind); + if let Some(drop) = drop { + self.check_edge(location, *drop, EdgeKind::Normal); + } } TerminatorKind::Call { func, args, .. } | TerminatorKind::TailCall { func, args, .. } => { @@ -747,7 +750,9 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { // since we may be in the process of computing this MIR in the // first place. let layout = if def_id == self.caller_body.source.def_id() { - self.caller_body.coroutine_layout_raw() + self.caller_body + .coroutine_layout_raw() + .or_else(|| self.tcx.coroutine_layout(def_id, args)) } else if self.tcx.needs_coroutine_by_move_body_def_id(def_id) && let ty::ClosureKind::FnOnce = args.as_coroutine().kind_ty().to_opt_closure_kind().unwrap() @@ -757,7 +762,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { // Same if this is the by-move body of a coroutine-closure. self.caller_body.coroutine_layout_raw() } else { - self.tcx.coroutine_layout(def_id, args.as_coroutine().kind_ty()) + self.tcx.coroutine_layout(def_id, args) }; let Some(layout) = layout else { diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index d1d0f7cacae..76dad6b3571 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -929,14 +929,16 @@ fn visit_instance_use<'tcx>( ty::InstanceKind::ThreadLocalShim(..) => { bug!("{:?} being reified", instance); } - ty::InstanceKind::DropGlue(_, None) | ty::InstanceKind::AsyncDropGlueCtorShim(_, None) => { + ty::InstanceKind::DropGlue(_, None) => { // Don't need to emit noop drop glue if we are calling directly. if !is_direct_call { output.push(create_fn_mono_item(tcx, instance, source)); } } ty::InstanceKind::DropGlue(_, Some(_)) - | ty::InstanceKind::AsyncDropGlueCtorShim(_, Some(_)) + | ty::InstanceKind::FutureDropPollShim(..) + | ty::InstanceKind::AsyncDropGlue(_, _) + | ty::InstanceKind::AsyncDropGlueCtorShim(_, _) | ty::InstanceKind::VTableShim(..) | ty::InstanceKind::ReifyShim(..) | ty::InstanceKind::ClosureOnceShim { .. } diff --git a/compiler/rustc_monomorphize/src/partitioning.rs b/compiler/rustc_monomorphize/src/partitioning.rs index 6bc8a0fc88c..6948dceddf9 100644 --- a/compiler/rustc_monomorphize/src/partitioning.rs +++ b/compiler/rustc_monomorphize/src/partitioning.rs @@ -644,6 +644,8 @@ fn characteristic_def_id_of_mono_item<'tcx>( | ty::InstanceKind::CloneShim(..) | ty::InstanceKind::ThreadLocalShim(..) | ty::InstanceKind::FnPtrAddrShim(..) + | ty::InstanceKind::FutureDropPollShim(..) + | ty::InstanceKind::AsyncDropGlue(..) | ty::InstanceKind::AsyncDropGlueCtorShim(..) => return None, }; @@ -796,7 +798,9 @@ fn mono_item_visibility<'tcx>( let def_id = match instance.def { InstanceKind::Item(def_id) | InstanceKind::DropGlue(def_id, Some(_)) - | InstanceKind::AsyncDropGlueCtorShim(def_id, Some(_)) => def_id, + | InstanceKind::FutureDropPollShim(def_id, _, _) + | InstanceKind::AsyncDropGlue(def_id, _) + | InstanceKind::AsyncDropGlueCtorShim(def_id, _) => def_id, // We match the visibility of statics here InstanceKind::ThreadLocalShim(def_id) => { @@ -812,7 +816,6 @@ fn mono_item_visibility<'tcx>( | InstanceKind::ClosureOnceShim { .. } | InstanceKind::ConstructCoroutineInClosureShim { .. } | InstanceKind::DropGlue(..) - | InstanceKind::AsyncDropGlueCtorShim(..) | InstanceKind::CloneShim(..) | InstanceKind::FnPtrAddrShim(..) => return Visibility::Hidden, }; diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs index 381a732b8de..224c44e60fd 100644 --- a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs @@ -256,11 +256,6 @@ where goal: Goal, ) -> Result, NoSolution>; - fn consider_builtin_async_destruct_candidate( - ecx: &mut EvalCtxt<'_, D>, - goal: Goal, - ) -> Result, NoSolution>; - fn consider_builtin_destruct_candidate( ecx: &mut EvalCtxt<'_, D>, goal: Goal, @@ -477,9 +472,6 @@ where Some(TraitSolverLangItem::DiscriminantKind) => { G::consider_builtin_discriminant_kind_candidate(self, goal) } - Some(TraitSolverLangItem::AsyncDestruct) => { - G::consider_builtin_async_destruct_candidate(self, goal) - } Some(TraitSolverLangItem::Destruct) => { G::consider_builtin_destruct_candidate(self, goal) } diff --git a/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs b/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs index 7752a705cd1..5edc777262b 100644 --- a/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs +++ b/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs @@ -336,13 +336,6 @@ where unreachable!("DiscriminantKind is not const") } - fn consider_builtin_async_destruct_candidate( - _ecx: &mut EvalCtxt<'_, D>, - _goal: Goal, - ) -> Result, NoSolution> { - unreachable!("AsyncDestruct is not const") - } - fn consider_builtin_destruct_candidate( ecx: &mut EvalCtxt<'_, D>, goal: Goal, diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs index 119d197de13..1625da81b85 100644 --- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs @@ -887,66 +887,6 @@ where }) } - fn consider_builtin_async_destruct_candidate( - ecx: &mut EvalCtxt<'_, D>, - goal: Goal, - ) -> Result, NoSolution> { - let self_ty = goal.predicate.self_ty(); - let async_destructor_ty = match self_ty.kind() { - ty::Bool - | ty::Char - | ty::Int(..) - | ty::Uint(..) - | ty::Float(..) - | ty::Array(..) - | ty::RawPtr(..) - | ty::Ref(..) - | ty::FnDef(..) - | ty::FnPtr(..) - | ty::Closure(..) - | ty::CoroutineClosure(..) - | ty::Infer(ty::IntVar(..) | ty::FloatVar(..)) - | ty::Never - | ty::Adt(_, _) - | ty::Str - | ty::Slice(_) - | ty::Tuple(_) - | ty::Error(_) => self_ty.async_destructor_ty(ecx.cx()), - - ty::UnsafeBinder(_) => { - // FIXME(unsafe_binders): Instantiate the binder with placeholders I guess. - todo!() - } - - // Given an alias, parameter, or placeholder we add an impl candidate normalizing to a rigid - // alias. In case there's a where-bound further constraining this alias it is preferred over - // this impl candidate anyways. It's still a bit scuffed. - ty::Alias(_, _) | ty::Param(_) | ty::Placeholder(..) => { - return ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| { - ecx.structurally_instantiate_normalizes_to_term(goal, goal.predicate.alias); - ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) - }); - } - - ty::Infer(ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) - | ty::Foreign(..) - | ty::Bound(..) => panic!( - "unexpected self ty `{:?}` when normalizing `::AsyncDestructor`", - goal.predicate.self_ty() - ), - - ty::Pat(..) | ty::Dynamic(..) | ty::Coroutine(..) | ty::CoroutineWitness(..) => panic!( - "`consider_builtin_async_destruct_candidate` is not yet implemented for type: {self_ty:?}" - ), - }; - - ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| { - ecx.eq(goal.param_env, goal.predicate.term, async_destructor_ty.into()) - .expect("expected goal term to be fully unconstrained"); - ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) - }) - } - fn consider_builtin_destruct_candidate( _ecx: &mut EvalCtxt<'_, D>, goal: Goal, diff --git a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs index 24657496df6..94e181ae8d8 100644 --- a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs +++ b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs @@ -599,19 +599,6 @@ where .enter(|ecx| ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)) } - fn consider_builtin_async_destruct_candidate( - ecx: &mut EvalCtxt<'_, D>, - goal: Goal, - ) -> Result, NoSolution> { - if goal.predicate.polarity != ty::PredicatePolarity::Positive { - return Err(NoSolution); - } - - // `AsyncDestruct` is automatically implemented for every type. - ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc) - .enter(|ecx| ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)) - } - fn consider_builtin_destruct_candidate( ecx: &mut EvalCtxt<'_, D>, goal: Goal, diff --git a/compiler/rustc_passes/src/lib.rs b/compiler/rustc_passes/src/lib.rs index c7bb00df796..424bce9d4d4 100644 --- a/compiler/rustc_passes/src/lib.rs +++ b/compiler/rustc_passes/src/lib.rs @@ -9,6 +9,7 @@ #![cfg_attr(bootstrap, feature(let_chains))] #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![doc(rust_logo)] +#![feature(box_patterns)] #![feature(map_try_insert)] #![feature(rustdoc_internals)] #![feature(try_blocks)] diff --git a/compiler/rustc_smir/src/rustc_smir/context.rs b/compiler/rustc_smir/src/rustc_smir/context.rs index 9a4cac243bd..bac5c9066f1 100644 --- a/compiler/rustc_smir/src/rustc_smir/context.rs +++ b/compiler/rustc_smir/src/rustc_smir/context.rs @@ -695,13 +695,6 @@ impl<'tcx> SmirCtxt<'tcx> { matches!(instance.def, ty::InstanceKind::DropGlue(_, None)) } - /// Check if this is an empty AsyncDropGlueCtor shim. - pub fn is_empty_async_drop_ctor_shim(&self, def: InstanceDef) -> bool { - let tables = self.0.borrow_mut(); - let instance = tables.instances[def]; - matches!(instance.def, ty::InstanceKind::AsyncDropGlueCtorShim(_, None)) - } - /// Convert a non-generic crate item into an instance. /// This function will panic if the item is generic. pub fn mono_instance(&self, def_id: stable_mir::DefId) -> stable_mir::mir::mono::Instance { diff --git a/compiler/rustc_smir/src/rustc_smir/convert/mir.rs b/compiler/rustc_smir/src/rustc_smir/convert/mir.rs index 61b769bce08..42b3e59b73a 100644 --- a/compiler/rustc_smir/src/rustc_smir/convert/mir.rs +++ b/compiler/rustc_smir/src/rustc_smir/convert/mir.rs @@ -494,6 +494,9 @@ impl<'tcx> Stable<'tcx> for mir::AssertMessage<'tcx> { AssertKind::ResumedAfterPanic(coroutine) => { stable_mir::mir::AssertMessage::ResumedAfterPanic(coroutine.stable(tables)) } + AssertKind::ResumedAfterDrop(coroutine) => { + stable_mir::mir::AssertMessage::ResumedAfterDrop(coroutine.stable(tables)) + } AssertKind::MisalignedPointerDereference { required, found } => { stable_mir::mir::AssertMessage::MisalignedPointerDereference { required: required.stable(tables), @@ -648,13 +651,18 @@ impl<'tcx> Stable<'tcx> for mir::TerminatorKind<'tcx> { mir::TerminatorKind::UnwindTerminate(_) => TerminatorKind::Abort, mir::TerminatorKind::Return => TerminatorKind::Return, mir::TerminatorKind::Unreachable => TerminatorKind::Unreachable, - mir::TerminatorKind::Drop { place, target, unwind, replace: _ } => { - TerminatorKind::Drop { - place: place.stable(tables), - target: target.as_usize(), - unwind: unwind.stable(tables), - } - } + mir::TerminatorKind::Drop { + place, + target, + unwind, + replace: _, + drop: _, + async_fut: _, + } => TerminatorKind::Drop { + place: place.stable(tables), + target: target.as_usize(), + unwind: unwind.stable(tables), + }, mir::TerminatorKind::Call { func, args, diff --git a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs index c0ed3b90eb4..5a4aa7fe278 100644 --- a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs +++ b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs @@ -813,6 +813,8 @@ impl<'tcx> Stable<'tcx> for ty::Instance<'tcx> { | ty::InstanceKind::DropGlue(..) | ty::InstanceKind::CloneShim(..) | ty::InstanceKind::FnPtrShim(..) + | ty::InstanceKind::FutureDropPollShim(..) + | ty::InstanceKind::AsyncDropGlue(..) | ty::InstanceKind::AsyncDropGlueCtorShim(..) => { stable_mir::mir::mono::InstanceKind::Shim } diff --git a/compiler/rustc_smir/src/stable_mir/compiler_interface.rs b/compiler/rustc_smir/src/stable_mir/compiler_interface.rs index cd61907dc6b..bb35e23a728 100644 --- a/compiler/rustc_smir/src/stable_mir/compiler_interface.rs +++ b/compiler/rustc_smir/src/stable_mir/compiler_interface.rs @@ -354,11 +354,6 @@ impl<'tcx> SmirInterface<'tcx> { self.cx.is_empty_drop_shim(def) } - /// Check if this is an empty AsyncDropGlueCtor shim. - pub(crate) fn is_empty_async_drop_ctor_shim(&self, def: InstanceDef) -> bool { - self.cx.is_empty_async_drop_ctor_shim(def) - } - /// Convert a non-generic crate item into an instance. /// This function will panic if the item is generic. pub(crate) fn mono_instance(&self, def_id: DefId) -> Instance { diff --git a/compiler/rustc_smir/src/stable_mir/mir/body.rs b/compiler/rustc_smir/src/stable_mir/mir/body.rs index b2360545424..660cd7db080 100644 --- a/compiler/rustc_smir/src/stable_mir/mir/body.rs +++ b/compiler/rustc_smir/src/stable_mir/mir/body.rs @@ -267,6 +267,7 @@ pub enum AssertMessage { RemainderByZero(Operand), ResumedAfterReturn(CoroutineKind), ResumedAfterPanic(CoroutineKind), + ResumedAfterDrop(CoroutineKind), MisalignedPointerDereference { required: Operand, found: Operand }, NullPointerDereference, } @@ -320,6 +321,22 @@ impl AssertMessage { _, )) => Ok("`gen fn` should just keep returning `AssertMessage::None` after panicking"), + AssertMessage::ResumedAfterDrop(CoroutineKind::Coroutine(_)) => { + Ok("coroutine resumed after async drop") + } + AssertMessage::ResumedAfterDrop(CoroutineKind::Desugared( + CoroutineDesugaring::Async, + _, + )) => Ok("`async fn` resumed after async drop"), + AssertMessage::ResumedAfterDrop(CoroutineKind::Desugared( + CoroutineDesugaring::Gen, + _, + )) => Ok("`async gen fn` resumed after async drop"), + AssertMessage::ResumedAfterDrop(CoroutineKind::Desugared( + CoroutineDesugaring::AsyncGen, + _, + )) => Ok("`gen fn` should just keep returning `AssertMessage::None` after async drop"), + AssertMessage::BoundsCheck { .. } => Ok("index out of bounds"), AssertMessage::MisalignedPointerDereference { .. } => { Ok("misaligned pointer dereference") diff --git a/compiler/rustc_smir/src/stable_mir/mir/mono.rs b/compiler/rustc_smir/src/stable_mir/mir/mono.rs index 0c3e4fb7c90..f5239cccae1 100644 --- a/compiler/rustc_smir/src/stable_mir/mir/mono.rs +++ b/compiler/rustc_smir/src/stable_mir/mir/mono.rs @@ -163,10 +163,7 @@ impl Instance { /// When generating code for a Drop terminator, users can ignore an empty drop glue. /// These shims are only needed to generate a valid Drop call done via VTable. pub fn is_empty_shim(&self) -> bool { - self.kind == InstanceKind::Shim - && with(|cx| { - cx.is_empty_drop_shim(self.def) || cx.is_empty_async_drop_ctor_shim(self.def) - }) + self.kind == InstanceKind::Shim && with(|cx| cx.is_empty_drop_shim(self.def)) } /// Try to constant evaluate the instance into a constant with the given type. diff --git a/compiler/rustc_smir/src/stable_mir/mir/pretty.rs b/compiler/rustc_smir/src/stable_mir/mir/pretty.rs index 8a6be0cd37a..ba20651f993 100644 --- a/compiler/rustc_smir/src/stable_mir/mir/pretty.rs +++ b/compiler/rustc_smir/src/stable_mir/mir/pretty.rs @@ -313,7 +313,9 @@ fn pretty_assert_message(writer: &mut W, msg: &AssertMessage) -> io::R AssertMessage::NullPointerDereference => { write!(writer, "\"null pointer dereference occurred\"") } - AssertMessage::ResumedAfterReturn(_) | AssertMessage::ResumedAfterPanic(_) => { + AssertMessage::ResumedAfterReturn(_) + | AssertMessage::ResumedAfterPanic(_) + | AssertMessage::ResumedAfterDrop(_) => { write!(writer, "{}", msg.description().unwrap()) } } diff --git a/compiler/rustc_smir/src/stable_mir/mir/visit.rs b/compiler/rustc_smir/src/stable_mir/mir/visit.rs index 786693ea98d..e21dc11eea9 100644 --- a/compiler/rustc_smir/src/stable_mir/mir/visit.rs +++ b/compiler/rustc_smir/src/stable_mir/mir/visit.rs @@ -372,7 +372,8 @@ macro_rules! make_mir_visitor { } AssertMessage::ResumedAfterReturn(_) | AssertMessage::ResumedAfterPanic(_) - | AssertMessage::NullPointerDereference => { + | AssertMessage::NullPointerDereference + | AssertMessage::ResumedAfterDrop(_) => { //nothing to visit } AssertMessage::MisalignedPointerDereference { required, found } => { diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 32a5aff0cb3..dcf3a31da50 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -502,17 +502,8 @@ symbols! { async_call_mut, async_call_once, async_closure, - async_destruct, async_drop, - async_drop_chain, - async_drop_defer, - async_drop_deferred_drop_in_place, - async_drop_either, - async_drop_fuse, async_drop_in_place, - async_drop_noop, - async_drop_slice, - async_drop_surface_drop_in_place, async_fn, async_fn_in_dyn_trait, async_fn_in_trait, @@ -983,7 +974,6 @@ symbols! { fadd_fast, fake_variadic, fallback, - fallback_surface_drop, fdiv_algebraic, fdiv_fast, feature, @@ -1064,6 +1054,7 @@ symbols! { fundamental, fused_iterator, future, + future_drop_poll, future_output, future_trait, gdb_script_file, @@ -1522,14 +1513,18 @@ symbols! { panic_cannot_unwind, panic_const_add_overflow, panic_const_async_fn_resumed, + panic_const_async_fn_resumed_drop, panic_const_async_fn_resumed_panic, panic_const_async_gen_fn_resumed, + panic_const_async_gen_fn_resumed_drop, panic_const_async_gen_fn_resumed_panic, panic_const_coroutine_resumed, + panic_const_coroutine_resumed_drop, panic_const_coroutine_resumed_panic, panic_const_div_by_zero, panic_const_div_overflow, panic_const_gen_fn_none, + panic_const_gen_fn_none_drop, panic_const_gen_fn_none_panic, panic_const_mul_overflow, panic_const_neg_overflow, @@ -2057,7 +2052,6 @@ symbols! { suggestion, super_let, supertrait_item_shadowing, - surface_async_drop_in_place, sym, sync, synthetic, diff --git a/compiler/rustc_symbol_mangling/src/legacy.rs b/compiler/rustc_symbol_mangling/src/legacy.rs index 2802e891807..db102abda7f 100644 --- a/compiler/rustc_symbol_mangling/src/legacy.rs +++ b/compiler/rustc_symbol_mangling/src/legacy.rs @@ -63,10 +63,17 @@ pub(super) fn mangle<'tcx>( .print_def_path( def_id, if let ty::InstanceKind::DropGlue(_, _) - | ty::InstanceKind::AsyncDropGlueCtorShim(_, _) = instance.def + | ty::InstanceKind::AsyncDropGlueCtorShim(_, _) + | ty::InstanceKind::FutureDropPollShim(_, _, _) = instance.def { // Add the name of the dropped type to the symbol name &*instance.args + } else if let ty::InstanceKind::AsyncDropGlue(_, ty) = instance.def { + let ty::Coroutine(_, cor_args) = ty.kind() else { + bug!(); + }; + let drop_ty = cor_args.first().unwrap().expect_ty(); + tcx.mk_args(&[GenericArg::from(drop_ty)]) } else { &[] }, @@ -99,6 +106,10 @@ pub(super) fn mangle<'tcx>( _ => {} } + if let ty::InstanceKind::FutureDropPollShim(..) = instance.def { + let _ = printer.write_str("{{drop-shim}}"); + } + printer.path.finish(hash) } diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs index f310aa65500..9f80f8443cb 100644 --- a/compiler/rustc_symbol_mangling/src/v0.rs +++ b/compiler/rustc_symbol_mangling/src/v0.rs @@ -58,11 +58,17 @@ pub(super) fn mangle<'tcx>( ty::InstanceKind::ConstructCoroutineInClosureShim { receiver_by_ref: false, .. } => { Some("by_ref") } - + ty::InstanceKind::FutureDropPollShim(_, _, _) => Some("drop"), _ => None, }; - if let Some(shim_kind) = shim_kind { + if let ty::InstanceKind::AsyncDropGlue(_, ty) = instance.def { + let ty::Coroutine(_, cor_args) = ty.kind() else { + bug!(); + }; + let drop_ty = cor_args.first().unwrap().expect_ty(); + cx.print_def_path(def_id, tcx.mk_args(&[GenericArg::from(drop_ty)])).unwrap() + } else if let Some(shim_kind) = shim_kind { cx.path_append_ns(|cx| cx.print_def_path(def_id, args), 'S', 0, shim_kind).unwrap() } else { cx.print_def_path(def_id, args).unwrap() diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index 99fa791b375..6087d793721 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -1034,42 +1034,6 @@ fn assemble_candidates_from_impls<'cx, 'tcx>( | ty::Infer(..) | ty::Error(_) => false, }, - Some(LangItem::AsyncDestruct) => match self_ty.kind() { - ty::Bool - | ty::Char - | ty::Int(_) - | ty::Uint(_) - | ty::Float(_) - | ty::Adt(..) - | ty::Str - | ty::Array(..) - | ty::Slice(_) - | ty::RawPtr(..) - | ty::Ref(..) - | ty::FnDef(..) - | ty::FnPtr(..) - | ty::UnsafeBinder(_) - | ty::Dynamic(..) - | ty::Closure(..) - | ty::CoroutineClosure(..) - | ty::Coroutine(..) - | ty::CoroutineWitness(..) - | ty::Pat(..) - | ty::Never - | ty::Tuple(..) - | ty::Infer(ty::InferTy::IntVar(_) | ty::InferTy::FloatVar(..)) => true, - - // type parameters, opaques, and unnormalized projections don't have - // a known async destructor and may need to be normalized further or rely - // on param env for async destructor projections - ty::Param(_) - | ty::Foreign(_) - | ty::Alias(..) - | ty::Bound(..) - | ty::Placeholder(..) - | ty::Infer(_) - | ty::Error(_) => false, - }, Some(LangItem::PointeeTrait) => { let tail = selcx.tcx().struct_tail_raw( self_ty, @@ -1528,11 +1492,6 @@ fn confirm_builtin_candidate<'cx, 'tcx>( assert_eq!(discriminant_def_id, item_def_id); (self_ty.discriminant_ty(tcx).into(), PredicateObligations::new()) - } else if tcx.is_lang_item(trait_def_id, LangItem::AsyncDestruct) { - let destructor_def_id = tcx.associated_item_def_ids(trait_def_id)[0]; - assert_eq!(destructor_def_id, item_def_id); - - (self_ty.async_destructor_ty(tcx).into(), PredicateObligations::new()) } else if tcx.is_lang_item(trait_def_id, LangItem::PointeeTrait) { let metadata_def_id = tcx.require_lang_item(LangItem::Metadata, None); assert_eq!(metadata_def_id, item_def_id); 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 00101010f14..95778242c72 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -79,9 +79,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } else if tcx.is_lang_item(def_id, LangItem::DiscriminantKind) { // `DiscriminantKind` is automatically implemented for every type. candidates.vec.push(BuiltinCandidate { has_nested: false }); - } else if tcx.is_lang_item(def_id, LangItem::AsyncDestruct) { - // `AsyncDestruct` is automatically implemented for every type. - candidates.vec.push(BuiltinCandidate { has_nested: false }); } else if tcx.is_lang_item(def_id, LangItem::PointeeTrait) { // `Pointee` is automatically implemented for every type. candidates.vec.push(BuiltinCandidate { has_nested: false }); diff --git a/compiler/rustc_ty_utils/src/abi.rs b/compiler/rustc_ty_utils/src/abi.rs index 63ea035bd0e..2b49d7ac8b5 100644 --- a/compiler/rustc_ty_utils/src/abi.rs +++ b/compiler/rustc_ty_utils/src/abi.rs @@ -551,8 +551,10 @@ fn fn_abi_new_uncached<'tcx>( extra_args }; - let is_drop_in_place = - determined_fn_def_id.is_some_and(|def_id| tcx.is_lang_item(def_id, LangItem::DropInPlace)); + let is_drop_in_place = determined_fn_def_id.is_some_and(|def_id| { + tcx.is_lang_item(def_id, LangItem::DropInPlace) + || tcx.is_lang_item(def_id, LangItem::AsyncDropInPlace) + }); let arg_of = |ty: Ty<'tcx>, arg_idx: Option| -> Result<_, &'tcx FnAbiError<'tcx>> { let span = tracing::debug_span!("arg_of"); diff --git a/compiler/rustc_ty_utils/src/common_traits.rs b/compiler/rustc_ty_utils/src/common_traits.rs index 20646cf9a82..bb2c4172b08 100644 --- a/compiler/rustc_ty_utils/src/common_traits.rs +++ b/compiler/rustc_ty_utils/src/common_traits.rs @@ -29,6 +29,13 @@ fn is_unpin_raw<'tcx>(tcx: TyCtxt<'tcx>, query: ty::PseudoCanonicalInput<'tcx, T is_item_raw(tcx, query, LangItem::Unpin) } +fn is_async_drop_raw<'tcx>( + tcx: TyCtxt<'tcx>, + query: ty::PseudoCanonicalInput<'tcx, Ty<'tcx>>, +) -> bool { + is_item_raw(tcx, query, LangItem::AsyncDrop) +} + fn is_item_raw<'tcx>( tcx: TyCtxt<'tcx>, query: ty::PseudoCanonicalInput<'tcx, Ty<'tcx>>, @@ -46,6 +53,7 @@ pub(crate) fn provide(providers: &mut Providers) { is_sized_raw, is_freeze_raw, is_unpin_raw, + is_async_drop_raw, ..*providers }; } diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs index 66c18bed5e7..da83566dad0 100644 --- a/compiler/rustc_ty_utils/src/instance.rs +++ b/compiler/rustc_ty_utils/src/instance.rs @@ -5,7 +5,6 @@ use rustc_infer::infer::TyCtxtInferExt; use rustc_middle::bug; use rustc_middle::query::Providers; use rustc_middle::traits::{BuiltinImplSource, CodegenObligationError}; -use rustc_middle::ty::util::AsyncDropGlueMorphology; use rustc_middle::ty::{ self, ClosureKind, GenericArgsRef, Instance, PseudoCanonicalInput, TyCtxt, TypeVisitableExt, }; @@ -41,20 +40,26 @@ fn resolve_instance_raw<'tcx>( if ty.needs_drop(tcx, typing_env) { debug!(" => nontrivial drop glue"); match *ty.kind() { + ty::Coroutine(coroutine_def_id, ..) => { + // FIXME: sync drop of coroutine with async drop (generate both versions?) + // Currently just ignored + if tcx.optimized_mir(coroutine_def_id).coroutine_drop_async().is_some() { + ty::InstanceKind::DropGlue(def_id, None) + } else { + ty::InstanceKind::DropGlue(def_id, Some(ty)) + } + } ty::Closure(..) | ty::CoroutineClosure(..) - | ty::Coroutine(..) | ty::Tuple(..) | ty::Adt(..) | ty::Dynamic(..) | ty::Array(..) | ty::Slice(..) - | ty::UnsafeBinder(..) => {} + | ty::UnsafeBinder(..) => ty::InstanceKind::DropGlue(def_id, Some(ty)), // Drop shims can only be built from ADTs. _ => return Ok(None), } - - ty::InstanceKind::DropGlue(def_id, Some(ty)) } else { debug!(" => trivial drop glue"); ty::InstanceKind::DropGlue(def_id, None) @@ -62,7 +67,7 @@ fn resolve_instance_raw<'tcx>( } else if tcx.is_lang_item(def_id, LangItem::AsyncDropInPlace) { let ty = args.type_at(0); - if ty.async_drop_glue_morphology(tcx) != AsyncDropGlueMorphology::Noop { + if ty.needs_async_drop(tcx, typing_env) { match *ty.kind() { ty::Closure(..) | ty::CoroutineClosure(..) @@ -76,11 +81,14 @@ fn resolve_instance_raw<'tcx>( _ => return Ok(None), } debug!(" => nontrivial async drop glue ctor"); - ty::InstanceKind::AsyncDropGlueCtorShim(def_id, Some(ty)) + ty::InstanceKind::AsyncDropGlueCtorShim(def_id, ty) } else { debug!(" => trivial async drop glue ctor"); - ty::InstanceKind::AsyncDropGlueCtorShim(def_id, None) + ty::InstanceKind::AsyncDropGlueCtorShim(def_id, ty) } + } else if tcx.is_async_drop_in_place_coroutine(def_id) { + let ty = args.type_at(0); + ty::InstanceKind::AsyncDropGlue(def_id, ty) } else { debug!(" => free item"); ty::InstanceKind::Item(def_id) diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs index 1915ba623cb..16336ed530a 100644 --- a/compiler/rustc_ty_utils/src/layout.rs +++ b/compiler/rustc_ty_utils/src/layout.rs @@ -184,6 +184,10 @@ fn layout_of_uncached<'tcx>( } let tcx = cx.tcx(); + + // layout of `async_drop_in_place::{closure}` in case, + // when T is a coroutine, contains this internal coroutine's ref + let dl = cx.data_layout(); let map_layout = |result: Result<_, _>| match result { Ok(layout) => Ok(tcx.mk_layout(layout)), @@ -406,7 +410,7 @@ fn layout_of_uncached<'tcx>( ty::Coroutine(def_id, args) => { use rustc_middle::ty::layout::PrimitiveExt as _; - let Some(info) = tcx.coroutine_layout(def_id, args.as_coroutine().kind_ty()) else { + let Some(info) = tcx.coroutine_layout(def_id, args) else { return Err(error(cx, LayoutError::Unknown(ty))); }; @@ -770,7 +774,7 @@ fn variant_info_for_coroutine<'tcx>( return (vec![], None); }; - let coroutine = cx.tcx().coroutine_layout(def_id, args.as_coroutine().kind_ty()).unwrap(); + let coroutine = cx.tcx().coroutine_layout(def_id, args).unwrap(); let upvar_names = cx.tcx().closure_saved_names_of_captured_variables(def_id); let mut upvars_size = Size::ZERO; diff --git a/compiler/rustc_ty_utils/src/needs_drop.rs b/compiler/rustc_ty_utils/src/needs_drop.rs index 52955ec59a4..c3b04c20f4b 100644 --- a/compiler/rustc_ty_utils/src/needs_drop.rs +++ b/compiler/rustc_ty_utils/src/needs_drop.rs @@ -42,11 +42,11 @@ fn needs_async_drop_raw<'tcx>( let adt_has_async_dtor = |adt_def: ty::AdtDef<'tcx>| adt_def.async_destructor(tcx).map(|_| DtorType::Significant); let res = drop_tys_helper(tcx, query.value, query.typing_env, adt_has_async_dtor, false, false) - .filter(filter_array_elements(tcx, query.typing_env)) + .filter(filter_array_elements_async(tcx, query.typing_env)) .next() .is_some(); - debug!("needs_drop_raw({:?}) = {:?}", query, res); + debug!("needs_async_drop_raw({:?}) = {:?}", query, res); res } @@ -66,6 +66,18 @@ fn filter_array_elements<'tcx>( Err(AlwaysRequiresDrop) => true, } } +fn filter_array_elements_async<'tcx>( + tcx: TyCtxt<'tcx>, + typing_env: ty::TypingEnv<'tcx>, +) -> impl Fn(&Result, AlwaysRequiresDrop>) -> bool { + move |ty| match ty { + Ok(ty) => match *ty.kind() { + ty::Array(elem, _) => tcx.needs_async_drop_raw(typing_env.as_query_input(elem)), + _ => true, + }, + Err(AlwaysRequiresDrop) => true, + } +} fn has_significant_drop_raw<'tcx>( tcx: TyCtxt<'tcx>, @@ -414,6 +426,27 @@ fn adt_drop_tys<'tcx>( .collect::, _>>() .map(|components| tcx.mk_type_list(&components)) } + +fn adt_async_drop_tys<'tcx>( + tcx: TyCtxt<'tcx>, + def_id: DefId, +) -> Result<&'tcx ty::List>, AlwaysRequiresDrop> { + // This is for the "adt_async_drop_tys" query, that considers all `AsyncDrop` impls. + let adt_has_dtor = + |adt_def: ty::AdtDef<'tcx>| adt_def.async_destructor(tcx).map(|_| DtorType::Significant); + // `tcx.type_of(def_id)` identical to `tcx.make_adt(def, identity_args)` + drop_tys_helper( + tcx, + tcx.type_of(def_id).instantiate_identity(), + ty::TypingEnv::non_body_analysis(tcx, def_id), + adt_has_dtor, + false, + false, + ) + .collect::, _>>() + .map(|components| tcx.mk_type_list(&components)) +} + // If `def_id` refers to a generic ADT, the queries above and below act as if they had been handed // a `tcx.make_ty(def, identity_args)` and as such it is legal to instantiate the generic parameters // of the ADT into the outputted `ty`s. @@ -458,6 +491,7 @@ pub(crate) fn provide(providers: &mut Providers) { needs_async_drop_raw, has_significant_drop_raw, adt_drop_tys, + adt_async_drop_tys, adt_significant_drop_tys, list_significant_drop_tys, ..*providers diff --git a/compiler/rustc_type_ir/src/inherent.rs b/compiler/rustc_type_ir/src/inherent.rs index 9b066b6869f..e6e6466766b 100644 --- a/compiler/rustc_type_ir/src/inherent.rs +++ b/compiler/rustc_type_ir/src/inherent.rs @@ -151,7 +151,6 @@ pub trait Ty>: fn discriminant_ty(self, interner: I) -> I::Ty; - fn async_destructor_ty(self, interner: I) -> I::Ty; fn is_known_rigid(self) -> bool { self.kind().is_known_rigid() } diff --git a/compiler/rustc_type_ir/src/lang_items.rs b/compiler/rustc_type_ir/src/lang_items.rs index 65f7cdf8f92..699dd82fb22 100644 --- a/compiler/rustc_type_ir/src/lang_items.rs +++ b/compiler/rustc_type_ir/src/lang_items.rs @@ -2,7 +2,6 @@ /// representation of `LangItem`s used in the underlying compiler implementation. pub enum TraitSolverLangItem { // tidy-alphabetical-start - AsyncDestruct, AsyncFn, AsyncFnKindHelper, AsyncFnKindUpvars, diff --git a/library/core/src/future/async_drop.rs b/library/core/src/future/async_drop.rs index f1778a4d782..fc4f95a98b4 100644 --- a/library/core/src/future/async_drop.rs +++ b/library/core/src/future/async_drop.rs @@ -1,284 +1,51 @@ #![unstable(feature = "async_drop", issue = "126482")] -use crate::fmt; -use crate::future::{Future, IntoFuture}; -use crate::intrinsics::discriminant_value; -use crate::marker::{DiscriminantKind, PhantomPinned}; -use crate::mem::MaybeUninit; -use crate::pin::Pin; -use crate::task::{Context, Poll, ready}; - -/// Asynchronously drops a value by running `AsyncDrop::async_drop` -/// on a value and its fields recursively. -#[unstable(feature = "async_drop", issue = "126482")] -pub fn async_drop(value: T) -> AsyncDropOwning { - AsyncDropOwning { value: MaybeUninit::new(value), dtor: None, _pinned: PhantomPinned } -} - -/// A future returned by the [`async_drop`]. -#[unstable(feature = "async_drop", issue = "126482")] -pub struct AsyncDropOwning { - value: MaybeUninit, - dtor: Option>, - _pinned: PhantomPinned, -} - -#[unstable(feature = "async_drop", issue = "126482")] -impl fmt::Debug for AsyncDropOwning { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("AsyncDropOwning").finish_non_exhaustive() - } -} - -#[unstable(feature = "async_drop", issue = "126482")] -impl Future for AsyncDropOwning { - type Output = (); - - fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { - // SAFETY: Self is pinned thus it is ok to store references to self - unsafe { - let this = self.get_unchecked_mut(); - let dtor = Pin::new_unchecked( - this.dtor.get_or_insert_with(|| async_drop_in_place(this.value.as_mut_ptr())), - ); - // AsyncDestuctors are idempotent so Self gets idempotency as well - dtor.poll(cx) - } - } -} +#[allow(unused_imports)] +use core::future::Future; -#[lang = "async_drop_in_place"] -#[allow(unconditional_recursion)] -// FIXME: Consider if `#[rustc_diagnostic_item = "ptr_drop_in_place"]` is needed? -unsafe fn async_drop_in_place_raw( - to_drop: *mut T, -) -> ::AsyncDestructor { - // Code here does not matter - this is replaced by the - // real async drop glue constructor by the compiler. - - // SAFETY: see comment above - unsafe { async_drop_in_place_raw(to_drop) } -} +#[allow(unused_imports)] +use crate::pin::Pin; +#[allow(unused_imports)] +use crate::task::{Context, Poll}; -/// Creates the asynchronous destructor of the pointed-to value. -/// -/// # Safety -/// -/// Behavior is undefined if any of the following conditions are violated: -/// -/// * `to_drop` must be [valid](crate::ptr#safety) for both reads and writes. -/// -/// * `to_drop` must be properly aligned, even if `T` has size 0. +/// Async version of Drop trait. /// -/// * `to_drop` must be nonnull, even if `T` has size 0. +/// When a value is no longer needed, Rust will run a "destructor" on that value. +/// The most common way that a value is no longer needed is when it goes out of +/// scope. Destructors may still run in other circumstances, but we're going to +/// focus on scope for the examples here. To learn about some of those other cases, +/// please see [the reference] section on destructors. /// -/// * The value `to_drop` points to must be valid for async dropping, -/// which may mean it must uphold additional invariants. These -/// invariants depend on the type of the value being dropped. For -/// instance, when dropping a Box, the box's pointer to the heap must -/// be valid. +/// [the reference]: https://doc.rust-lang.org/reference/destructors.html /// -/// * While `async_drop_in_place` is executing or the returned async -/// destructor is alive, the only way to access parts of `to_drop` -/// is through the `self: Pin<&mut Self>` references supplied to -/// the `AsyncDrop::async_drop` methods that `async_drop_in_place` -/// or `AsyncDropInPlace::poll` invokes. This usually means the -/// returned future stores the `to_drop` pointer and user is required -/// to guarantee that dropped value doesn't move. +/// ## `Copy` and ([`Drop`]|`AsyncDrop`) are exclusive /// -#[unstable(feature = "async_drop", issue = "126482")] -pub unsafe fn async_drop_in_place(to_drop: *mut T) -> AsyncDropInPlace { - // SAFETY: `async_drop_in_place_raw` has the same safety requirements - unsafe { AsyncDropInPlace(async_drop_in_place_raw(to_drop)) } -} - -/// A future returned by the [`async_drop_in_place`]. -#[unstable(feature = "async_drop", issue = "126482")] -pub struct AsyncDropInPlace(::AsyncDestructor); - -#[unstable(feature = "async_drop", issue = "126482")] -impl fmt::Debug for AsyncDropInPlace { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("AsyncDropInPlace").finish_non_exhaustive() - } -} - -#[unstable(feature = "async_drop", issue = "126482")] -impl Future for AsyncDropInPlace { - type Output = (); - - #[inline(always)] - fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { - // SAFETY: This code simply forwards poll call to the inner future - unsafe { Pin::new_unchecked(&mut self.get_unchecked_mut().0) }.poll(cx) - } -} - -// FIXME(zetanumbers): Add same restrictions on AsyncDrop impls as -// with Drop impls -/// Custom code within the asynchronous destructor. +/// You cannot implement both [`Copy`] and ([`Drop`]|`AsyncDrop`) on the same type. Types that +/// are `Copy` get implicitly duplicated by the compiler, making it very +/// hard to predict when, and how often destructors will be executed. As such, +/// these types cannot have destructors. +#[cfg(not(bootstrap))] #[unstable(feature = "async_drop", issue = "126482")] #[lang = "async_drop"] pub trait AsyncDrop { - /// A future returned by the [`AsyncDrop::async_drop`] to be part - /// of the async destructor. - #[unstable(feature = "async_drop", issue = "126482")] - type Dropper<'a>: Future - where - Self: 'a; - - /// Constructs the asynchronous destructor for this type. - #[unstable(feature = "async_drop", issue = "126482")] - fn async_drop(self: Pin<&mut Self>) -> Self::Dropper<'_>; -} - -#[lang = "async_destruct"] -#[rustc_deny_explicit_impl] -#[rustc_do_not_implement_via_object] -trait AsyncDestruct { - type AsyncDestructor: Future; -} - -/// Basically calls `AsyncDrop::async_drop` with pointer. Used to simplify -/// generation of the code for `async_drop_in_place_raw` -#[lang = "surface_async_drop_in_place"] -async unsafe fn surface_async_drop_in_place(ptr: *mut T) { - // SAFETY: We call this from async drop `async_drop_in_place_raw` - // which has the same safety requirements - unsafe { ::async_drop(Pin::new_unchecked(&mut *ptr)).await } -} - -/// Basically calls `Drop::drop` with pointer. Used to simplify generation -/// of the code for `async_drop_in_place_raw` -#[allow(drop_bounds)] -#[lang = "async_drop_surface_drop_in_place"] -async unsafe fn surface_drop_in_place(ptr: *mut T) { - // SAFETY: We call this from async drop `async_drop_in_place_raw` - // which has the same safety requirements - unsafe { crate::ops::fallback_surface_drop(&mut *ptr) } -} - -/// Wraps a future to continue outputting `Poll::Ready(())` once after -/// wrapped future completes by returning `Poll::Ready(())` on poll. This -/// is useful for constructing async destructors to guarantee this -/// "fuse" property -// -// FIXME: Consider optimizing combinators to not have to use fuse in majority -// of cases, perhaps by adding `#[(rustc_)idempotent(_future)]` attribute for -// async functions and blocks with the unit return type. However current layout -// optimizations currently encode `None` case into the async block's discriminant. -struct Fuse { - inner: Option, -} - -#[lang = "async_drop_fuse"] -fn fuse(inner: T) -> Fuse { - Fuse { inner: Some(inner) } -} - -impl Future for Fuse -where - T: Future, -{ - type Output = (); - - fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { - // SAFETY: pin projection into `self.inner` - unsafe { - let this = self.get_unchecked_mut(); - if let Some(inner) = &mut this.inner { - ready!(Pin::new_unchecked(inner).poll(cx)); - this.inner = None; - } - } - Poll::Ready(()) - } -} - -/// Async destructor for arrays and slices. -#[lang = "async_drop_slice"] -async unsafe fn slice(s: *mut [T]) { - let len = s.len(); - let ptr = s.as_mut_ptr(); - for i in 0..len { - // SAFETY: we iterate over elements of `s` slice - unsafe { async_drop_in_place_raw(ptr.add(i)).await } - } -} - -/// Constructs a chain of two futures, which awaits them sequentially as -/// a future. -#[lang = "async_drop_chain"] -async fn chain(first: F, last: G) -where - F: IntoFuture, - G: IntoFuture, -{ - first.await; - last.await; -} - -/// Basically a lazy version of `async_drop_in_place`. Returns a future -/// that would call `AsyncDrop::async_drop` on a first poll. -/// -/// # Safety -/// -/// Same as `async_drop_in_place` except is lazy to avoid creating -/// multiple mutable references. -#[lang = "async_drop_defer"] -async unsafe fn defer(to_drop: *mut T) { - // SAFETY: same safety requirements as `async_drop_in_place` - unsafe { async_drop_in_place(to_drop) }.await -} - -/// If `T`'s discriminant is equal to the stored one then awaits `M` -/// otherwise awaits the `O`. -/// -/// # Safety -/// -/// Users should carefully manage the returned future, since it would -/// try creating an immutable reference from `this` and get pointee's -/// discriminant. -// FIXME(zetanumbers): Send and Sync impls -#[lang = "async_drop_either"] -async unsafe fn either, M: IntoFuture, T>( - other: O, - matched: M, - this: *mut T, - discr: ::Discriminant, -) { - // SAFETY: Guaranteed by the safety section of this funtion's documentation - if unsafe { discriminant_value(&*this) } == discr { - drop(other); - matched.await - } else { - drop(matched); - other.await - } -} - -#[lang = "async_drop_deferred_drop_in_place"] -async unsafe fn deferred_drop_in_place(to_drop: *mut T) { - // SAFETY: same safety requirements as with drop_in_place (implied by - // function's name) - unsafe { crate::ptr::drop_in_place(to_drop) } -} - -/// Used for noop async destructors. We don't use [`core::future::Ready`] -/// because it panics after its second poll, which could be potentially -/// bad if that would happen during the cleanup. -#[derive(Clone, Copy)] -struct Noop; - -#[lang = "async_drop_noop"] -fn noop() -> Noop { - Noop -} - -impl Future for Noop { - type Output = (); - - fn poll(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll { - Poll::Ready(()) - } + /// Executes the async destructor for this type. + /// + /// This method is called implicitly when the value goes out of scope, + /// and cannot be called explicitly. + /// + /// When this method has been called, `self` has not yet been deallocated. + /// That only happens after the method is over. + /// + /// # Panics + #[allow(async_fn_in_trait)] + async fn drop(self: Pin<&mut Self>); +} + +/// Async drop. +#[cfg(not(bootstrap))] +#[unstable(feature = "async_drop", issue = "126482")] +#[lang = "async_drop_in_place"] +pub async unsafe fn async_drop_in_place(_to_drop: *mut T) { + // Code here does not matter - this is replaced by the + // real implementation by the compiler. } diff --git a/library/core/src/future/mod.rs b/library/core/src/future/mod.rs index 65c0171c88d..4b5a2f34d3f 100644 --- a/library/core/src/future/mod.rs +++ b/library/core/src/future/mod.rs @@ -20,8 +20,9 @@ mod pending; mod poll_fn; mod ready; +#[cfg(not(bootstrap))] #[unstable(feature = "async_drop", issue = "126482")] -pub use async_drop::{AsyncDrop, AsyncDropInPlace, async_drop, async_drop_in_place}; +pub use async_drop::{AsyncDrop, async_drop_in_place}; #[stable(feature = "into_future", since = "1.64.0")] pub use into_future::IntoFuture; #[stable(feature = "future_readiness_fns", since = "1.48.0")] diff --git a/library/core/src/ops/drop.rs b/library/core/src/ops/drop.rs index e024b7fb4d3..5d040804a8d 100644 --- a/library/core/src/ops/drop.rs +++ b/library/core/src/ops/drop.rs @@ -240,10 +240,3 @@ pub trait Drop { #[stable(feature = "rust1", since = "1.0.0")] fn drop(&mut self); } - -/// Fallback function to call surface level `Drop::drop` function -#[allow(drop_bounds)] -#[lang = "fallback_surface_drop"] -pub(crate) fn fallback_surface_drop(x: &mut T) { - ::drop(x) -} diff --git a/library/core/src/ops/mod.rs b/library/core/src/ops/mod.rs index 627a875d9f7..1658f0e5a36 100644 --- a/library/core/src/ops/mod.rs +++ b/library/core/src/ops/mod.rs @@ -176,7 +176,6 @@ pub use self::deref::Receiver; pub use self::deref::{Deref, DerefMut}; #[stable(feature = "rust1", since = "1.0.0")] pub use self::drop::Drop; -pub(crate) use self::drop::fallback_surface_drop; #[stable(feature = "rust1", since = "1.0.0")] pub use self::function::{Fn, FnMut, FnOnce}; #[stable(feature = "rust1", since = "1.0.0")] diff --git a/library/core/src/panicking.rs b/library/core/src/panicking.rs index 33ad59916e3..83a45436b30 100644 --- a/library/core/src/panicking.rs +++ b/library/core/src/panicking.rs @@ -155,30 +155,26 @@ pub const fn panic(expr: &'static str) -> ! { // reducing binary size impact. macro_rules! panic_const { ($($lang:ident = $message:expr,)+) => { - pub mod panic_const { - use super::*; - - $( - /// This is a panic called with a message that's a result of a MIR-produced Assert. - // - // never inline unless panic_immediate_abort to avoid code - // bloat at the call sites as much as possible - #[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)] - #[cfg_attr(feature = "panic_immediate_abort", inline)] - #[track_caller] - #[rustc_const_stable_indirect] // must follow stable const rules since it is exposed to stable - #[lang = stringify!($lang)] - pub const fn $lang() -> ! { - // Use Arguments::new_const instead of format_args!("{expr}") to potentially - // reduce size overhead. The format_args! macro uses str's Display trait to - // write expr, which calls Formatter::pad, which must accommodate string - // truncation and padding (even though none is used here). Using - // Arguments::new_const may allow the compiler to omit Formatter::pad from the - // output binary, saving up to a few kilobytes. - panic_fmt(fmt::Arguments::new_const(&[$message])); - } - )+ - } + $( + /// This is a panic called with a message that's a result of a MIR-produced Assert. + // + // never inline unless panic_immediate_abort to avoid code + // bloat at the call sites as much as possible + #[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)] + #[cfg_attr(feature = "panic_immediate_abort", inline)] + #[track_caller] + #[rustc_const_stable_indirect] // must follow stable const rules since it is exposed to stable + #[lang = stringify!($lang)] + pub const fn $lang() -> ! { + // Use Arguments::new_const instead of format_args!("{expr}") to potentially + // reduce size overhead. The format_args! macro uses str's Display trait to + // write expr, which calls Formatter::pad, which must accommodate string + // truncation and padding (even though none is used here). Using + // Arguments::new_const may allow the compiler to omit Formatter::pad from the + // output binary, saving up to a few kilobytes. + panic_fmt(fmt::Arguments::new_const(&[$message])); + } + )+ } } @@ -186,25 +182,37 @@ macro_rules! panic_const { // slightly different forms. It's not clear if there's a good way to deduplicate without adding // special cases to the compiler (e.g., a const generic function wouldn't have a single definition // shared across crates, which is exactly what we want here). -panic_const! { - panic_const_add_overflow = "attempt to add with overflow", - panic_const_sub_overflow = "attempt to subtract with overflow", - panic_const_mul_overflow = "attempt to multiply with overflow", - panic_const_div_overflow = "attempt to divide with overflow", - panic_const_rem_overflow = "attempt to calculate the remainder with overflow", - panic_const_neg_overflow = "attempt to negate with overflow", - panic_const_shr_overflow = "attempt to shift right with overflow", - panic_const_shl_overflow = "attempt to shift left with overflow", - panic_const_div_by_zero = "attempt to divide by zero", - panic_const_rem_by_zero = "attempt to calculate the remainder with a divisor of zero", - panic_const_coroutine_resumed = "coroutine resumed after completion", - panic_const_async_fn_resumed = "`async fn` resumed after completion", - panic_const_async_gen_fn_resumed = "`async gen fn` resumed after completion", - panic_const_gen_fn_none = "`gen fn` should just keep returning `None` after completion", - panic_const_coroutine_resumed_panic = "coroutine resumed after panicking", - panic_const_async_fn_resumed_panic = "`async fn` resumed after panicking", - panic_const_async_gen_fn_resumed_panic = "`async gen fn` resumed after panicking", - panic_const_gen_fn_none_panic = "`gen fn` should just keep returning `None` after panicking", +pub mod panic_const { + use super::*; + panic_const! { + panic_const_add_overflow = "attempt to add with overflow", + panic_const_sub_overflow = "attempt to subtract with overflow", + panic_const_mul_overflow = "attempt to multiply with overflow", + panic_const_div_overflow = "attempt to divide with overflow", + panic_const_rem_overflow = "attempt to calculate the remainder with overflow", + panic_const_neg_overflow = "attempt to negate with overflow", + panic_const_shr_overflow = "attempt to shift right with overflow", + panic_const_shl_overflow = "attempt to shift left with overflow", + panic_const_div_by_zero = "attempt to divide by zero", + panic_const_rem_by_zero = "attempt to calculate the remainder with a divisor of zero", + panic_const_coroutine_resumed = "coroutine resumed after completion", + panic_const_async_fn_resumed = "`async fn` resumed after completion", + panic_const_async_gen_fn_resumed = "`async gen fn` resumed after completion", + panic_const_gen_fn_none = "`gen fn` should just keep returning `None` after completion", + panic_const_coroutine_resumed_panic = "coroutine resumed after panicking", + panic_const_async_fn_resumed_panic = "`async fn` resumed after panicking", + panic_const_async_gen_fn_resumed_panic = "`async gen fn` resumed after panicking", + panic_const_gen_fn_none_panic = "`gen fn` should just keep returning `None` after panicking", + } + // Separated panic constants list for async drop feature + // (May be joined when the corresponding lang items will be in the bootstrap) + #[cfg(not(bootstrap))] + panic_const! { + panic_const_coroutine_resumed_drop = "coroutine resumed after async drop", + panic_const_async_fn_resumed_drop = "`async fn` resumed after async drop", + panic_const_async_gen_fn_resumed_drop = "`async gen fn` resumed after async drop", + panic_const_gen_fn_none_drop = "`gen fn` resumed after async drop", + } } /// Like `panic`, but without unwinding and track_caller to reduce the impact on codesize on the caller. diff --git a/src/tools/miri/tests/pass/async-drop.rs b/src/tools/miri/tests/pass/async-drop.rs index 6d556b77795..2a95f644389 100644 --- a/src/tools/miri/tests/pass/async-drop.rs +++ b/src/tools/miri/tests/pass/async-drop.rs @@ -4,16 +4,16 @@ // WARNING: If you would ever want to modify this test, // please consider modifying rustc's async drop test at -// `tests/ui/async-await/async-drop.rs`. +// `tests/ui/async-await/async-drop/async-drop-initial.rs`. #![feature(async_drop, impl_trait_in_assoc_type)] #![allow(incomplete_features, dead_code)] // FIXME(zetanumbers): consider AsyncDestruct::async_drop cleanup tests -use core::future::{AsyncDrop, Future, async_drop_in_place}; +use core::future::{async_drop_in_place, AsyncDrop, Future}; use core::hint::black_box; use core::mem::{self, ManuallyDrop}; -use core::pin::{Pin, pin}; +use core::pin::{pin, Pin}; use core::task::{Context, Poll, Waker}; async fn test_async_drop(x: T) { @@ -68,7 +68,8 @@ fn main() { test_async_drop(SyncThenAsync { i: 15, a: AsyncInt(16), b: SyncInt(17), c: AsyncInt(18) }) .await; - let async_drop_fut = pin!(core::future::async_drop(AsyncInt(19))); + let mut ptr19 = mem::MaybeUninit::new(AsyncInt(19)); + let async_drop_fut = pin!(unsafe { async_drop_in_place(ptr19.as_mut_ptr()) }); test_idempotency(async_drop_fut).await; let foo = AsyncInt(20); @@ -89,13 +90,14 @@ fn main() { struct AsyncInt(i32); +impl Drop for AsyncInt { + fn drop(&mut self) { + println!("AsyncInt::drop: {}", self.0); + } +} impl AsyncDrop for AsyncInt { - type Dropper<'a> = impl Future; - - fn async_drop(self: Pin<&mut Self>) -> Self::Dropper<'_> { - async move { - println!("AsyncInt::Dropper::poll: {}", self.0); - } + async fn drop(self: Pin<&mut Self>) { + println!("AsyncInt::async_drop: {}", self.0); } } @@ -124,16 +126,14 @@ struct AsyncReference<'a> { foo: &'a AsyncInt, } +impl Drop for AsyncReference<'_> { + fn drop(&mut self) { + println!("AsyncReference::drop: {}", self.foo.0); + } +} impl AsyncDrop for AsyncReference<'_> { - type Dropper<'a> - = impl Future - where - Self: 'a; - - fn async_drop(self: Pin<&mut Self>) -> Self::Dropper<'_> { - async move { - println!("AsyncReference::Dropper::poll: {}", self.foo.0); - } + async fn drop(self: Pin<&mut Self>) { + println!("AsyncReference::async_drop: {}", self.foo.0); } } @@ -145,13 +145,14 @@ struct AsyncStruct { b: AsyncInt, } +impl Drop for AsyncStruct { + fn drop(&mut self) { + println!("AsyncStruct::drop: {}", self.i); + } +} impl AsyncDrop for AsyncStruct { - type Dropper<'a> = impl Future; - - fn async_drop(self: Pin<&mut Self>) -> Self::Dropper<'_> { - async move { - println!("AsyncStruct::Dropper::poll: {}", self.i); - } + async fn drop(self: Pin<&mut Self>) { + println!("AsyncStruct::async_drop: {}", self.i); } } @@ -160,23 +161,34 @@ enum AsyncEnum { B(SyncInt), } +impl Drop for AsyncEnum { + fn drop(&mut self) { + let new_self = match self { + AsyncEnum::A(foo) => { + println!("AsyncEnum(A)::drop: {}", foo.0); + AsyncEnum::B(SyncInt(foo.0)) + } + AsyncEnum::B(foo) => { + println!("AsyncEnum(B)::drop: {}", foo.0); + AsyncEnum::A(AsyncInt(foo.0)) + } + }; + mem::forget(mem::replace(&mut *self, new_self)); + } +} impl AsyncDrop for AsyncEnum { - type Dropper<'a> = impl Future; - - fn async_drop(mut self: Pin<&mut Self>) -> Self::Dropper<'_> { - async move { - let new_self = match &*self { - AsyncEnum::A(foo) => { - println!("AsyncEnum(A)::Dropper::poll: {}", foo.0); - AsyncEnum::B(SyncInt(foo.0)) - } - AsyncEnum::B(foo) => { - println!("AsyncEnum(B)::Dropper::poll: {}", foo.0); - AsyncEnum::A(AsyncInt(foo.0)) - } - }; - mem::forget(mem::replace(&mut *self, new_self)); - } + async fn drop(mut self: Pin<&mut Self>) { + let new_self = match &*self { + AsyncEnum::A(foo) => { + println!("AsyncEnum(A)::async_drop: {}", foo.0); + AsyncEnum::B(SyncInt(foo.0)) + } + AsyncEnum::B(foo) => { + println!("AsyncEnum(B)::async_drop: {}", foo.0); + AsyncEnum::A(AsyncInt(foo.0)) + } + }; + mem::forget(mem::replace(&mut *self, new_self)); } } @@ -186,14 +198,19 @@ union AsyncUnion { unsigned: u32, } +impl Drop for AsyncUnion { + fn drop(&mut self) { + println!( + "AsyncUnion::drop: {}, {}", + unsafe { self.signed }, + unsafe { self.unsigned }, + ); + } +} impl AsyncDrop for AsyncUnion { - type Dropper<'a> = impl Future; - - fn async_drop(self: Pin<&mut Self>) -> Self::Dropper<'_> { - async move { - println!("AsyncUnion::Dropper::poll: {}, {}", unsafe { self.signed }, unsafe { - self.unsigned - }); - } + async fn drop(self: Pin<&mut Self>) { + println!("AsyncUnion::async_drop: {}, {}", unsafe { self.signed }, unsafe { + self.unsigned + }); } } diff --git a/src/tools/miri/tests/pass/async-drop.stack.stdout b/src/tools/miri/tests/pass/async-drop.stack.stdout index 9cae4331caf..fc53df2f1b4 100644 --- a/src/tools/miri/tests/pass/async-drop.stack.stdout +++ b/src/tools/miri/tests/pass/async-drop.stack.stdout @@ -1,22 +1,23 @@ -AsyncInt::Dropper::poll: 0 -AsyncInt::Dropper::poll: 1 -AsyncInt::Dropper::poll: 2 -AsyncInt::Dropper::poll: 3 -AsyncInt::Dropper::poll: 4 -AsyncStruct::Dropper::poll: 6 -AsyncInt::Dropper::poll: 7 -AsyncInt::Dropper::poll: 8 -AsyncReference::Dropper::poll: 10 -AsyncInt::Dropper::poll: 11 -AsyncEnum(A)::Dropper::poll: 12 +AsyncInt::async_drop: 0 +AsyncInt::async_drop: 1 +AsyncInt::async_drop: 2 +AsyncInt::async_drop: 3 +AsyncInt::async_drop: 4 +AsyncStruct::async_drop: 6 +AsyncInt::async_drop: 7 +AsyncInt::async_drop: 8 +AsyncReference::async_drop: 10 +AsyncInt::async_drop: 11 +AsyncEnum(A)::async_drop: 12 SyncInt::drop: 12 -AsyncEnum(B)::Dropper::poll: 13 -AsyncInt::Dropper::poll: 13 +AsyncEnum(B)::async_drop: 13 +AsyncInt::async_drop: 13 SyncInt::drop: 14 SyncThenAsync::drop: 15 -AsyncInt::Dropper::poll: 16 +AsyncInt::async_drop: 16 SyncInt::drop: 17 -AsyncInt::Dropper::poll: 18 -AsyncInt::Dropper::poll: 19 -AsyncInt::Dropper::poll: 20 -AsyncUnion::Dropper::poll: 21, 21 +AsyncInt::async_drop: 18 +AsyncInt::async_drop: 19 +AsyncInt::async_drop: 20 +AsyncUnion::async_drop: 21, 21 +AsyncInt::async_drop: 10 diff --git a/src/tools/miri/tests/pass/async-drop.tree.stdout b/src/tools/miri/tests/pass/async-drop.tree.stdout index 9cae4331caf..fc53df2f1b4 100644 --- a/src/tools/miri/tests/pass/async-drop.tree.stdout +++ b/src/tools/miri/tests/pass/async-drop.tree.stdout @@ -1,22 +1,23 @@ -AsyncInt::Dropper::poll: 0 -AsyncInt::Dropper::poll: 1 -AsyncInt::Dropper::poll: 2 -AsyncInt::Dropper::poll: 3 -AsyncInt::Dropper::poll: 4 -AsyncStruct::Dropper::poll: 6 -AsyncInt::Dropper::poll: 7 -AsyncInt::Dropper::poll: 8 -AsyncReference::Dropper::poll: 10 -AsyncInt::Dropper::poll: 11 -AsyncEnum(A)::Dropper::poll: 12 +AsyncInt::async_drop: 0 +AsyncInt::async_drop: 1 +AsyncInt::async_drop: 2 +AsyncInt::async_drop: 3 +AsyncInt::async_drop: 4 +AsyncStruct::async_drop: 6 +AsyncInt::async_drop: 7 +AsyncInt::async_drop: 8 +AsyncReference::async_drop: 10 +AsyncInt::async_drop: 11 +AsyncEnum(A)::async_drop: 12 SyncInt::drop: 12 -AsyncEnum(B)::Dropper::poll: 13 -AsyncInt::Dropper::poll: 13 +AsyncEnum(B)::async_drop: 13 +AsyncInt::async_drop: 13 SyncInt::drop: 14 SyncThenAsync::drop: 15 -AsyncInt::Dropper::poll: 16 +AsyncInt::async_drop: 16 SyncInt::drop: 17 -AsyncInt::Dropper::poll: 18 -AsyncInt::Dropper::poll: 19 -AsyncInt::Dropper::poll: 20 -AsyncUnion::Dropper::poll: 21, 21 +AsyncInt::async_drop: 18 +AsyncInt::async_drop: 19 +AsyncInt::async_drop: 20 +AsyncUnion::async_drop: 21, 21 +AsyncInt::async_drop: 10 diff --git a/tests/crashes/128695.rs b/tests/crashes/128695.rs deleted file mode 100644 index 661f427dc0e..00000000000 --- a/tests/crashes/128695.rs +++ /dev/null @@ -1,11 +0,0 @@ -//@ known-bug: rust-lang/rust#128695 -//@ edition: 2021 - -use core::pin::{pin, Pin}; - -fn main() { - let fut = pin!(async { - let async_drop_fut = pin!(core::future::async_drop(async {})); - (async_drop_fut).await; - }); -} diff --git a/tests/crashes/132103.rs b/tests/crashes/132103.rs deleted file mode 100644 index e2d8378efe6..00000000000 --- a/tests/crashes/132103.rs +++ /dev/null @@ -1,22 +0,0 @@ -//@ known-bug: #132103 -//@ compile-flags: -Zvalidate-mir -Zinline-mir=yes -//@ edition: 2018 -use core::future::{async_drop_in_place, Future}; -use core::mem::{self}; -use core::pin::pin; -use core::task::{Context, Waker}; - -async fn test_async_drop(x: T) { - let mut x = mem::MaybeUninit::new(x); - pin!(unsafe { async_drop_in_place(x.as_mut_ptr()) }); -} - -fn main() { - let waker = Waker::noop(); - let mut cx = Context::from_waker(&waker); - - let fut = pin!(async { - test_async_drop(test_async_drop(0)).await; - }); - fut.poll(&mut cx); -} diff --git a/tests/mir-opt/async_closure_fake_read_for_by_move.foo-{closure#0}-{closure#0}.built.after.mir b/tests/mir-opt/async_closure_fake_read_for_by_move.foo-{closure#0}-{closure#0}.built.after.mir index 0c8a17ff70b..b43af549b23 100644 --- a/tests/mir-opt/async_closure_fake_read_for_by_move.foo-{closure#0}-{closure#0}.built.after.mir +++ b/tests/mir-opt/async_closure_fake_read_for_by_move.foo-{closure#0}-{closure#0}.built.after.mir @@ -68,14 +68,18 @@ yields () } bb10: { - drop(_1) -> [return: bb11, unwind: bb12]; + drop(_1) -> [return: bb11, unwind: bb13, drop: bb12]; } bb11: { return; } - bb12 (cleanup): { + bb12: { + coroutine_drop; + } + + bb13 (cleanup): { resume; } } diff --git a/tests/mir-opt/async_closure_fake_read_for_by_move.foo-{closure#0}-{synthetic#0}.built.after.mir b/tests/mir-opt/async_closure_fake_read_for_by_move.foo-{closure#0}-{synthetic#0}.built.after.mir index 9070c95bca4..5623b6d64e9 100644 --- a/tests/mir-opt/async_closure_fake_read_for_by_move.foo-{closure#0}-{synthetic#0}.built.after.mir +++ b/tests/mir-opt/async_closure_fake_read_for_by_move.foo-{closure#0}-{synthetic#0}.built.after.mir @@ -51,14 +51,18 @@ yields () } bb6: { - drop(_1) -> [return: bb7, unwind: bb8]; + drop(_1) -> [return: bb7, unwind: bb9, drop: bb8]; } bb7: { return; } - bb8 (cleanup): { + bb8: { + coroutine_drop; + } + + bb9 (cleanup): { resume; } } diff --git a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{closure#0}.built.after.mir b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{closure#0}.built.after.mir index 8a584853e00..4d484b16b50 100644 --- a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{closure#0}.built.after.mir +++ b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{closure#0}.built.after.mir @@ -34,14 +34,18 @@ yields () StorageDead(_5); StorageDead(_4); StorageDead(_3); - drop(_1) -> [return: bb1, unwind: bb2]; + drop(_1) -> [return: bb1, unwind: bb3, drop: bb2]; } bb1: { return; } - bb2 (cleanup): { + bb2: { + coroutine_drop; + } + + bb3 (cleanup): { resume; } } diff --git a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{synthetic#0}.built.after.mir b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{synthetic#0}.built.after.mir index c5f538e5ecd..ace780f773e 100644 --- a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{synthetic#0}.built.after.mir +++ b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{synthetic#0}.built.after.mir @@ -34,14 +34,18 @@ yields () StorageDead(_5); StorageDead(_4); StorageDead(_3); - drop(_1) -> [return: bb1, unwind: bb2]; + drop(_1) -> [return: bb1, unwind: bb3, drop: bb2]; } bb1: { return; } - bb2 (cleanup): { + bb2: { + coroutine_drop; + } + + bb3 (cleanup): { resume; } } diff --git a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}-{closure#0}.built.after.mir b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}-{closure#0}.built.after.mir index c6721085eb2..f50ad689f44 100644 --- a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}-{closure#0}.built.after.mir +++ b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}-{closure#0}.built.after.mir @@ -34,14 +34,18 @@ yields () StorageDead(_5); StorageDead(_4); StorageDead(_3); - drop(_1) -> [return: bb1, unwind: bb2]; + drop(_1) -> [return: bb1, unwind: bb3, drop: bb2]; } bb1: { return; } - bb2 (cleanup): { + bb2: { + coroutine_drop; + } + + bb3 (cleanup): { resume; } } diff --git a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}-{synthetic#0}.built.after.mir b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}-{synthetic#0}.built.after.mir index e295f9b3cf1..62d8adeedcb 100644 --- a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}-{synthetic#0}.built.after.mir +++ b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}-{synthetic#0}.built.after.mir @@ -34,14 +34,18 @@ yields () StorageDead(_5); StorageDead(_4); StorageDead(_3); - drop(_1) -> [return: bb1, unwind: bb2]; + drop(_1) -> [return: bb1, unwind: bb3, drop: bb2]; } bb1: { return; } - bb2 (cleanup): { + bb2: { + coroutine_drop; + } + + bb3 (cleanup): { resume; } } diff --git a/tests/ui/async-await/async-drop.rs b/tests/ui/async-await/async-drop.rs deleted file mode 100644 index b1af81423ce..00000000000 --- a/tests/ui/async-await/async-drop.rs +++ /dev/null @@ -1,222 +0,0 @@ -//@ run-pass -//@ check-run-results - -// WARNING: If you would ever want to modify this test, -// please consider modifying miri's async drop test at -// `src/tools/miri/tests/pass/async-drop.rs`. - -#![feature(async_drop, impl_trait_in_assoc_type)] -#![allow(incomplete_features, dead_code)] - -//@ edition: 2021 - -// FIXME(zetanumbers): consider AsyncDestruct::async_drop cleanup tests -use core::future::{async_drop_in_place, AsyncDrop, Future}; -use core::hint::black_box; -use core::mem::{self, ManuallyDrop}; -use core::pin::{pin, Pin}; -use core::task::{Context, Poll, Waker}; - -async fn test_async_drop(x: T, _size: usize) { - let mut x = mem::MaybeUninit::new(x); - let dtor = pin!(unsafe { async_drop_in_place(x.as_mut_ptr()) }); - - // FIXME(zetanumbers): This check fully depends on the layout of - // the coroutine state, since async destructor combinators are just - // async functions. - #[cfg(target_pointer_width = "64")] - assert_eq!( - mem::size_of_val(&*dtor), - _size, - "sizes did not match for async destructor of type {}", - core::any::type_name::(), - ); - - test_idempotency(dtor).await; -} - -fn test_idempotency(mut x: Pin<&mut T>) -> impl Future + '_ -where - T: Future, -{ - core::future::poll_fn(move |cx| { - assert_eq!(x.as_mut().poll(cx), Poll::Ready(())); - assert_eq!(x.as_mut().poll(cx), Poll::Ready(())); - Poll::Ready(()) - }) -} - -fn main() { - let waker = Waker::noop(); - let mut cx = Context::from_waker(&waker); - - let i = 13; - let fut = pin!(async { - test_async_drop(Int(0), 0).await; - // FIXME(#63818): niches in coroutines are disabled. - // Some of these sizes should be smaller, as indicated in comments. - test_async_drop(AsyncInt(0), /*104*/ 112).await; - test_async_drop([AsyncInt(1), AsyncInt(2)], /*152*/ 168).await; - test_async_drop((AsyncInt(3), AsyncInt(4)), /*488*/ 528).await; - test_async_drop(5, 0).await; - let j = 42; - test_async_drop(&i, 0).await; - test_async_drop(&j, 0).await; - test_async_drop(AsyncStruct { b: AsyncInt(8), a: AsyncInt(7), i: 6 }, /*1688*/ 1792).await; - test_async_drop(ManuallyDrop::new(AsyncInt(9)), 0).await; - - let foo = AsyncInt(10); - test_async_drop(AsyncReference { foo: &foo }, /*104*/ 112).await; - - let foo = AsyncInt(11); - test_async_drop( - || { - black_box(foo); - let foo = AsyncInt(10); - foo - }, - /*120*/ 136, - ) - .await; - - test_async_drop(AsyncEnum::A(AsyncInt(12)), /*680*/ 736).await; - test_async_drop(AsyncEnum::B(SyncInt(13)), /*680*/ 736).await; - - test_async_drop(SyncInt(14), /*16*/ 24).await; - test_async_drop( - SyncThenAsync { i: 15, a: AsyncInt(16), b: SyncInt(17), c: AsyncInt(18) }, - /*3064*/ 3296, - ) - .await; - - let async_drop_fut = pin!(core::future::async_drop(AsyncInt(19))); - test_idempotency(async_drop_fut).await; - - let foo = AsyncInt(20); - test_async_drop( - async || { - black_box(foo); - let foo = AsyncInt(19); - // Await point there, but this is async closure so it's fine - black_box(core::future::ready(())).await; - foo - }, - /*120*/ 136, - ) - .await; - - test_async_drop(AsyncUnion { signed: 21 }, /*32*/ 40).await; - }); - let res = fut.poll(&mut cx); - assert_eq!(res, Poll::Ready(())); -} - -struct AsyncInt(i32); - -impl AsyncDrop for AsyncInt { - type Dropper<'a> = impl Future; - - fn async_drop(self: Pin<&mut Self>) -> Self::Dropper<'_> { - async move { - println!("AsyncInt::Dropper::poll: {}", self.0); - } - } -} - -struct SyncInt(i32); - -impl Drop for SyncInt { - fn drop(&mut self) { - println!("SyncInt::drop: {}", self.0); - } -} - -struct SyncThenAsync { - i: i32, - a: AsyncInt, - b: SyncInt, - c: AsyncInt, -} - -impl Drop for SyncThenAsync { - fn drop(&mut self) { - println!("SyncThenAsync::drop: {}", self.i); - } -} - -struct AsyncReference<'a> { - foo: &'a AsyncInt, -} - -impl AsyncDrop for AsyncReference<'_> { - type Dropper<'a> = impl Future where Self: 'a; - - fn async_drop(self: Pin<&mut Self>) -> Self::Dropper<'_> { - async move { - println!("AsyncReference::Dropper::poll: {}", self.foo.0); - } - } -} - -struct Int(i32); - -struct AsyncStruct { - i: i32, - a: AsyncInt, - b: AsyncInt, -} - -impl AsyncDrop for AsyncStruct { - type Dropper<'a> = impl Future; - - fn async_drop(self: Pin<&mut Self>) -> Self::Dropper<'_> { - async move { - println!("AsyncStruct::Dropper::poll: {}", self.i); - } - } -} - -enum AsyncEnum { - A(AsyncInt), - B(SyncInt), -} - -impl AsyncDrop for AsyncEnum { - type Dropper<'a> = impl Future; - - fn async_drop(mut self: Pin<&mut Self>) -> Self::Dropper<'_> { - async move { - let new_self = match &*self { - AsyncEnum::A(foo) => { - println!("AsyncEnum(A)::Dropper::poll: {}", foo.0); - AsyncEnum::B(SyncInt(foo.0)) - } - AsyncEnum::B(foo) => { - println!("AsyncEnum(B)::Dropper::poll: {}", foo.0); - AsyncEnum::A(AsyncInt(foo.0)) - } - }; - mem::forget(mem::replace(&mut *self, new_self)); - } - } -} - -// FIXME(zetanumbers): Disallow types with `AsyncDrop` in unions -union AsyncUnion { - signed: i32, - unsigned: u32, -} - -impl AsyncDrop for AsyncUnion { - type Dropper<'a> = impl Future; - - fn async_drop(self: Pin<&mut Self>) -> Self::Dropper<'_> { - async move { - println!( - "AsyncUnion::Dropper::poll: {}, {}", - unsafe { self.signed }, - unsafe { self.unsigned }, - ); - } - } -} diff --git a/tests/ui/async-await/async-drop.run.stdout b/tests/ui/async-await/async-drop.run.stdout deleted file mode 100644 index 9cae4331caf..00000000000 --- a/tests/ui/async-await/async-drop.run.stdout +++ /dev/null @@ -1,22 +0,0 @@ -AsyncInt::Dropper::poll: 0 -AsyncInt::Dropper::poll: 1 -AsyncInt::Dropper::poll: 2 -AsyncInt::Dropper::poll: 3 -AsyncInt::Dropper::poll: 4 -AsyncStruct::Dropper::poll: 6 -AsyncInt::Dropper::poll: 7 -AsyncInt::Dropper::poll: 8 -AsyncReference::Dropper::poll: 10 -AsyncInt::Dropper::poll: 11 -AsyncEnum(A)::Dropper::poll: 12 -SyncInt::drop: 12 -AsyncEnum(B)::Dropper::poll: 13 -AsyncInt::Dropper::poll: 13 -SyncInt::drop: 14 -SyncThenAsync::drop: 15 -AsyncInt::Dropper::poll: 16 -SyncInt::drop: 17 -AsyncInt::Dropper::poll: 18 -AsyncInt::Dropper::poll: 19 -AsyncInt::Dropper::poll: 20 -AsyncUnion::Dropper::poll: 21, 21 diff --git a/tests/ui/async-await/async-drop/async-drop-future-from-future.rs b/tests/ui/async-await/async-drop/async-drop-future-from-future.rs new file mode 100644 index 00000000000..44dcbd14f48 --- /dev/null +++ b/tests/ui/async-await/async-drop/async-drop-future-from-future.rs @@ -0,0 +1,101 @@ +//@ run-pass +//@ check-run-results +// Future `bar` with internal async drop `Foo` will have async drop itself. +// And we trying to drop this future in sync context (`block_on` func) + +#![feature(async_drop)] +#![allow(incomplete_features)] + +use std::mem::ManuallyDrop; + +//@ edition: 2021 + +use std::{ + future::{Future, async_drop_in_place, AsyncDrop}, + pin::{pin, Pin}, + sync::{mpsc, Arc}, + task::{Context, Poll, Wake, Waker}, +}; + +struct Foo { + my_resource_handle: usize, +} + +impl Foo { + fn new(my_resource_handle: usize) -> Self { + let out = Foo { + my_resource_handle, + }; + println!("Foo::new({})", my_resource_handle); + out + } +} + +impl Drop for Foo { + fn drop(&mut self) { + println!("Foo::drop({})", self.my_resource_handle); + } +} + +impl AsyncDrop for Foo { + async fn drop(self: Pin<&mut Self>) { + println!("Foo::async drop({})", self.my_resource_handle); + } +} + +fn main() { + block_on(bar(10)); + println!("done") +} + +async fn baz(ident_base: usize) { + let mut _first = Foo::new(ident_base); +} + +async fn bar(ident_base: usize) { + let mut _first = Foo::new(ident_base); + baz(ident_base + 1).await; +} + +fn block_on(fut_unpin: F) -> F::Output +where + F: Future, +{ + let mut fut_pin = pin!(ManuallyDrop::new(fut_unpin)); + let mut fut: Pin<&mut F> = unsafe { + Pin::map_unchecked_mut(fut_pin.as_mut(), |x| &mut **x) + }; + let (waker, rx) = simple_waker(); + let mut context = Context::from_waker(&waker); + let rv = loop { + match fut.as_mut().poll(&mut context) { + Poll::Ready(out) => break out, + // expect wake in polls + Poll::Pending => rx.try_recv().unwrap(), + } + }; + let drop_fut_unpin = unsafe { async_drop_in_place(fut.get_unchecked_mut()) }; + let mut drop_fut: Pin<&mut _> = pin!(drop_fut_unpin); + loop { + match drop_fut.as_mut().poll(&mut context) { + Poll::Ready(()) => break, + Poll::Pending => rx.try_recv().unwrap(), + } + } + rv +} + +fn simple_waker() -> (Waker, mpsc::Receiver<()>) { + struct SimpleWaker { + tx: std::sync::mpsc::Sender<()>, + } + + impl Wake for SimpleWaker { + fn wake(self: Arc) { + self.tx.send(()).unwrap(); + } + } + + let (tx, rx) = mpsc::channel(); + (Waker::from(Arc::new(SimpleWaker { tx })), rx) +} diff --git a/tests/ui/async-await/async-drop/async-drop-future-from-future.run.stdout b/tests/ui/async-await/async-drop/async-drop-future-from-future.run.stdout new file mode 100644 index 00000000000..c2663b3f238 --- /dev/null +++ b/tests/ui/async-await/async-drop/async-drop-future-from-future.run.stdout @@ -0,0 +1,5 @@ +Foo::new(10) +Foo::new(11) +Foo::async drop(11) +Foo::async drop(10) +done diff --git a/tests/ui/async-await/async-drop/async-drop-future-in-sync-context.rs b/tests/ui/async-await/async-drop/async-drop-future-in-sync-context.rs new file mode 100644 index 00000000000..417dce62dba --- /dev/null +++ b/tests/ui/async-await/async-drop/async-drop-future-in-sync-context.rs @@ -0,0 +1,82 @@ +//@ run-pass +//@ check-run-results +// Future `bar` with internal async drop `Foo` will have async drop itself. +// And we trying to drop this future in sync context (`block_on` func) + +#![feature(async_drop)] +#![allow(incomplete_features)] + +//@ edition: 2021 + +use std::{ + future::{Future, AsyncDrop}, + pin::{pin, Pin}, + sync::{mpsc, Arc}, + task::{Context, Poll, Wake, Waker}, +}; + +struct Foo { + my_resource_handle: usize, +} + +impl Foo { + fn new(my_resource_handle: usize) -> Self { + let out = Foo { + my_resource_handle, + }; + println!("Foo::new({})", my_resource_handle); + out + } +} + +impl Drop for Foo { + fn drop(&mut self) { + println!("Foo::drop({})", self.my_resource_handle); + } +} + +impl AsyncDrop for Foo { + async fn drop(self: Pin<&mut Self>) { + println!("Foo::async drop({})", self.my_resource_handle); + } +} + +fn main() { + block_on(bar(10)); + println!("done") +} + +async fn bar(ident_base: usize) { + let mut _first = Foo::new(ident_base); +} + +fn block_on(fut: F) -> F::Output +where + F: Future, +{ + let mut fut = pin!(fut); + let (waker, rx) = simple_waker(); + let mut context = Context::from_waker(&waker); + loop { + match fut.as_mut().poll(&mut context) { + Poll::Ready(out) => break out, + // expect wake in polls + Poll::Pending => rx.try_recv().unwrap(), + } + } +} + +fn simple_waker() -> (Waker, mpsc::Receiver<()>) { + struct SimpleWaker { + tx: std::sync::mpsc::Sender<()>, + } + + impl Wake for SimpleWaker { + fn wake(self: Arc) { + self.tx.send(()).unwrap(); + } + } + + let (tx, rx) = mpsc::channel(); + (Waker::from(Arc::new(SimpleWaker { tx })), rx) +} diff --git a/tests/ui/async-await/async-drop/async-drop-future-in-sync-context.run.stdout b/tests/ui/async-await/async-drop/async-drop-future-in-sync-context.run.stdout new file mode 100644 index 00000000000..ad0b083ca09 --- /dev/null +++ b/tests/ui/async-await/async-drop/async-drop-future-in-sync-context.run.stdout @@ -0,0 +1,3 @@ +Foo::new(10) +Foo::async drop(10) +done diff --git a/tests/ui/async-await/async-drop/async-drop-glue-array.rs b/tests/ui/async-await/async-drop/async-drop-glue-array.rs new file mode 100644 index 00000000000..21c08da2337 --- /dev/null +++ b/tests/ui/async-await/async-drop/async-drop-glue-array.rs @@ -0,0 +1,112 @@ +//@ run-pass +//@ check-run-results +// struct `Foo` has both sync and async drop. +// Struct `Complex` contains three `Foo` fields and has complex async drop glue. + +#![feature(async_drop)] +#![allow(incomplete_features)] + +use std::mem::ManuallyDrop; + +//@ edition: 2021 + +#[inline(never)] +fn myprintln(msg: &str, my_resource_handle: usize) { + println!("{} : {}", msg, my_resource_handle); +} + +use std::{ + future::{Future, async_drop_in_place, AsyncDrop}, + pin::{pin, Pin}, + sync::{mpsc, Arc}, + task::{Context, Poll, Wake, Waker}, +}; + +struct Foo { + my_resource_handle: usize, +} + +impl Foo { + fn new(my_resource_handle: usize) -> Self { + let out = Foo { + my_resource_handle, + }; + myprintln("Foo::new()", my_resource_handle); + out + } +} + +impl Drop for Foo { + fn drop(&mut self) { + myprintln("Foo::drop()", self.my_resource_handle); + } +} + +impl AsyncDrop for Foo { + async fn drop(self: Pin<&mut Self>) { + myprintln("Foo::async drop()", self.my_resource_handle); + } +} + +fn main() { + { + let _ = Foo::new(7); + } + println!("Middle"); + { + block_on(bar(10)); + } + println!("Done") +} + +async fn bar(ident_base: usize) { + let _vec: [Foo; 4] = [ + Foo::new(ident_base), + Foo::new(ident_base + 1), + Foo::new(ident_base + 2), + Foo::new(ident_base + 3) + ]; +} + +fn block_on(fut_unpin: F) -> F::Output +where + F: Future, +{ + let mut fut_pin = pin!(ManuallyDrop::new(fut_unpin)); + let mut fut: Pin<&mut F> = unsafe { + Pin::map_unchecked_mut(fut_pin.as_mut(), |x| &mut **x) + }; + let (waker, rx) = simple_waker(); + let mut context = Context::from_waker(&waker); + let rv = loop { + match fut.as_mut().poll(&mut context) { + Poll::Ready(out) => break out, + // expect wake in polls + Poll::Pending => rx.try_recv().unwrap(), + } + }; + let drop_fut_unpin = unsafe { async_drop_in_place(fut.get_unchecked_mut()) }; + let mut drop_fut: Pin<&mut _> = pin!(drop_fut_unpin); + loop { + match drop_fut.as_mut().poll(&mut context) { + Poll::Ready(()) => break, + Poll::Pending => rx.try_recv().unwrap(), + } + } + rv +} + +fn simple_waker() -> (Waker, mpsc::Receiver<()>) { + struct SimpleWaker { + tx: std::sync::mpsc::Sender<()>, + } + + impl Wake for SimpleWaker { + fn wake(self: Arc) { + self.tx.send(()).unwrap(); + } + } + + let (tx, rx) = mpsc::channel(); + (Waker::from(Arc::new(SimpleWaker { tx })), rx) +} diff --git a/tests/ui/async-await/async-drop/async-drop-glue-array.run.stdout b/tests/ui/async-await/async-drop/async-drop-glue-array.run.stdout new file mode 100644 index 00000000000..56b61103cc4 --- /dev/null +++ b/tests/ui/async-await/async-drop/async-drop-glue-array.run.stdout @@ -0,0 +1,12 @@ +Foo::new() : 7 +Foo::drop() : 7 +Middle +Foo::new() : 10 +Foo::new() : 11 +Foo::new() : 12 +Foo::new() : 13 +Foo::async drop() : 10 +Foo::async drop() : 11 +Foo::async drop() : 12 +Foo::async drop() : 13 +Done diff --git a/tests/ui/async-await/async-drop/async-drop-glue-generic.rs b/tests/ui/async-await/async-drop/async-drop-glue-generic.rs new file mode 100644 index 00000000000..9e8ae130324 --- /dev/null +++ b/tests/ui/async-await/async-drop/async-drop-glue-generic.rs @@ -0,0 +1,111 @@ +//@ run-pass +//@ check-run-results +// struct `Foo` has both sync and async drop. + +#![feature(async_drop)] +#![allow(incomplete_features)] + +use std::mem::ManuallyDrop; + +//@ edition: 2021 + +#[inline(never)] +fn myprintln(msg: &str, my_resource_handle: usize) { + println!("{} : {}", msg, my_resource_handle); +} + +use std::{ + future::{Future, async_drop_in_place, AsyncDrop}, + pin::{pin, Pin}, + sync::{mpsc, Arc}, + task::{Context, Poll, Wake, Waker}, +}; + +struct Foo { + my_resource_handle: usize, +} + +impl Foo { + fn new(my_resource_handle: usize) -> Self { + let out = Foo { + my_resource_handle, + }; + myprintln("Foo::new()", my_resource_handle); + out + } +} + +impl Drop for Foo { + fn drop(&mut self) { + myprintln("Foo::drop()", self.my_resource_handle); + } +} + +impl AsyncDrop for Foo { + async fn drop(self: Pin<&mut Self>) { + myprintln("Foo::async drop()", self.my_resource_handle); + } +} + +fn main() { + { + let _ = Foo::new(7); + } + println!("Middle"); + { + block_on(bar(6, 10)); + } + println!("Done") +} + +async fn bar(_arg: T, ident_base: usize) { + let _vec: [Foo; 4] = [ + Foo::new(ident_base), + Foo::new(ident_base + 1), + Foo::new(ident_base + 2), + Foo::new(ident_base + 3) + ]; +} + +fn block_on(fut_unpin: F) -> F::Output +where + F: Future, +{ + let mut fut_pin = pin!(ManuallyDrop::new(fut_unpin)); + let mut fut: Pin<&mut F> = unsafe { + Pin::map_unchecked_mut(fut_pin.as_mut(), |x| &mut **x) + }; + let (waker, rx) = simple_waker(); + let mut context = Context::from_waker(&waker); + let rv = loop { + match fut.as_mut().poll(&mut context) { + Poll::Ready(out) => break out, + // expect wake in polls + Poll::Pending => rx.try_recv().unwrap(), + } + }; + let drop_fut_unpin = unsafe { async_drop_in_place(fut.get_unchecked_mut()) }; + let mut drop_fut: Pin<&mut _> = pin!(drop_fut_unpin); + loop { + match drop_fut.as_mut().poll(&mut context) { + Poll::Ready(()) => break, + Poll::Pending => rx.try_recv().unwrap(), + } + } + rv +} + +fn simple_waker() -> (Waker, mpsc::Receiver<()>) { + struct SimpleWaker { + tx: std::sync::mpsc::Sender<()>, + } + + impl Wake for SimpleWaker { + fn wake(self: Arc) { + self.tx.send(()).unwrap(); + } + } + + let (tx, rx) = mpsc::channel(); + (Waker::from(Arc::new(SimpleWaker { tx })), rx) +} diff --git a/tests/ui/async-await/async-drop/async-drop-glue-generic.run.stdout b/tests/ui/async-await/async-drop/async-drop-glue-generic.run.stdout new file mode 100644 index 00000000000..56b61103cc4 --- /dev/null +++ b/tests/ui/async-await/async-drop/async-drop-glue-generic.run.stdout @@ -0,0 +1,12 @@ +Foo::new() : 7 +Foo::drop() : 7 +Middle +Foo::new() : 10 +Foo::new() : 11 +Foo::new() : 12 +Foo::new() : 13 +Foo::async drop() : 10 +Foo::async drop() : 11 +Foo::async drop() : 12 +Foo::async drop() : 13 +Done diff --git a/tests/ui/async-await/async-drop/async-drop-glue.rs b/tests/ui/async-await/async-drop/async-drop-glue.rs new file mode 100644 index 00000000000..dc4bb527a51 --- /dev/null +++ b/tests/ui/async-await/async-drop/async-drop-glue.rs @@ -0,0 +1,124 @@ +//@ run-pass +//@ check-run-results +// struct `Foo` has both sync and async drop. +// Struct `Complex` contains three `Foo` fields and has complex async drop glue. + +#![feature(async_drop)] +#![allow(incomplete_features)] + +use std::mem::ManuallyDrop; + +//@ edition: 2021 + +#[inline(never)] +fn myprintln(msg: &str, my_resource_handle: usize) { + println!("{} : {}", msg, my_resource_handle); +} + +use std::{ + future::{Future, async_drop_in_place, AsyncDrop}, + pin::{pin, Pin}, + sync::{mpsc, Arc}, + task::{Context, Poll, Wake, Waker}, +}; + +struct Foo { + my_resource_handle: usize, +} + +#[allow(dead_code)] +struct Complex { + field1: Foo, + field2: Foo, + field3: Foo, +} + +impl Complex { + fn new(my_resource_handle: usize) -> Self { + myprintln("Complex::new()", my_resource_handle); + let field1 = Foo::new(my_resource_handle); + let field2 = Foo::new(my_resource_handle + 1); + let field3 = Foo::new(my_resource_handle + 2); + Complex { field1, field2, field3 } + } +} + +impl Foo { + fn new(my_resource_handle: usize) -> Self { + let out = Foo { + my_resource_handle, + }; + myprintln("Foo::new()", my_resource_handle); + out + } +} + +impl Drop for Foo { + fn drop(&mut self) { + myprintln("Foo::drop()", self.my_resource_handle); + } +} + +impl AsyncDrop for Foo { + async fn drop(self: Pin<&mut Self>) { + myprintln("Foo::async drop()", self.my_resource_handle); + } +} + +fn main() { + { + let _ = Foo::new(7); + } + println!("Middle"); + { + block_on(bar(10)); + } + println!("Done") +} + +async fn bar(ident_base: usize) { + let _complex = Complex::new(ident_base); +} + +fn block_on(fut_unpin: F) -> F::Output +where + F: Future, +{ + let mut fut_pin = pin!(ManuallyDrop::new(fut_unpin)); + let mut fut: Pin<&mut F> = unsafe { + Pin::map_unchecked_mut(fut_pin.as_mut(), |x| &mut **x) + }; + let (waker, rx) = simple_waker(); + let mut context = Context::from_waker(&waker); + let rv = loop { + match fut.as_mut().poll(&mut context) { + Poll::Ready(out) => break out, + // expect wake in polls + Poll::Pending => rx.try_recv().unwrap(), + } + }; + let drop_fut_unpin = unsafe { async_drop_in_place(fut.get_unchecked_mut()) }; + let mut drop_fut: Pin<&mut _> = pin!(drop_fut_unpin); + loop { + match drop_fut.as_mut().poll(&mut context) { + Poll::Ready(()) => break, + Poll::Pending => rx.try_recv().unwrap(), + } + } + rv +} + +fn simple_waker() -> (Waker, mpsc::Receiver<()>) { + struct SimpleWaker { + tx: std::sync::mpsc::Sender<()>, + } + + impl Wake for SimpleWaker { + fn wake(self: Arc) { + self.tx.send(()).unwrap(); + } + } + + let (tx, rx) = mpsc::channel(); + (Waker::from(Arc::new(SimpleWaker { tx })), rx) +} diff --git a/tests/ui/async-await/async-drop/async-drop-glue.run.stdout b/tests/ui/async-await/async-drop/async-drop-glue.run.stdout new file mode 100644 index 00000000000..e21a9dd34fa --- /dev/null +++ b/tests/ui/async-await/async-drop/async-drop-glue.run.stdout @@ -0,0 +1,11 @@ +Foo::new() : 7 +Foo::drop() : 7 +Middle +Complex::new() : 10 +Foo::new() : 10 +Foo::new() : 11 +Foo::new() : 12 +Foo::async drop() : 10 +Foo::async drop() : 11 +Foo::async drop() : 12 +Done diff --git a/tests/ui/async-await/async-drop/async-drop-initial.rs b/tests/ui/async-await/async-drop/async-drop-initial.rs new file mode 100644 index 00000000000..80b34840c8b --- /dev/null +++ b/tests/ui/async-await/async-drop/async-drop-initial.rs @@ -0,0 +1,243 @@ +//@ run-pass +//@ check-run-results + +// WARNING: If you would ever want to modify this test, +// please consider modifying miri's async drop test at +// `src/tools/miri/tests/pass/async-drop.rs`. + +#![feature(async_drop, impl_trait_in_assoc_type)] +#![allow(incomplete_features, dead_code)] + +//@ edition: 2021 + +// FIXME(zetanumbers): consider AsyncDestruct::async_drop cleanup tests +use core::future::{async_drop_in_place, AsyncDrop, Future}; +use core::hint::black_box; +use core::mem::{self, ManuallyDrop}; +use core::pin::{pin, Pin}; +use core::task::{Context, Poll, Waker}; + +async fn test_async_drop(x: T, _size: usize) { + let mut x = mem::MaybeUninit::new(x); + let dtor = pin!(unsafe { async_drop_in_place(x.as_mut_ptr()) }); + + // FIXME(zetanumbers): This check fully depends on the layout of + // the coroutine state, since async destructor combinators are just + // async functions. + #[cfg(target_pointer_width = "64")] + assert_eq!( + mem::size_of_val(&*dtor), + _size, + "sizes did not match for async destructor of type {}", + core::any::type_name::(), + ); + + test_idempotency(dtor).await; +} + +fn test_idempotency(mut x: Pin<&mut T>) -> impl Future + '_ +where + T: Future, +{ + core::future::poll_fn(move |cx| { + assert_eq!(x.as_mut().poll(cx), Poll::Ready(())); + assert_eq!(x.as_mut().poll(cx), Poll::Ready(())); + Poll::Ready(()) + }) +} + +fn main() { + let waker = Waker::noop(); + let mut cx = Context::from_waker(&waker); + + let i = 13; + let fut = pin!(async { + test_async_drop(Int(0), 16).await; + test_async_drop(AsyncInt(0), 32).await; + test_async_drop([AsyncInt(1), AsyncInt(2)], 104).await; + test_async_drop((AsyncInt(3), AsyncInt(4)), 120).await; + test_async_drop(5, 16).await; + let j = 42; + test_async_drop(&i, 16).await; + test_async_drop(&j, 16).await; + test_async_drop(AsyncStruct { b: AsyncInt(8), a: AsyncInt(7), i: 6 }, 168).await; + test_async_drop(ManuallyDrop::new(AsyncInt(9)), 16).await; + + let foo = AsyncInt(10); + test_async_drop(AsyncReference { foo: &foo }, 32).await; + let _ = ManuallyDrop::new(foo); + + let foo = AsyncInt(11); + test_async_drop( + || { + black_box(foo); + let foo = AsyncInt(10); + foo + }, + 48, + ) + .await; + + test_async_drop(AsyncEnum::A(AsyncInt(12)), 104).await; + test_async_drop(AsyncEnum::B(SyncInt(13)), 104).await; + + test_async_drop(SyncInt(14), 16).await; + test_async_drop( + SyncThenAsync { i: 15, a: AsyncInt(16), b: SyncInt(17), c: AsyncInt(18) }, + 120, + ) + .await; + + let mut ptr19 = mem::MaybeUninit::new(AsyncInt(19)); + let async_drop_fut = pin!(unsafe { async_drop_in_place(ptr19.as_mut_ptr()) }); + test_idempotency(async_drop_fut).await; + + let foo = AsyncInt(20); + test_async_drop( + async || { + black_box(foo); + let foo = AsyncInt(19); + // Await point there, but this is async closure so it's fine + black_box(core::future::ready(())).await; + foo + }, + 48, + ) + .await; + + test_async_drop(AsyncUnion { signed: 21 }, 32).await; + }); + let res = fut.poll(&mut cx); + assert_eq!(res, Poll::Ready(())); +} + +struct AsyncInt(i32); + +impl Drop for AsyncInt { + fn drop(&mut self) { + println!("AsyncInt::drop: {}", self.0); + } +} +impl AsyncDrop for AsyncInt { + async fn drop(self: Pin<&mut Self>) { + println!("AsyncInt::Dropper::poll: {}", self.0); + } +} + +struct SyncInt(i32); + +impl Drop for SyncInt { + fn drop(&mut self) { + println!("SyncInt::drop: {}", self.0); + } +} + +struct SyncThenAsync { + i: i32, + a: AsyncInt, + b: SyncInt, + c: AsyncInt, +} + +impl Drop for SyncThenAsync { + fn drop(&mut self) { + println!("SyncThenAsync::drop: {}", self.i); + } +} + +struct AsyncReference<'a> { + foo: &'a AsyncInt, +} + +impl Drop for AsyncReference<'_> { + fn drop(&mut self) { + println!("AsyncReference::drop: {}", self.foo.0); + } +} + +impl AsyncDrop for AsyncReference<'_> { + async fn drop(self: Pin<&mut Self>) { + println!("AsyncReference::Dropper::poll: {}", self.foo.0); + } +} + +struct Int(i32); + +struct AsyncStruct { + i: i32, + a: AsyncInt, + b: AsyncInt, +} + +impl Drop for AsyncStruct { + fn drop(&mut self) { + println!("AsyncStruct::drop: {}", self.i); + } +} + +impl AsyncDrop for AsyncStruct { + async fn drop(self: Pin<&mut Self>) { + println!("AsyncStruct::Dropper::poll: {}", self.i); + } +} + +enum AsyncEnum { + A(AsyncInt), + B(SyncInt), +} + +impl Drop for AsyncEnum { + fn drop(&mut self) { + let new_self = match self { + AsyncEnum::A(foo) => { + println!("AsyncEnum(A)::drop: {}", foo.0); + AsyncEnum::B(SyncInt(foo.0)) + } + AsyncEnum::B(foo) => { + println!("AsyncEnum(B)::drop: {}", foo.0); + AsyncEnum::A(AsyncInt(foo.0)) + } + }; + mem::forget(mem::replace(&mut *self, new_self)); + } +} +impl AsyncDrop for AsyncEnum { + async fn drop(mut self: Pin<&mut Self>) { + let new_self = match &*self { + AsyncEnum::A(foo) => { + println!("AsyncEnum(A)::Dropper::poll: {}", foo.0); + AsyncEnum::B(SyncInt(foo.0)) + } + AsyncEnum::B(foo) => { + println!("AsyncEnum(B)::Dropper::poll: {}", foo.0); + AsyncEnum::A(AsyncInt(foo.0)) + } + }; + mem::forget(mem::replace(&mut *self, new_self)); + } +} + +// FIXME(zetanumbers): Disallow types with `AsyncDrop` in unions +union AsyncUnion { + signed: i32, + unsigned: u32, +} + +impl Drop for AsyncUnion { + fn drop(&mut self) { + println!( + "AsyncUnion::drop: {}, {}", + unsafe { self.signed }, + unsafe { self.unsigned }, + ); + } +} +impl AsyncDrop for AsyncUnion { + async fn drop(self: Pin<&mut Self>) { + println!( + "AsyncUnion::Dropper::poll: {}, {}", + unsafe { self.signed }, + unsafe { self.unsigned }, + ); + } +} diff --git a/tests/ui/async-await/async-drop/async-drop-initial.run.stdout b/tests/ui/async-await/async-drop/async-drop-initial.run.stdout new file mode 100644 index 00000000000..9cae4331caf --- /dev/null +++ b/tests/ui/async-await/async-drop/async-drop-initial.run.stdout @@ -0,0 +1,22 @@ +AsyncInt::Dropper::poll: 0 +AsyncInt::Dropper::poll: 1 +AsyncInt::Dropper::poll: 2 +AsyncInt::Dropper::poll: 3 +AsyncInt::Dropper::poll: 4 +AsyncStruct::Dropper::poll: 6 +AsyncInt::Dropper::poll: 7 +AsyncInt::Dropper::poll: 8 +AsyncReference::Dropper::poll: 10 +AsyncInt::Dropper::poll: 11 +AsyncEnum(A)::Dropper::poll: 12 +SyncInt::drop: 12 +AsyncEnum(B)::Dropper::poll: 13 +AsyncInt::Dropper::poll: 13 +SyncInt::drop: 14 +SyncThenAsync::drop: 15 +AsyncInt::Dropper::poll: 16 +SyncInt::drop: 17 +AsyncInt::Dropper::poll: 18 +AsyncInt::Dropper::poll: 19 +AsyncInt::Dropper::poll: 20 +AsyncUnion::Dropper::poll: 21, 21 diff --git a/tests/ui/async-await/async-drop/async-drop-middle-drop.rs b/tests/ui/async-await/async-drop/async-drop-middle-drop.rs new file mode 100644 index 00000000000..772a853fe1e --- /dev/null +++ b/tests/ui/async-await/async-drop/async-drop-middle-drop.rs @@ -0,0 +1,110 @@ +//@ run-pass +//@ check-run-results +// Test async drop of coroutine `bar` (with internal async drop), +// stopped at the middle of execution, with AsyncDrop object Foo active. + +#![feature(async_drop)] +#![allow(incomplete_features)] + +//@ edition: 2021 + +use std::mem::ManuallyDrop; + +use std::{ + future::{Future, async_drop_in_place, AsyncDrop}, + pin::{pin, Pin}, + sync::{mpsc, Arc}, + task::{Context, Poll, Wake, Waker}, +}; + +struct Foo { + my_resource_handle: usize, +} + +impl Foo { + fn new(my_resource_handle: usize) -> Self { + let out = Foo { + my_resource_handle, + }; + println!("Foo::new({})", my_resource_handle); + out + } +} + +impl Drop for Foo { + fn drop(&mut self) { + println!("Foo::drop({})", self.my_resource_handle); + } +} + +impl AsyncDrop for Foo { + async fn drop(self: Pin<&mut Self>) { + println!("Foo::async drop({})", self.my_resource_handle); + } +} + +fn main() { + block_on_and_drop_in_the_middle(bar(10)); + println!("done") +} + +pub struct MiddleFuture { + first_call: bool, +} +impl Future for MiddleFuture { + type Output = (); + fn poll(mut self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll { + if self.first_call { + println!("MiddleFuture first poll"); + self.first_call = false; + Poll::Pending + } else { + println!("MiddleFuture Ready"); + Poll::Ready(()) + } + } +} + +async fn bar(ident_base: usize) { + let middle = MiddleFuture { first_call: true }; + let mut _first = Foo::new(ident_base); + middle.await; // Hanging `bar` future before Foo drop +} + +fn block_on_and_drop_in_the_middle(fut_unpin: F) -> F::Output +where + F: Future, +{ + let mut fut_pin = pin!(ManuallyDrop::new(fut_unpin)); + let mut fut: Pin<&mut F> = unsafe { + Pin::map_unchecked_mut(fut_pin.as_mut(), |x| &mut **x) + }; + let (waker, rx) = simple_waker(); + let mut context = Context::from_waker(&waker); + let poll1 = fut.as_mut().poll(&mut context); + assert!(poll1.is_pending()); + + let drop_fut_unpin = unsafe { async_drop_in_place(fut.get_unchecked_mut()) }; + let mut drop_fut: Pin<&mut _> = pin!(drop_fut_unpin); + loop { + match drop_fut.as_mut().poll(&mut context) { + Poll::Ready(()) => break, + Poll::Pending => rx.try_recv().unwrap(), + } + } +} + +fn simple_waker() -> (Waker, mpsc::Receiver<()>) { + struct SimpleWaker { + tx: std::sync::mpsc::Sender<()>, + } + + impl Wake for SimpleWaker { + fn wake(self: Arc) { + self.tx.send(()).unwrap(); + } + } + + let (tx, rx) = mpsc::channel(); + (Waker::from(Arc::new(SimpleWaker { tx })), rx) +} diff --git a/tests/ui/async-await/async-drop/async-drop-middle-drop.run.stdout b/tests/ui/async-await/async-drop/async-drop-middle-drop.run.stdout new file mode 100644 index 00000000000..60df7674d0a --- /dev/null +++ b/tests/ui/async-await/async-drop/async-drop-middle-drop.run.stdout @@ -0,0 +1,4 @@ +Foo::new(10) +MiddleFuture first poll +Foo::async drop(10) +done diff --git a/tests/ui/async-await/async-drop/async-drop-open.rs b/tests/ui/async-await/async-drop/async-drop-open.rs new file mode 100644 index 00000000000..d14eff874ae --- /dev/null +++ b/tests/ui/async-await/async-drop/async-drop-open.rs @@ -0,0 +1,127 @@ +//@ run-pass +//@ check-run-results +// struct `Foo` has both sync and async drop. +// Struct `Complex` contains three `Foo` fields and one of them is moved out. + +#![feature(async_drop)] +#![allow(incomplete_features)] + +use std::mem::ManuallyDrop; + +//@ edition: 2021 + +#[inline(never)] +fn myprintln(msg: &str, my_resource_handle: usize) { + println!("{} : {}", msg, my_resource_handle); +} + +use std::{ + future::{Future, async_drop_in_place, AsyncDrop}, + pin::{pin, Pin}, + sync::{mpsc, Arc}, + task::{Context, Poll, Wake, Waker}, +}; + +struct Foo { + my_resource_handle: usize, +} + +#[allow(dead_code)] +struct Complex { + field1: Foo, + field2: Foo, + field3: Foo, +} + +impl Complex { + fn new(my_resource_handle: usize) -> Self { + myprintln("Complex::new()", my_resource_handle); + let field1 = Foo::new(my_resource_handle); + let field2 = Foo::new(my_resource_handle + 1); + let field3 = Foo::new(my_resource_handle + 2); + Complex { field1, field2, field3 } + } +} + +impl Foo { + fn new(my_resource_handle: usize) -> Self { + let out = Foo { + my_resource_handle, + }; + myprintln("Foo::new()", my_resource_handle); + out + } +} + +impl Drop for Foo { + fn drop(&mut self) { + myprintln("Foo::drop()", self.my_resource_handle); + } +} + +impl AsyncDrop for Foo { + async fn drop(self: Pin<&mut Self>) { + myprintln("Foo::async drop()", self.my_resource_handle); + } +} + +fn main() { + { + let _ = Foo::new(7); + } + println!("Middle"); + // Inside field1 and field3 of Complex must be dropped (as async drop) + // field2 must be dropped here (as sync drop) + { + let _field2 = block_on(bar(10)); + } + println!("Done") +} + +async fn bar(ident_base: usize) -> Foo { + let complex = Complex::new(ident_base); + complex.field2 +} + +fn block_on(fut_unpin: F) -> F::Output +where + F: Future, +{ + let mut fut_pin = pin!(ManuallyDrop::new(fut_unpin)); + let mut fut: Pin<&mut F> = unsafe { + Pin::map_unchecked_mut(fut_pin.as_mut(), |x| &mut **x) + }; + let (waker, rx) = simple_waker(); + let mut context = Context::from_waker(&waker); + let rv = loop { + match fut.as_mut().poll(&mut context) { + Poll::Ready(out) => break out, + // expect wake in polls + Poll::Pending => rx.try_recv().unwrap(), + } + }; + let drop_fut_unpin = unsafe { async_drop_in_place(fut.get_unchecked_mut()) }; + let mut drop_fut: Pin<&mut _> = pin!(drop_fut_unpin); + loop { + match drop_fut.as_mut().poll(&mut context) { + Poll::Ready(()) => break, + Poll::Pending => rx.try_recv().unwrap(), + } + } + rv +} + +fn simple_waker() -> (Waker, mpsc::Receiver<()>) { + struct SimpleWaker { + tx: std::sync::mpsc::Sender<()>, + } + + impl Wake for SimpleWaker { + fn wake(self: Arc) { + self.tx.send(()).unwrap(); + } + } + + let (tx, rx) = mpsc::channel(); + (Waker::from(Arc::new(SimpleWaker { tx })), rx) +} diff --git a/tests/ui/async-await/async-drop/async-drop-open.run.stdout b/tests/ui/async-await/async-drop/async-drop-open.run.stdout new file mode 100644 index 00000000000..e72dfd8a743 --- /dev/null +++ b/tests/ui/async-await/async-drop/async-drop-open.run.stdout @@ -0,0 +1,11 @@ +Foo::new() : 7 +Foo::drop() : 7 +Middle +Complex::new() : 10 +Foo::new() : 10 +Foo::new() : 11 +Foo::new() : 12 +Foo::async drop() : 10 +Foo::async drop() : 12 +Foo::drop() : 11 +Done diff --git a/tests/ui/async-await/async-drop/async-drop.rs b/tests/ui/async-await/async-drop/async-drop.rs new file mode 100644 index 00000000000..2d9c5934be5 --- /dev/null +++ b/tests/ui/async-await/async-drop/async-drop.rs @@ -0,0 +1,105 @@ +//@ run-pass +//@ check-run-results +// struct `Foo` has both sync and async drop. +// Sync version is called in sync context, async version is called in async function. + +#![feature(async_drop)] +#![allow(incomplete_features)] + +use std::mem::ManuallyDrop; + +//@ edition: 2021 + +#[inline(never)] +fn myprintln(msg: &str, my_resource_handle: usize) { + println!("{} : {}", msg, my_resource_handle); +} + +use std::{ + future::{Future, async_drop_in_place, AsyncDrop}, + pin::{pin, Pin}, + sync::{mpsc, Arc}, + task::{Context, Poll, Wake, Waker}, +}; + +struct Foo { + my_resource_handle: usize, +} + +impl Foo { + fn new(my_resource_handle: usize) -> Self { + let out = Foo { + my_resource_handle, + }; + myprintln("Foo::new()", my_resource_handle); + out + } +} + +impl Drop for Foo { + fn drop(&mut self) { + myprintln("Foo::drop()", self.my_resource_handle); + } +} + +impl AsyncDrop for Foo { + async fn drop(self: Pin<&mut Self>) { + myprintln("Foo::async drop()", self.my_resource_handle); + } +} + +fn main() { + { + let _ = Foo::new(7); + } + println!("Middle"); + block_on(bar(10)); + println!("Done") +} + +async fn bar(ident_base: usize) { + let mut _first = Foo::new(ident_base); +} + +fn block_on(fut_unpin: F) -> F::Output +where + F: Future, +{ + let mut fut_pin = pin!(ManuallyDrop::new(fut_unpin)); + let mut fut: Pin<&mut F> = unsafe { + Pin::map_unchecked_mut(fut_pin.as_mut(), |x| &mut **x) + }; + let (waker, rx) = simple_waker(); + let mut context = Context::from_waker(&waker); + let rv = loop { + match fut.as_mut().poll(&mut context) { + Poll::Ready(out) => break out, + // expect wake in polls + Poll::Pending => rx.try_recv().unwrap(), + } + }; + let drop_fut_unpin = unsafe { async_drop_in_place(fut.get_unchecked_mut()) }; + let mut drop_fut: Pin<&mut _> = pin!(drop_fut_unpin); + loop { + match drop_fut.as_mut().poll(&mut context) { + Poll::Ready(()) => break, + Poll::Pending => rx.try_recv().unwrap(), + } + } + rv +} + +fn simple_waker() -> (Waker, mpsc::Receiver<()>) { + struct SimpleWaker { + tx: std::sync::mpsc::Sender<()>, + } + + impl Wake for SimpleWaker { + fn wake(self: Arc) { + self.tx.send(()).unwrap(); + } + } + + let (tx, rx) = mpsc::channel(); + (Waker::from(Arc::new(SimpleWaker { tx })), rx) +} diff --git a/tests/ui/async-await/async-drop/async-drop.run.stdout b/tests/ui/async-await/async-drop/async-drop.run.stdout new file mode 100644 index 00000000000..cb7d0b0fea5 --- /dev/null +++ b/tests/ui/async-await/async-drop/async-drop.run.stdout @@ -0,0 +1,6 @@ +Foo::new() : 7 +Foo::drop() : 7 +Middle +Foo::new() : 10 +Foo::async drop() : 10 +Done diff --git a/tests/ui/async-await/async-drop/ex-ice-132103.rs b/tests/ui/async-await/async-drop/ex-ice-132103.rs new file mode 100644 index 00000000000..3d32cb14fb0 --- /dev/null +++ b/tests/ui/async-await/async-drop/ex-ice-132103.rs @@ -0,0 +1,27 @@ +//@ run-pass +//! This test used to ICE: rust-lang/rust#132103 +//! Fixed when re-work async drop to shim drop glue coroutine scheme. +//@ compile-flags: -Zvalidate-mir -Zinline-mir=yes +//@ edition: 2018 +#![feature(async_drop)] +#![allow(incomplete_features)] + +use core::future::{async_drop_in_place, Future}; +use core::mem::{self}; +use core::pin::pin; +use core::task::{Context, Waker}; + +async fn test_async_drop(x: T) { + let mut x = mem::MaybeUninit::new(x); + pin!(unsafe { async_drop_in_place(x.as_mut_ptr()) }); +} + +fn main() { + let waker = Waker::noop(); + let mut cx = Context::from_waker(&waker); + + let fut = pin!(async { + test_async_drop(test_async_drop(0)).await; + }); + let _ = fut.poll(&mut cx); +} diff --git a/tests/ui/async-await/async-drop/ex-ice1.rs b/tests/ui/async-await/async-drop/ex-ice1.rs new file mode 100644 index 00000000000..f514c57097a --- /dev/null +++ b/tests/ui/async-await/async-drop/ex-ice1.rs @@ -0,0 +1,13 @@ +//! This test used to ICE: rust-lang/rust#128695 +//! Fixed when re-work async drop to shim drop glue coroutine scheme. +//@ edition: 2021 + +use core::pin::{pin, Pin}; + +fn main() { + let fut = pin!(async { + let async_drop_fut = pin!(core::future::async_drop(async {})); //~ ERROR: expected function, found module `core::future::async_drop` + //~^ ERROR: module `async_drop` is private + (async_drop_fut).await; + }); +} diff --git a/tests/ui/async-await/async-drop/ex-ice1.stderr b/tests/ui/async-await/async-drop/ex-ice1.stderr new file mode 100644 index 00000000000..68533edeb08 --- /dev/null +++ b/tests/ui/async-await/async-drop/ex-ice1.stderr @@ -0,0 +1,19 @@ +error[E0423]: expected function, found module `core::future::async_drop` + --> $DIR/ex-ice1.rs:9:35 + | +LL | let async_drop_fut = pin!(core::future::async_drop(async {})); + | ^^^^^^^^^^^^^^^^^^^^^^^^ not a function + +error[E0603]: module `async_drop` is private + --> $DIR/ex-ice1.rs:9:49 + | +LL | let async_drop_fut = pin!(core::future::async_drop(async {})); + | ^^^^^^^^^^ private module + | +note: the module `async_drop` is defined here + --> $SRC_DIR/core/src/future/mod.rs:LL:COL + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0423, E0603. +For more information about an error, try `rustc --explain E0423`. diff --git a/tests/ui/feature-gates/feature-gate-async-drop.rs b/tests/ui/feature-gates/feature-gate-async-drop.rs new file mode 100644 index 00000000000..20511b1d8ee --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-async-drop.rs @@ -0,0 +1,16 @@ +//@ edition: 2021 + +use std::future::AsyncDrop; //~ ERROR use of unstable library feature `async_drop` +use std::pin::Pin; + +struct Foo {} + +impl Drop for Foo { + fn drop(&mut self) {} +} + +impl AsyncDrop for Foo { //~ ERROR use of unstable library feature `async_drop` + async fn drop(self: Pin<&mut Self>) {} //~ ERROR use of unstable library feature `async_drop` +} + +fn main() {} diff --git a/tests/ui/feature-gates/feature-gate-async-drop.stderr b/tests/ui/feature-gates/feature-gate-async-drop.stderr new file mode 100644 index 00000000000..e795c3a3422 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-async-drop.stderr @@ -0,0 +1,33 @@ +error[E0658]: use of unstable library feature `async_drop` + --> $DIR/feature-gate-async-drop.rs:3:5 + | +LL | use std::future::AsyncDrop; + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #126482 for more information + = help: add `#![feature(async_drop)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: use of unstable library feature `async_drop` + --> $DIR/feature-gate-async-drop.rs:13:5 + | +LL | async fn drop(self: Pin<&mut Self>) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #126482 for more information + = help: add `#![feature(async_drop)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: use of unstable library feature `async_drop` + --> $DIR/feature-gate-async-drop.rs:12:6 + | +LL | impl AsyncDrop for Foo { + | ^^^^^^^^^ + | + = note: see issue #126482 for more information + = help: add `#![feature(async_drop)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0658`. -- cgit 1.4.1-3-g733a5 From ce6a066339c6cd5c3bd6478d297cbb8076710e84 Mon Sep 17 00:00:00 2001 From: Laurențiu Nicola Date: Mon, 28 Apr 2025 14:16:43 +0300 Subject: Unelide lifetime --- src/tools/rust-analyzer/crates/query-group-macro/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/tools') diff --git a/src/tools/rust-analyzer/crates/query-group-macro/src/lib.rs b/src/tools/rust-analyzer/crates/query-group-macro/src/lib.rs index 3ade12733a7..f4f316c1ac1 100644 --- a/src/tools/rust-analyzer/crates/query-group-macro/src/lib.rs +++ b/src/tools/rust-analyzer/crates/query-group-macro/src/lib.rs @@ -159,7 +159,7 @@ impl Parse for Cycle { } impl Parse for Option { - fn parse(input: ParseStream) -> syn::Result { + fn parse(input: ParseStream<'_>) -> syn::Result { let name = input.parse()?; input.parse::()?; let value = input.parse()?; -- cgit 1.4.1-3-g733a5 From cbfc3640b047ebde1beb11629508597f960596ad Mon Sep 17 00:00:00 2001 From: Zalathar Date: Mon, 28 Apr 2025 21:14:37 +1000 Subject: compiletest: Remove the libtest-based executor and its dependency This patch has deliberately been kept small and simple, to make it easier to revert if necessary. Further cleanup can take palce after we're confident that it won't need to be reverted. --- src/bootstrap/src/core/build_steps/tool.rs | 2 +- src/tools/compiletest/src/common.rs | 8 -- src/tools/compiletest/src/executor.rs | 1 - src/tools/compiletest/src/executor/libtest.rs | 111 -------------------------- src/tools/compiletest/src/lib.rs | 19 ++--- 5 files changed, 8 insertions(+), 133 deletions(-) delete mode 100644 src/tools/compiletest/src/executor/libtest.rs (limited to 'src/tools') diff --git a/src/bootstrap/src/core/build_steps/tool.rs b/src/bootstrap/src/core/build_steps/tool.rs index 1549d4713af..ac568eab2e8 100644 --- a/src/bootstrap/src/core/build_steps/tool.rs +++ b/src/bootstrap/src/core/build_steps/tool.rs @@ -462,7 +462,7 @@ macro_rules! bootstrap_tool { } } -pub(crate) const COMPILETEST_ALLOW_FEATURES: &str = "test,internal_output_capture"; +pub(crate) const COMPILETEST_ALLOW_FEATURES: &str = "internal_output_capture"; bootstrap_tool!( // This is marked as an external tool because it includes dependencies diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs index e0132056d6c..4f93b498741 100644 --- a/src/tools/compiletest/src/common.rs +++ b/src/tools/compiletest/src/common.rs @@ -413,14 +413,6 @@ pub struct Config { /// cross-compilation scenarios that do not otherwise want/need to `-Zbuild-std`. Used in e.g. /// ABI tests. pub minicore_path: Utf8PathBuf, - - /// If true, disable the "new" executor, and use the older libtest-based - /// executor to run tests instead. This is a temporary fallback, to make - /// manual comparative testing easier if bugs are found in the new executor. - /// - /// FIXME(Zalathar): Eventually remove this flag and remove the libtest - /// dependency. - pub no_new_executor: bool, } impl Config { diff --git a/src/tools/compiletest/src/executor.rs b/src/tools/compiletest/src/executor.rs index 990be56ce0c..e774c5e2047 100644 --- a/src/tools/compiletest/src/executor.rs +++ b/src/tools/compiletest/src/executor.rs @@ -12,7 +12,6 @@ use crate::common::{Config, TestPaths}; mod deadline; mod json; -pub(crate) mod libtest; pub(crate) fn run_tests(config: &Config, tests: Vec) -> bool { let tests_len = tests.len(); diff --git a/src/tools/compiletest/src/executor/libtest.rs b/src/tools/compiletest/src/executor/libtest.rs deleted file mode 100644 index 032b3f4fa9a..00000000000 --- a/src/tools/compiletest/src/executor/libtest.rs +++ /dev/null @@ -1,111 +0,0 @@ -//! This submodule encapsulates all of the code that actually interacts with -//! libtest, so that it can be easily removed after the new executor becomes -//! the default. - -use std::borrow::Cow; -use std::io; - -use crate::common::Config; -use crate::executor::{CollectedTest, CollectedTestDesc, ColorConfig, OutputFormat, ShouldPanic}; - -/// Delegates to libtest to run the list of collected tests. -/// -/// Returns `Ok(true)` if all tests passed, or `Ok(false)` if one or more tests failed. -pub(crate) fn execute_tests(config: &Config, tests: Vec) -> io::Result { - let opts = test_opts(config); - let tests = tests.into_iter().map(|t| t.into_libtest()).collect::>(); - - test::run_tests_console(&opts, tests) -} - -impl CollectedTest { - fn into_libtest(self) -> test::TestDescAndFn { - let Self { desc, config, testpaths, revision } = self; - let CollectedTestDesc { name, ignore, ignore_message, should_panic } = desc; - - // Libtest requires the ignore message to be a &'static str, so we might - // have to leak memory to create it. This is fine, as we only do so once - // per test, so the leak won't grow indefinitely. - let ignore_message = ignore_message.map(|msg| match msg { - Cow::Borrowed(s) => s, - Cow::Owned(s) => &*String::leak(s), - }); - - let desc = test::TestDesc { - name: test::DynTestName(name), - ignore, - ignore_message, - source_file: "", - start_line: 0, - start_col: 0, - end_line: 0, - end_col: 0, - should_panic: should_panic.to_libtest(), - compile_fail: false, - no_run: false, - test_type: test::TestType::Unknown, - }; - - // This closure is invoked when libtest returns control to compiletest - // to execute the test. - let testfn = test::DynTestFn(Box::new(move || { - crate::runtest::run(config, &testpaths, revision.as_deref()); - Ok(()) - })); - - test::TestDescAndFn { desc, testfn } - } -} - -impl ColorConfig { - fn to_libtest(self) -> test::ColorConfig { - match self { - Self::AutoColor => test::ColorConfig::AutoColor, - Self::AlwaysColor => test::ColorConfig::AlwaysColor, - Self::NeverColor => test::ColorConfig::NeverColor, - } - } -} - -impl OutputFormat { - fn to_libtest(self) -> test::OutputFormat { - match self { - Self::Pretty => test::OutputFormat::Pretty, - Self::Terse => test::OutputFormat::Terse, - Self::Json => test::OutputFormat::Json, - } - } -} - -impl ShouldPanic { - fn to_libtest(self) -> test::ShouldPanic { - match self { - Self::No => test::ShouldPanic::No, - Self::Yes => test::ShouldPanic::Yes, - } - } -} - -fn test_opts(config: &Config) -> test::TestOpts { - test::TestOpts { - exclude_should_panic: false, - filters: config.filters.clone(), - filter_exact: config.filter_exact, - run_ignored: if config.run_ignored { test::RunIgnored::Yes } else { test::RunIgnored::No }, - format: config.format.to_libtest(), - logfile: None, - run_tests: true, - bench_benchmarks: true, - nocapture: config.nocapture, - color: config.color.to_libtest(), - shuffle: false, - shuffle_seed: None, - test_threads: None, - skip: config.skip.clone(), - list: false, - options: test::Options::new(), - time_options: None, - force_run_in_process: false, - fail_fast: config.fail_fast, - } -} diff --git a/src/tools/compiletest/src/lib.rs b/src/tools/compiletest/src/lib.rs index 788bafaa724..0db4d3f6a41 100644 --- a/src/tools/compiletest/src/lib.rs +++ b/src/tools/compiletest/src/lib.rs @@ -1,11 +1,10 @@ #![crate_name = "compiletest"] -// Needed by the libtest-based test executor. -#![feature(test)] // Needed by the "new" test executor that does not depend on libtest. +// FIXME(Zalathar): We should be able to get rid of `internal_output_capture`, +// by having `runtest` manually capture all of its println-like output instead. +// That would result in compiletest being written entirely in stable Rust! #![feature(internal_output_capture)] -extern crate test; - #[cfg(test)] mod tests; @@ -448,8 +447,6 @@ pub fn parse_config(args: Vec) -> Config { diff_command: matches.opt_str("compiletest-diff-tool"), minicore_path: opt_path(matches, "minicore-path"), - - no_new_executor: matches.opt_present("no-new-executor"), } } @@ -576,12 +573,10 @@ pub fn run_tests(config: Arc) { // Delegate to the executor to filter and run the big list of test structures // created during test discovery. When the executor decides to run a test, // it will return control to the rest of compiletest by calling `runtest::run`. - let res = if !config.no_new_executor { - Ok(executor::run_tests(&config, tests)) - } else { - // FIXME(Zalathar): Eventually remove the libtest executor entirely. - crate::executor::libtest::execute_tests(&config, tests) - }; + // FIXME(Zalathar): Once we're confident that we won't need to revert the + // removal of the libtest-based executor, remove this Result and other + // remnants of the old executor. + let res: io::Result = Ok(executor::run_tests(&config, tests)); // Check the outcome reported by libtest. match res { -- cgit 1.4.1-3-g733a5 From 7953c9dda43674121dfb253afc4aade280243f07 Mon Sep 17 00:00:00 2001 From: The Miri Cronjob Bot Date: Tue, 29 Apr 2025 06:16:28 +0000 Subject: Preparing for merge from rustc --- src/tools/miri/rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/tools') diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version index 1ecaf8675c2..59d53891217 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -555e1d0386f024a8359645c3217f4b3eae9be042 +1b8ab72680f36e783af84c1a3c4f8508572bd9f9 -- cgit 1.4.1-3-g733a5 From c2973c949d52b6a577721b4626e3e005e2dbaabf Mon Sep 17 00:00:00 2001 From: The Miri Cronjob Bot Date: Tue, 29 Apr 2025 06:25:01 +0000 Subject: fmt --- src/tools/miri/tests/pass/async-drop.rs | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) (limited to 'src/tools') diff --git a/src/tools/miri/tests/pass/async-drop.rs b/src/tools/miri/tests/pass/async-drop.rs index 2a95f644389..4fa84384d9b 100644 --- a/src/tools/miri/tests/pass/async-drop.rs +++ b/src/tools/miri/tests/pass/async-drop.rs @@ -10,10 +10,10 @@ #![allow(incomplete_features, dead_code)] // FIXME(zetanumbers): consider AsyncDestruct::async_drop cleanup tests -use core::future::{async_drop_in_place, AsyncDrop, Future}; +use core::future::{AsyncDrop, Future, async_drop_in_place}; use core::hint::black_box; use core::mem::{self, ManuallyDrop}; -use core::pin::{pin, Pin}; +use core::pin::{Pin, pin}; use core::task::{Context, Poll, Waker}; async fn test_async_drop(x: T) { @@ -200,11 +200,7 @@ union AsyncUnion { impl Drop for AsyncUnion { fn drop(&mut self) { - println!( - "AsyncUnion::drop: {}, {}", - unsafe { self.signed }, - unsafe { self.unsigned }, - ); + println!("AsyncUnion::drop: {}, {}", unsafe { self.signed }, unsafe { self.unsigned },); } } impl AsyncDrop for AsyncUnion { -- cgit 1.4.1-3-g733a5 From 0917a072641fb50866fed781af4745321d9e0373 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 29 Apr 2025 08:53:22 +0200 Subject: suppress dangerous_implicit_autorefs in TB test --- src/tools/miri/tests/pass/tree_borrows/interior_mutability.rs | 1 + 1 file changed, 1 insertion(+) (limited to 'src/tools') diff --git a/src/tools/miri/tests/pass/tree_borrows/interior_mutability.rs b/src/tools/miri/tests/pass/tree_borrows/interior_mutability.rs index 752ae4b20c5..6dde593d2cf 100644 --- a/src/tools/miri/tests/pass/tree_borrows/interior_mutability.rs +++ b/src/tools/miri/tests/pass/tree_borrows/interior_mutability.rs @@ -1,6 +1,7 @@ //@revisions: default uniq //@compile-flags: -Zmiri-tree-borrows //@[uniq]compile-flags: -Zmiri-unique-is-unique +#![allow(dangerous_implicit_autorefs)] use std::cell::{Cell, Ref, RefCell, RefMut, UnsafeCell}; use std::mem::{self, MaybeUninit}; -- cgit 1.4.1-3-g733a5 From 2393e447eba2edf86c90812a78b78b37a5374f6b Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 29 Apr 2025 11:03:30 +0200 Subject: miri: algebraic intrinsics: bring back float non-determinism --- .../rustc_const_eval/src/interpret/intrinsics.rs | 3 +- compiler/rustc_const_eval/src/interpret/machine.rs | 8 ++ src/tools/miri/src/intrinsics/mod.rs | 27 +---- src/tools/miri/src/machine.rs | 10 ++ src/tools/miri/src/math.rs | 26 +++++ src/tools/miri/tests/pass/float.rs | 119 +++++++++++---------- 6 files changed, 107 insertions(+), 86 deletions(-) (limited to 'src/tools') diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs index 40c63f2b250..63043de9739 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs @@ -178,8 +178,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { let res = self.binary_op(op, &a, &b)?; // `binary_op` already called `generate_nan` if needed. - - // FIXME: Miri should add some non-determinism to the result here to catch any dependences on exact computations. This has previously been done, but the behaviour was removed as part of constification. + let res = M::apply_float_nondet(self, res)?; self.write_immediate(*res, dest)?; } diff --git a/compiler/rustc_const_eval/src/interpret/machine.rs b/compiler/rustc_const_eval/src/interpret/machine.rs index e5026eff21f..a1386b4e1be 100644 --- a/compiler/rustc_const_eval/src/interpret/machine.rs +++ b/compiler/rustc_const_eval/src/interpret/machine.rs @@ -276,6 +276,14 @@ pub trait Machine<'tcx>: Sized { F2::NAN } + /// Apply non-determinism to float operations that do not return a precise result. + fn apply_float_nondet( + _ecx: &mut InterpCx<'tcx, Self>, + val: ImmTy<'tcx, Self::Provenance>, + ) -> InterpResult<'tcx, ImmTy<'tcx, Self::Provenance>> { + interp_ok(val) + } + /// Determines the result of `min`/`max` on floats when the arguments are equal. fn equal_float_min_max(_ecx: &InterpCx<'tcx, Self>, a: F, _b: F) -> F { // By default, we pick the left argument. diff --git a/src/tools/miri/src/intrinsics/mod.rs b/src/tools/miri/src/intrinsics/mod.rs index 7d60a7e5c48..3334c0b5edf 100644 --- a/src/tools/miri/src/intrinsics/mod.rs +++ b/src/tools/miri/src/intrinsics/mod.rs @@ -7,13 +7,13 @@ use rand::Rng; use rustc_abi::Size; use rustc_apfloat::{Float, Round}; use rustc_middle::mir; -use rustc_middle::ty::{self, FloatTy, ScalarInt}; +use rustc_middle::ty::{self, FloatTy}; use rustc_span::{Symbol, sym}; use self::atomic::EvalContextExt as _; use self::helpers::{ToHost, ToSoft, check_intrinsic_arg_count}; use self::simd::EvalContextExt as _; -use crate::math::apply_random_float_error_ulp; +use crate::math::apply_random_float_error_to_imm; use crate::*; impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {} @@ -473,26 +473,3 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { interp_ok(EmulateItemResult::NeedsReturn) } } - -/// Applies a random 16ULP floating point error to `val` and returns the new value. -/// Will fail if `val` is not a floating point number. -fn apply_random_float_error_to_imm<'tcx>( - ecx: &mut MiriInterpCx<'tcx>, - val: ImmTy<'tcx>, - ulp_exponent: u32, -) -> InterpResult<'tcx, ImmTy<'tcx>> { - let scalar = val.to_scalar_int()?; - let res: ScalarInt = match val.layout.ty.kind() { - ty::Float(FloatTy::F16) => - apply_random_float_error_ulp(ecx, scalar.to_f16(), ulp_exponent).into(), - ty::Float(FloatTy::F32) => - apply_random_float_error_ulp(ecx, scalar.to_f32(), ulp_exponent).into(), - ty::Float(FloatTy::F64) => - apply_random_float_error_ulp(ecx, scalar.to_f64(), ulp_exponent).into(), - ty::Float(FloatTy::F128) => - apply_random_float_error_ulp(ecx, scalar.to_f128(), ulp_exponent).into(), - _ => bug!("intrinsic called with non-float input type"), - }; - - interp_ok(ImmTy::from_scalar_int(res, val.layout)) -} diff --git a/src/tools/miri/src/machine.rs b/src/tools/miri/src/machine.rs index ea59d327be8..10b288882ce 100644 --- a/src/tools/miri/src/machine.rs +++ b/src/tools/miri/src/machine.rs @@ -1199,6 +1199,16 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> { ecx.generate_nan(inputs) } + #[inline(always)] + fn apply_float_nondet( + ecx: &mut InterpCx<'tcx, Self>, + val: ImmTy<'tcx>, + ) -> InterpResult<'tcx, ImmTy<'tcx>> { + crate::math::apply_random_float_error_to_imm( + ecx, val, 2 /* log2(4) */ + ) + } + #[inline(always)] fn equal_float_min_max(ecx: &MiriInterpCx<'tcx>, a: F, b: F) -> F { ecx.equal_float_min_max(a, b) diff --git a/src/tools/miri/src/math.rs b/src/tools/miri/src/math.rs index fdd021f8539..2ff29c7ac1a 100644 --- a/src/tools/miri/src/math.rs +++ b/src/tools/miri/src/math.rs @@ -1,6 +1,9 @@ use rand::Rng as _; use rustc_apfloat::Float as _; use rustc_apfloat::ieee::IeeeFloat; +use rustc_middle::ty::{self, FloatTy, ScalarInt}; + +use crate::*; /// Disturbes a floating-point result by a relative error in the range (-2^scale, 2^scale). /// @@ -43,6 +46,29 @@ pub(crate) fn apply_random_float_error_ulp( apply_random_float_error(ecx, val, err_scale) } +/// Applies a random 16ULP floating point error to `val` and returns the new value. +/// Will fail if `val` is not a floating point number. +pub(crate) fn apply_random_float_error_to_imm<'tcx>( + ecx: &mut MiriInterpCx<'tcx>, + val: ImmTy<'tcx>, + ulp_exponent: u32, +) -> InterpResult<'tcx, ImmTy<'tcx>> { + let scalar = val.to_scalar_int()?; + let res: ScalarInt = match val.layout.ty.kind() { + ty::Float(FloatTy::F16) => + apply_random_float_error_ulp(ecx, scalar.to_f16(), ulp_exponent).into(), + ty::Float(FloatTy::F32) => + apply_random_float_error_ulp(ecx, scalar.to_f32(), ulp_exponent).into(), + ty::Float(FloatTy::F64) => + apply_random_float_error_ulp(ecx, scalar.to_f64(), ulp_exponent).into(), + ty::Float(FloatTy::F128) => + apply_random_float_error_ulp(ecx, scalar.to_f128(), ulp_exponent).into(), + _ => bug!("intrinsic called with non-float input type"), + }; + + interp_ok(ImmTy::from_scalar_int(res, val.layout)) +} + pub(crate) fn sqrt(x: IeeeFloat) -> IeeeFloat { match x.category() { // preserve zero sign diff --git a/src/tools/miri/tests/pass/float.rs b/src/tools/miri/tests/pass/float.rs index 575d70579a4..98a88cfd62d 100644 --- a/src/tools/miri/tests/pass/float.rs +++ b/src/tools/miri/tests/pass/float.rs @@ -1292,8 +1292,7 @@ fn test_non_determinism() { } } // We saw the same thing N times. - // FIXME: temporarily disabled as it breaks std tests. - //panic!("expected non-determinism, got {rounds} times the same result: {first:?}"); + panic!("expected non-determinism, got {rounds} times the same result: {first:?}"); } macro_rules! test_operations_f { @@ -1319,66 +1318,68 @@ fn test_non_determinism() { } pub fn test_operations_f32(a: f32, b: f32) { test_operations_f!(a, b); - ensure_nondet(|| a.log(b)); - ensure_nondet(|| a.exp()); - ensure_nondet(|| 10f32.exp2()); - ensure_nondet(|| f32::consts::E.ln()); - ensure_nondet(|| 1f32.ln_1p()); - ensure_nondet(|| 10f32.log10()); - ensure_nondet(|| 8f32.log2()); - ensure_nondet(|| 27.0f32.cbrt()); - ensure_nondet(|| 3.0f32.hypot(4.0f32)); - ensure_nondet(|| 1f32.sin()); - ensure_nondet(|| 0f32.cos()); - // On i686-pc-windows-msvc , these functions are implemented by calling the `f64` version, - // which means the little rounding errors Miri introduces are discard by the cast down to `f32`. - // Just skip the test for them. - if !cfg!(all(target_os = "windows", target_env = "msvc", target_arch = "x86")) { - ensure_nondet(|| 1.0f32.tan()); - ensure_nondet(|| 1.0f32.asin()); - ensure_nondet(|| 5.0f32.acos()); - ensure_nondet(|| 1.0f32.atan()); - ensure_nondet(|| 1.0f32.atan2(2.0f32)); - ensure_nondet(|| 1.0f32.sinh()); - ensure_nondet(|| 1.0f32.cosh()); - ensure_nondet(|| 1.0f32.tanh()); - } - ensure_nondet(|| 1.0f32.asinh()); - ensure_nondet(|| 2.0f32.acosh()); - ensure_nondet(|| 0.5f32.atanh()); - ensure_nondet(|| 5.0f32.gamma()); - ensure_nondet(|| 5.0f32.ln_gamma()); - ensure_nondet(|| 5.0f32.erf()); - ensure_nondet(|| 5.0f32.erfc()); + // FIXME: temporarily disabled as it breaks std tests. + // ensure_nondet(|| a.log(b)); + // ensure_nondet(|| a.exp()); + // ensure_nondet(|| 10f32.exp2()); + // ensure_nondet(|| f32::consts::E.ln()); + // ensure_nondet(|| 1f32.ln_1p()); + // ensure_nondet(|| 10f32.log10()); + // ensure_nondet(|| 8f32.log2()); + // ensure_nondet(|| 27.0f32.cbrt()); + // ensure_nondet(|| 3.0f32.hypot(4.0f32)); + // ensure_nondet(|| 1f32.sin()); + // ensure_nondet(|| 0f32.cos()); + // // On i686-pc-windows-msvc , these functions are implemented by calling the `f64` version, + // // which means the little rounding errors Miri introduces are discard by the cast down to `f32`. + // // Just skip the test for them. + // if !cfg!(all(target_os = "windows", target_env = "msvc", target_arch = "x86")) { + // ensure_nondet(|| 1.0f32.tan()); + // ensure_nondet(|| 1.0f32.asin()); + // ensure_nondet(|| 5.0f32.acos()); + // ensure_nondet(|| 1.0f32.atan()); + // ensure_nondet(|| 1.0f32.atan2(2.0f32)); + // ensure_nondet(|| 1.0f32.sinh()); + // ensure_nondet(|| 1.0f32.cosh()); + // ensure_nondet(|| 1.0f32.tanh()); + // } + // ensure_nondet(|| 1.0f32.asinh()); + // ensure_nondet(|| 2.0f32.acosh()); + // ensure_nondet(|| 0.5f32.atanh()); + // ensure_nondet(|| 5.0f32.gamma()); + // ensure_nondet(|| 5.0f32.ln_gamma()); + // ensure_nondet(|| 5.0f32.erf()); + // ensure_nondet(|| 5.0f32.erfc()); } pub fn test_operations_f64(a: f64, b: f64) { test_operations_f!(a, b); - ensure_nondet(|| a.log(b)); - ensure_nondet(|| a.exp()); - ensure_nondet(|| 50f64.exp2()); - ensure_nondet(|| 3f64.ln()); - ensure_nondet(|| 1f64.ln_1p()); - ensure_nondet(|| f64::consts::E.log10()); - ensure_nondet(|| f64::consts::E.log2()); - ensure_nondet(|| 27.0f64.cbrt()); - ensure_nondet(|| 3.0f64.hypot(4.0f64)); - ensure_nondet(|| 1f64.sin()); - ensure_nondet(|| 0f64.cos()); - ensure_nondet(|| 1.0f64.tan()); - ensure_nondet(|| 1.0f64.asin()); - ensure_nondet(|| 5.0f64.acos()); - ensure_nondet(|| 1.0f64.atan()); - ensure_nondet(|| 1.0f64.atan2(2.0f64)); - ensure_nondet(|| 1.0f64.sinh()); - ensure_nondet(|| 1.0f64.cosh()); - ensure_nondet(|| 1.0f64.tanh()); - ensure_nondet(|| 1.0f64.asinh()); - ensure_nondet(|| 3.0f64.acosh()); - ensure_nondet(|| 0.5f64.atanh()); - ensure_nondet(|| 5.0f64.gamma()); - ensure_nondet(|| 5.0f64.ln_gamma()); - ensure_nondet(|| 5.0f64.erf()); - ensure_nondet(|| 5.0f64.erfc()); + // FIXME: temporarily disabled as it breaks std tests. + // ensure_nondet(|| a.log(b)); + // ensure_nondet(|| a.exp()); + // ensure_nondet(|| 50f64.exp2()); + // ensure_nondet(|| 3f64.ln()); + // ensure_nondet(|| 1f64.ln_1p()); + // ensure_nondet(|| f64::consts::E.log10()); + // ensure_nondet(|| f64::consts::E.log2()); + // ensure_nondet(|| 27.0f64.cbrt()); + // ensure_nondet(|| 3.0f64.hypot(4.0f64)); + // ensure_nondet(|| 1f64.sin()); + // ensure_nondet(|| 0f64.cos()); + // ensure_nondet(|| 1.0f64.tan()); + // ensure_nondet(|| 1.0f64.asin()); + // ensure_nondet(|| 5.0f64.acos()); + // ensure_nondet(|| 1.0f64.atan()); + // ensure_nondet(|| 1.0f64.atan2(2.0f64)); + // ensure_nondet(|| 1.0f64.sinh()); + // ensure_nondet(|| 1.0f64.cosh()); + // ensure_nondet(|| 1.0f64.tanh()); + // ensure_nondet(|| 1.0f64.asinh()); + // ensure_nondet(|| 3.0f64.acosh()); + // ensure_nondet(|| 0.5f64.atanh()); + // ensure_nondet(|| 5.0f64.gamma()); + // ensure_nondet(|| 5.0f64.ln_gamma()); + // ensure_nondet(|| 5.0f64.erf()); + // ensure_nondet(|| 5.0f64.erfc()); } pub fn test_operations_f128(a: f128, b: f128) { test_operations_f!(a, b); -- cgit 1.4.1-3-g733a5 From a4ce307c0137dca593e2eaa982ee413c7ba03525 Mon Sep 17 00:00:00 2001 From: mejrs <59372212+mejrs@users.noreply.github.com> Date: Tue, 29 Apr 2025 12:46:26 +0200 Subject: Coalesce duplicate missing clone tests --- src/tools/tidy/src/issues.txt | 1 - src/tools/tidy/src/ui_tests.rs | 2 +- tests/ui/issues/issue-2823.rs | 14 -------------- tests/ui/issues/issue-2823.stderr | 16 ---------------- tests/ui/methods/clone-missing.rs | 33 +++++++++++++++++++++++--------- tests/ui/methods/clone-missing.stderr | 25 ++++++++++++++++++------ tests/ui/noncopyable-class.rs | 36 ----------------------------------- tests/ui/noncopyable-class.stderr | 16 ---------------- 8 files changed, 44 insertions(+), 99 deletions(-) delete mode 100644 tests/ui/issues/issue-2823.rs delete mode 100644 tests/ui/issues/issue-2823.stderr delete mode 100644 tests/ui/noncopyable-class.rs delete mode 100644 tests/ui/noncopyable-class.stderr (limited to 'src/tools') diff --git a/src/tools/tidy/src/issues.txt b/src/tools/tidy/src/issues.txt index f1ce3ccda04..e6b5aa59622 100644 --- a/src/tools/tidy/src/issues.txt +++ b/src/tools/tidy/src/issues.txt @@ -1979,7 +1979,6 @@ ui/issues/issue-27997.rs ui/issues/issue-28105.rs ui/issues/issue-28109.rs ui/issues/issue-28181.rs -ui/issues/issue-2823.rs ui/issues/issue-28279.rs ui/issues/issue-28344.rs ui/issues/issue-28433.rs diff --git a/src/tools/tidy/src/ui_tests.rs b/src/tools/tidy/src/ui_tests.rs index 2e069af23d6..44dd1e50f5b 100644 --- a/src/tools/tidy/src/ui_tests.rs +++ b/src/tools/tidy/src/ui_tests.rs @@ -17,7 +17,7 @@ use ignore::Walk; const ENTRY_LIMIT: u32 = 901; // FIXME: The following limits should be reduced eventually. -const ISSUES_ENTRY_LIMIT: u32 = 1626; +const ISSUES_ENTRY_LIMIT: u32 = 1624; const EXPECTED_TEST_FILE_EXTENSIONS: &[&str] = &[ "rs", // test source files diff --git a/tests/ui/issues/issue-2823.rs b/tests/ui/issues/issue-2823.rs deleted file mode 100644 index 7b443b41526..00000000000 --- a/tests/ui/issues/issue-2823.rs +++ /dev/null @@ -1,14 +0,0 @@ -struct C { - x: isize, -} - -impl Drop for C { - fn drop(&mut self) { - println!("dropping: {}", self.x); - } -} - -fn main() { - let c = C{ x: 2}; - let _d = c.clone(); //~ ERROR no method named `clone` found -} diff --git a/tests/ui/issues/issue-2823.stderr b/tests/ui/issues/issue-2823.stderr deleted file mode 100644 index 5cd3f080450..00000000000 --- a/tests/ui/issues/issue-2823.stderr +++ /dev/null @@ -1,16 +0,0 @@ -error[E0599]: no method named `clone` found for struct `C` in the current scope - --> $DIR/issue-2823.rs:13:16 - | -LL | struct C { - | -------- method `clone` not found for this struct -... -LL | let _d = c.clone(); - | ^^^^^ method not found in `C` - | - = help: items from traits can only be used if the trait is implemented and in scope - = note: the following trait defines an item `clone`, perhaps you need to implement it: - candidate #1: `Clone` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0599`. diff --git a/tests/ui/methods/clone-missing.rs b/tests/ui/methods/clone-missing.rs index f2e4ad268c6..c5ecd3f175e 100644 --- a/tests/ui/methods/clone-missing.rs +++ b/tests/ui/methods/clone-missing.rs @@ -1,19 +1,34 @@ -// This test checks that calling `.clone()` on a type that does not implement the `Clone` trait -// results in a compilation error. The `Foo` struct does not derive or implement `Clone`, -// so attempting to clone it should fail. +//! This test checks that calling `.clone()` on a type that does +//! not implement the `Clone` trait results in a compilation error. +//! The `NotClone` and AlsoNotClone structs do not derive or +//! implement `Clone`, so attempting to clone them should fail. -struct Foo { - i: isize, +struct NotClone { + i: isize, } -fn foo(i:isize) -> Foo { - Foo { - i: i +fn not_clone(i: isize) -> NotClone { + NotClone { i } +} + +struct AlsoNotClone { + i: isize, + j: NotClone, +} + +fn also_not_clone(i: isize) -> AlsoNotClone { + AlsoNotClone { + i, + j: NotClone { i: i }, } } fn main() { - let x = foo(10); + let x = not_clone(10); + let _y = x.clone(); + //~^ ERROR no method named `clone` found + + let x = also_not_clone(10); let _y = x.clone(); //~^ ERROR no method named `clone` found } diff --git a/tests/ui/methods/clone-missing.stderr b/tests/ui/methods/clone-missing.stderr index 4ab1aae4934..8676e73c8ca 100644 --- a/tests/ui/methods/clone-missing.stderr +++ b/tests/ui/methods/clone-missing.stderr @@ -1,16 +1,29 @@ -error[E0599]: no method named `clone` found for struct `Foo` in the current scope - --> $DIR/clone-missing.rs:17:16 +error[E0599]: no method named `clone` found for struct `NotClone` in the current scope + --> $DIR/clone-missing.rs:28:16 | -LL | struct Foo { - | ---------- method `clone` not found for this struct +LL | struct NotClone { + | --------------- method `clone` not found for this struct ... LL | let _y = x.clone(); - | ^^^^^ method not found in `Foo` + | ^^^^^ method not found in `NotClone` | = help: items from traits can only be used if the trait is implemented and in scope = note: the following trait defines an item `clone`, perhaps you need to implement it: candidate #1: `Clone` -error: aborting due to 1 previous error +error[E0599]: no method named `clone` found for struct `AlsoNotClone` in the current scope + --> $DIR/clone-missing.rs:32:16 + | +LL | struct AlsoNotClone { + | ------------------- method `clone` not found for this struct +... +LL | let _y = x.clone(); + | ^^^^^ method not found in `AlsoNotClone` + | + = help: items from traits can only be used if the trait is implemented and in scope + = note: the following trait defines an item `clone`, perhaps you need to implement it: + candidate #1: `Clone` + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0599`. diff --git a/tests/ui/noncopyable-class.rs b/tests/ui/noncopyable-class.rs deleted file mode 100644 index 11b6eb736e9..00000000000 --- a/tests/ui/noncopyable-class.rs +++ /dev/null @@ -1,36 +0,0 @@ -// Test that a class with a non-copyable field can't be -// copied - -#[derive(Debug)] -struct Bar { - x: isize, -} - -impl Drop for Bar { - fn drop(&mut self) {} -} - -fn bar(x:isize) -> Bar { - Bar { - x: x - } -} - -#[derive(Debug)] -struct Foo { - i: isize, - j: Bar, -} - -fn foo(i:isize) -> Foo { - Foo { - i: i, - j: bar(5) - } -} - -fn main() { - let x = foo(10); - let _y = x.clone(); //~ ERROR no method named `clone` found - println!("{:?}", x); -} diff --git a/tests/ui/noncopyable-class.stderr b/tests/ui/noncopyable-class.stderr deleted file mode 100644 index b8f7276c898..00000000000 --- a/tests/ui/noncopyable-class.stderr +++ /dev/null @@ -1,16 +0,0 @@ -error[E0599]: no method named `clone` found for struct `Foo` in the current scope - --> $DIR/noncopyable-class.rs:34:16 - | -LL | struct Foo { - | ---------- method `clone` not found for this struct -... -LL | let _y = x.clone(); - | ^^^^^ method not found in `Foo` - | - = help: items from traits can only be used if the trait is implemented and in scope - = note: the following trait defines an item `clone`, perhaps you need to implement it: - candidate #1: `Clone` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0599`. -- cgit 1.4.1-3-g733a5 From 04300d84bd43714d7fdca1cb985d177914fb2a39 Mon Sep 17 00:00:00 2001 From: Caleb Cartwright Date: Tue, 29 Apr 2025 15:36:23 -0500 Subject: Also allow bool literals as first item of let chain Co-authored-by: est31 --- src/tools/rustfmt/src/pairs.rs | 14 +++++++++----- src/tools/rustfmt/tests/source/let_chains.rs | 10 +++++----- src/tools/rustfmt/tests/target/let_chains.rs | 8 +++----- 3 files changed, 17 insertions(+), 15 deletions(-) (limited to 'src/tools') diff --git a/src/tools/rustfmt/src/pairs.rs b/src/tools/rustfmt/src/pairs.rs index 9c51298416b..17ff041d775 100644 --- a/src/tools/rustfmt/src/pairs.rs +++ b/src/tools/rustfmt/src/pairs.rs @@ -1,4 +1,4 @@ -use rustc_ast::ast; +use rustc_ast::{ast, token}; use rustc_span::Span; use crate::config::IndentStyle; @@ -272,13 +272,17 @@ struct PairList<'a, 'b, T: Rewrite> { span: Span, } -fn is_ident(expr: &ast::Expr) -> bool { +fn is_ident_or_bool_lit(expr: &ast::Expr) -> bool { match &expr.kind { ast::ExprKind::Path(None, path) if path.segments.len() == 1 => true, + ast::ExprKind::Lit(token::Lit { + kind: token::LitKind::Bool, + .. + }) => true, ast::ExprKind::Unary(_, expr) | ast::ExprKind::AddrOf(_, _, expr) | ast::ExprKind::Paren(expr) - | ast::ExprKind::Try(expr) => is_ident(expr), + | ast::ExprKind::Try(expr) => is_ident_or_bool_lit(expr), _ => false, } } @@ -296,10 +300,10 @@ impl<'a, 'b> PairList<'a, 'b, ast::Expr> { return false; } - let fist_item_is_ident = is_ident(self.list[0].0); + let fist_item_is_ident_or_bool_lit = is_ident_or_bool_lit(self.list[0].0); let second_item_is_let_chain = matches!(self.list[1].0.kind, ast::ExprKind::Let(..)); - fist_item_is_ident && second_item_is_let_chain + fist_item_is_ident_or_bool_lit && second_item_is_let_chain } } diff --git a/src/tools/rustfmt/tests/source/let_chains.rs b/src/tools/rustfmt/tests/source/let_chains.rs index b7c1f811096..0c4d8aa85ea 100644 --- a/src/tools/rustfmt/tests/source/let_chains.rs +++ b/src/tools/rustfmt/tests/source/let_chains.rs @@ -20,6 +20,11 @@ fn test_single_line_let_chain() { if a && let Some(b) = foo() { } + // first item in let-chain is a bool literal + if true && let Some(x) = y { + + } + // first item in let-chain is a unary ! with an ident let unary_not = if !from_hir_call && let Some(p) = parent @@ -94,11 +99,6 @@ fn test_multi_line_let_chain() { } - // bool literal - if true && let Some(x) = y { - - } - // cast to a bool if 1 as bool && let Some(x) = y { diff --git a/src/tools/rustfmt/tests/target/let_chains.rs b/src/tools/rustfmt/tests/target/let_chains.rs index 1ceecac8abc..204937b4cac 100644 --- a/src/tools/rustfmt/tests/target/let_chains.rs +++ b/src/tools/rustfmt/tests/target/let_chains.rs @@ -50,6 +50,9 @@ fn test_single_line_let_chain() { // first item in let-chain is an ident if a && let Some(b) = foo() {} + // first item in let-chain is a bool literal + if true && let Some(x) = y {} + // first item in let-chain is a unary ! with an ident let unary_not = if !from_hir_call && let Some(p) = parent {}; @@ -102,11 +105,6 @@ fn test_multi_line_let_chain() { && let Some(x) = y {} - // bool literal - if true - && let Some(x) = y - {} - // cast to a bool if 1 as bool && let Some(x) = y -- cgit 1.4.1-3-g733a5 From 20faf8532b5ddeb636ba3078344b0cad058c8f8a Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sat, 5 Apr 2025 19:19:56 +0300 Subject: compiletest: Make diagnostic kind mandatory on line annotations --- src/doc/rustc-dev-guide/src/tests/ui.md | 6 +- src/tools/compiletest/src/errors.rs | 35 ++- src/tools/compiletest/src/header.rs | 2 +- src/tools/compiletest/src/json.rs | 8 +- src/tools/compiletest/src/runtest.rs | 22 +- src/tools/compiletest/src/runtest/ui.rs | 6 +- .../issues/ice-generic-type-alias-105742.rs | 28 +-- .../issues/ice-generic-type-alias-105742.stderr | 148 ++++++------ tests/ui/array-slice-vec/array-not-vector.rs | 10 +- tests/ui/array-slice-vec/array-not-vector.stderr | 4 +- tests/ui/array-slice-vec/slice-mut.rs | 7 +- .../associated-consts/defaults-not-assumed-fail.rs | 3 +- .../defaults-not-assumed-fail.stderr | 10 +- tests/ui/associated-types/associated-types-eq-3.rs | 8 +- .../associated-types/associated-types-eq-3.stderr | 12 +- .../ui/associated-types/associated-types-path-2.rs | 6 +- .../associated-types-path-2.stderr | 18 +- .../ui/associated-types/substs-ppaux.normal.stderr | 12 +- tests/ui/associated-types/substs-ppaux.rs | 35 ++- .../associated-types/substs-ppaux.verbose.stderr | 12 +- tests/ui/binop/shift-various-bad-types.rs | 4 +- tests/ui/binop/shift-various-bad-types.stderr | 8 +- tests/ui/blind/blind-item-item-shadow.rs | 4 +- tests/ui/blind/blind-item-item-shadow.stderr | 2 +- .../block-must-not-have-result-while.rs | 4 +- .../block-must-not-have-result-while.stderr | 4 +- tests/ui/block-result/issue-13624.rs | 6 +- tests/ui/block-result/issue-13624.stderr | 4 +- tests/ui/block-result/issue-5500.rs | 8 +- .../borrowck-report-with-custom-diagnostic.rs | 14 +- .../borrowck-report-with-custom-diagnostic.stderr | 6 +- tests/ui/borrowck/issue-81899.rs | 6 +- tests/ui/borrowck/issue-81899.stderr | 8 +- tests/ui/borrowck/issue-88434-minimal-example.rs | 6 +- .../ui/borrowck/issue-88434-minimal-example.stderr | 8 +- .../issue-88434-removal-index-should-be-less.rs | 6 +- ...issue-88434-removal-index-should-be-less.stderr | 8 +- .../ptr-to-trait-obj-different-regions-misc.rs | 3 +- .../ptr-to-trait-obj-different-regions-misc.stderr | 22 +- tests/ui/coercion/coerce-mut.rs | 8 +- tests/ui/coercion/coerce-mut.stderr | 4 +- tests/ui/coercion/coercion-slice.rs | 3 +- tests/ui/coercion/mut-mut-wont-coerce.rs | 5 +- tests/ui/coercion/mut-mut-wont-coerce.stderr | 4 +- .../const_param_ty_impl_no_structural_eq.rs | 4 +- tests/ui/const-generics/defaults/mismatch.rs | 12 +- tests/ui/const-generics/defaults/mismatch.stderr | 10 +- tests/ui/const-generics/issues/issue-100313.rs | 4 +- tests/ui/const-generics/issues/issue-100313.stderr | 4 +- .../invalid-patterns.32bit.stderr | 16 +- .../invalid-patterns.64bit.stderr | 16 +- .../min_const_generics/invalid-patterns.rs | 6 +- tests/ui/consts/const-array-oob.rs | 3 +- tests/ui/consts/const-array-oob.stderr | 2 +- tests/ui/consts/const-err-late.rs | 3 +- tests/ui/consts/const-err-late.stderr | 12 +- tests/ui/consts/const-err-multi.rs | 7 +- tests/ui/consts/const-err-multi.stderr | 6 +- .../ui/consts/const-eval/const-eval-overflow-4b.rs | 4 +- .../const-eval/const-eval-overflow-4b.stderr | 8 +- ...st-pointer-values-in-various-types.64bit.stderr | 58 ++--- .../const-pointer-values-in-various-types.rs | 5 +- .../const-eval/heap/alloc_intrinsic_errors.rs | 6 +- .../const-eval/heap/alloc_intrinsic_errors.stderr | 4 +- tests/ui/consts/const-eval/issue-44578.rs | 3 +- tests/ui/consts/const-eval/issue-44578.stderr | 10 +- .../consts/const-eval/issue-50814-2.mir-opt.stderr | 16 +- .../consts/const-eval/issue-50814-2.normal.stderr | 10 +- tests/ui/consts/const-eval/issue-50814-2.rs | 3 +- tests/ui/consts/const-eval/issue-50814.rs | 3 +- tests/ui/consts/const-eval/issue-50814.stderr | 14 +- .../ui/consts/const-eval/panic-assoc-never-type.rs | 3 +- .../const-eval/panic-assoc-never-type.stderr | 6 +- tests/ui/consts/const-eval/raw-bytes.32bit.stderr | 106 ++++----- tests/ui/consts/const-eval/raw-bytes.64bit.stderr | 106 ++++----- tests/ui/consts/const-eval/raw-bytes.rs | 26 ++- tests/ui/consts/const-eval/ub-enum.rs | 4 +- tests/ui/consts/const-eval/ub-enum.stderr | 28 +-- tests/ui/consts/const-eval/ub-incorrect-vtable.rs | 14 +- tests/ui/consts/const-eval/ub-int-array.rs | 8 +- tests/ui/consts/const-eval/ub-int-array.stderr | 6 +- tests/ui/consts/const-eval/ub-nonnull.rs | 4 +- tests/ui/consts/const-eval/ub-nonnull.stderr | 16 +- tests/ui/consts/const-eval/ub-ref-ptr.rs | 10 +- tests/ui/consts/const-eval/ub-ref-ptr.stderr | 34 +-- tests/ui/consts/const-eval/ub-uninhabit.rs | 10 +- tests/ui/consts/const-eval/ub-uninhabit.stderr | 8 +- tests/ui/consts/const-eval/ub-wide-ptr.rs | 36 +-- .../ui/consts/const-eval/union-const-eval-field.rs | 4 +- .../const-eval/union-const-eval-field.stderr | 6 +- tests/ui/consts/const-eval/union-ub.32bit.stderr | 4 +- tests/ui/consts/const-eval/union-ub.64bit.stderr | 4 +- tests/ui/consts/const-eval/union-ub.rs | 3 +- tests/ui/consts/const-eval/unwind-abort.rs | 4 +- tests/ui/consts/const-eval/unwind-abort.stderr | 4 +- .../consts/const-eval/validate_uninhabited_zsts.rs | 4 +- .../const-eval/validate_uninhabited_zsts.stderr | 6 +- .../const-len-underflow-separate-spans.next.stderr | 2 +- .../const-len-underflow-separate-spans.old.stderr | 2 +- .../consts/const-len-underflow-separate-spans.rs | 3 +- tests/ui/consts/const-mut-refs/mut_ref_in_final.rs | 3 +- .../consts/const-mut-refs/mut_ref_in_final.stderr | 22 +- .../mut_ref_in_final_dynamic_check.rs | 7 +- .../mut_ref_in_final_dynamic_check.stderr | 10 +- tests/ui/consts/const-pattern-irrefutable.rs | 16 +- tests/ui/consts/const-pattern-irrefutable.stderr | 10 +- tests/ui/consts/const-tup-index-span.rs | 3 +- tests/ui/consts/const_refs_to_static_fail.rs | 5 +- tests/ui/consts/const_refs_to_static_fail.stderr | 6 +- .../ui/consts/const_refs_to_static_fail_invalid.rs | 8 +- .../const_refs_to_static_fail_invalid.stderr | 6 +- tests/ui/consts/issue-17718-const-bad-values.rs | 3 +- .../ui/consts/issue-17718-const-bad-values.stderr | 4 +- tests/ui/consts/issue-39974.rs | 3 +- tests/ui/consts/issue-39974.stderr | 2 +- tests/ui/consts/miri_unleashed/assoc_const_2.rs | 3 +- .../ui/consts/miri_unleashed/assoc_const_2.stderr | 6 +- .../miri_unleashed/const_refers_to_static.rs | 3 +- .../miri_unleashed/const_refers_to_static.stderr | 10 +- .../const_refers_to_static_cross_crate.rs | 10 +- .../const_refers_to_static_cross_crate.stderr | 8 +- .../ui/consts/miri_unleashed/mutable_references.rs | 29 +-- .../miri_unleashed/mutable_references.stderr | 62 ++--- tests/ui/consts/offset_from_ub.rs | 24 +- tests/ui/consts/offset_from_ub.stderr | 28 +-- .../interpret-in-const-called-fn.noopt.stderr | 2 +- .../interpret-in-const-called-fn.opt.stderr | 2 +- .../interpret-in-const-called-fn.rs | 3 +- .../interpret-in-promoted.noopt.stderr | 6 +- .../interpret-in-promoted.opt.stderr | 6 +- .../required-consts/interpret-in-promoted.rs | 4 +- .../interpret-in-static.noopt.stderr | 2 +- .../required-consts/interpret-in-static.opt.stderr | 2 +- .../consts/required-consts/interpret-in-static.rs | 3 +- tests/ui/consts/uninhabited-const-issue-61744.rs | 5 +- .../ui/consts/uninhabited-const-issue-61744.stderr | 256 ++++++++++----------- .../coroutine/drop-tracking-parent-expression.rs | 8 +- .../drop-tracking-parent-expression.stderr | 24 +- tests/ui/coroutine/parent-expression.rs | 8 +- tests/ui/coroutine/parent-expression.stderr | 24 +- tests/ui/coverage-attr/bad-attr-ice.rs | 2 +- tests/ui/cross/cross-borrow-trait.rs | 6 +- tests/ui/cross/cross-borrow-trait.stderr | 2 +- tests/ui/destructure-trait-ref.rs | 14 +- tests/ui/destructure-trait-ref.stderr | 12 +- tests/ui/diagnostic-width/long-E0529.rs | 3 +- tests/ui/diagnostic-width/long-E0529.stderr | 2 +- tests/ui/diagnostic-width/long-E0618.rs | 3 +- tests/ui/diagnostic-width/long-E0618.stderr | 2 +- .../custom-on-unimplemented-diagnostic.rs | 6 +- .../custom-on-unimplemented-diagnostic.stderr | 8 +- tests/ui/dst/dst-bad-assign-3.rs | 8 +- tests/ui/dst/dst-bad-assign-3.stderr | 4 +- tests/ui/dst/dst-bad-assign.rs | 8 +- tests/ui/dst/dst-bad-assign.stderr | 4 +- tests/ui/dst/dst-bad-coerce4.rs | 7 +- tests/ui/empty/empty-never-array.rs | 4 +- tests/ui/empty/empty-never-array.stderr | 4 +- .../ui/enum-discriminant/discriminant-overflow.rs | 13 +- .../enum-discriminant/discriminant-overflow.stderr | 16 +- tests/ui/error-codes/E0080.rs | 3 +- tests/ui/error-codes/E0106.rs | 6 +- tests/ui/error-codes/E0106.stderr | 10 +- tests/ui/error-codes/E0428.rs | 4 +- tests/ui/error-codes/E0428.stderr | 2 +- .../ui/explicit/explicit-self-lifetime-mismatch.rs | 14 +- .../explicit-self-lifetime-mismatch.stderr | 12 +- tests/ui/expr/if/if-branch-types.rs | 3 +- tests/ui/expr/if/if-without-else-result.rs | 4 +- tests/ui/expr/if/if-without-else-result.stderr | 2 +- tests/ui/expr/if/issue-4201.rs | 4 +- tests/ui/expr/if/issue-4201.stderr | 2 +- .../feature-gate-cfg-target-thread-local.rs | 2 +- tests/ui/fn/fn-item-type.rs | 26 ++- tests/ui/fn/fn-item-type.stderr | 20 +- tests/ui/fn/fn-pointer-mismatch.rs | 24 +- tests/ui/fn/fn-pointer-mismatch.stderr | 12 +- tests/ui/fn/fn-trait-formatting.rs | 16 +- tests/ui/fn/fn-trait-formatting.stderr | 2 +- .../foreign/issue-91370-foreign-fn-block-impl.rs | 5 +- .../issue-91370-foreign-fn-block-impl.stderr | 4 +- .../fully-qualified-type-name2.rs | 4 +- .../fully-qualified-type-name2.stderr | 6 +- .../fully-qualified-type-name4.rs | 8 +- tests/ui/generics/generic-type-params-name-repr.rs | 38 +-- .../generics/generic-type-params-name-repr.stderr | 12 +- .../slightly-nice-generic-literal-messages.rs | 8 +- tests/ui/impl-trait/equality.rs | 4 +- tests/ui/impl-trait/equality.stderr | 6 +- tests/ui/impl-trait/equality2.rs | 18 +- tests/ui/impl-trait/equality2.stderr | 10 +- tests/ui/impl-trait/no-method-suggested-traits.rs | 6 +- .../impl-trait/no-method-suggested-traits.stderr | 60 ++--- tests/ui/implied-bounds/sod_service_chain.rs | 12 +- tests/ui/implied-bounds/sod_service_chain.stderr | 12 +- tests/ui/imports/import.rs | 6 +- tests/ui/imports/import.stderr | 8 +- tests/ui/imports/issue-19498.rs | 8 +- tests/ui/imports/issue-19498.stderr | 6 +- tests/ui/imports/issue-24081.rs | 12 +- tests/ui/imports/issue-24081.stderr | 10 +- tests/ui/imports/issue-26886.rs | 6 +- tests/ui/imports/issue-26886.stderr | 4 +- .../ui/inference/tutorial-suffix-inference-test.rs | 8 +- .../tutorial-suffix-inference-test.stderr | 12 +- tests/ui/issues/issue-13359.rs | 6 +- tests/ui/issues/issue-13359.stderr | 8 +- tests/ui/issues/issue-13466.rs | 14 +- tests/ui/issues/issue-13466.stderr | 4 +- tests/ui/issues/issue-14541.rs | 3 +- tests/ui/issues/issue-15094.rs | 5 +- tests/ui/issues/issue-15381.rs | 3 +- tests/ui/issues/issue-15783.rs | 8 +- tests/ui/issues/issue-15783.stderr | 4 +- tests/ui/issues/issue-16401.rs | 8 +- tests/ui/issues/issue-17033.rs | 3 +- tests/ui/issues/issue-17740.rs | 14 +- tests/ui/issues/issue-17740.stderr | 12 +- tests/ui/issues/issue-19991.rs | 4 +- tests/ui/issues/issue-19991.stderr | 2 +- tests/ui/issues/issue-21332.rs | 3 +- tests/ui/issues/issue-24819.rs | 4 +- tests/ui/issues/issue-24819.stderr | 4 +- tests/ui/issues/issue-27942.rs | 6 +- tests/ui/issues/issue-27942.stderr | 12 +- tests/ui/issues/issue-2951.rs | 8 +- tests/ui/issues/issue-2951.stderr | 2 +- tests/ui/issues/issue-31011.rs | 4 +- tests/ui/issues/issue-31011.stderr | 2 +- tests/ui/issues/issue-31910.rs | 5 +- tests/ui/issues/issue-31910.stderr | 2 +- tests/ui/issues/issue-3477.rs | 3 +- tests/ui/issues/issue-3680.rs | 8 +- tests/ui/issues/issue-37884.rs | 4 +- tests/ui/issues/issue-37884.stderr | 4 +- tests/ui/issues/issue-43355.rs | 4 +- tests/ui/issues/issue-43355.stderr | 2 +- tests/ui/issues/issue-4517.rs | 4 +- tests/ui/issues/issue-4517.stderr | 4 +- tests/ui/issues/issue-4935.rs | 3 +- tests/ui/issues/issue-4968.rs | 8 +- tests/ui/issues/issue-4968.stderr | 2 +- tests/ui/issues/issue-5100.rs | 33 +-- tests/ui/issues/issue-5100.stderr | 14 +- tests/ui/issues/issue-5358-1.rs | 8 +- tests/ui/issues/issue-7061.rs | 6 +- tests/ui/issues/issue-7061.stderr | 2 +- tests/ui/issues/issue-7092.rs | 8 +- tests/ui/issues/issue-7867.rs | 8 +- tests/ui/issues/issue-7867.stderr | 2 +- tests/ui/macros/issue-118786.rs | 3 +- tests/ui/macros/issue-118786.stderr | 8 +- tests/ui/macros/issue-29084.rs | 6 +- tests/ui/macros/issue-29084.stderr | 4 +- tests/ui/match/match-struct.rs | 4 +- ...ef-to-same-trait-object-with-separate-params.rs | 12 +- ...o-same-trait-object-with-separate-params.stderr | 20 +- tests/ui/methods/method-self-arg-1.rs | 10 +- tests/ui/methods/method-self-arg-1.stderr | 8 +- tests/ui/mismatched_types/issue-13033.rs | 6 +- tests/ui/mismatched_types/issue-13033.stderr | 4 +- .../ui/moves/moves-based-on-type-match-bindings.rs | 6 +- tests/ui/mut/mut-pattern-mismatched.rs | 14 +- tests/ui/mut/mut-pattern-mismatched.stderr | 4 +- tests/ui/never_type/issue-10176.rs | 8 +- tests/ui/noexporttypeexe.rs | 7 +- .../ui/numeric/integer-literal-suffix-inference.rs | 106 ++++----- .../integer-literal-suffix-inference.stderr | 208 ++++++++--------- ...arenthesized-type-arguments-ice-issue-122345.rs | 4 +- ...thesized-type-arguments-ice-issue-122345.stderr | 4 +- tests/ui/parser/do-catch-suggests-try.rs | 4 +- tests/ui/parser/do-catch-suggests-try.stderr | 4 +- tests/ui/parser/mut-patterns.rs | 9 +- tests/ui/parser/mut-patterns.stderr | 28 +-- tests/ui/parser/recover/recover-pat-exprs.rs | 4 +- tests/ui/parser/recover/recover-pat-exprs.stderr | 90 ++++---- .../ui/pattern/byte-string-mutability-mismatch.rs | 6 +- .../pattern/byte-string-mutability-mismatch.stderr | 4 +- .../deref-patterns/byte-string-type-errors.rs | 12 +- .../deref-patterns/byte-string-type-errors.stderr | 10 +- .../pattern/deref-patterns/unsatisfied-bounds.rs | 2 +- tests/ui/pattern/pattern-error-continue.rs | 6 +- tests/ui/pattern/pattern-error-continue.stderr | 12 +- .../borrowck-errors.classic2021.stderr | 8 +- .../borrowck-errors.classic2024.stderr | 14 +- .../experimental/borrowck-errors.rs | 6 +- .../experimental/borrowck-errors.stable2021.stderr | 12 +- .../borrowck-errors.structural2021.stderr | 4 +- .../borrowck-errors.structural2024.stderr | 4 +- .../experimental/mut-ref-mut.classic2024.stderr | 6 +- .../experimental/mut-ref-mut.rs | 4 +- .../experimental/mut-ref-mut.structural2024.stderr | 6 +- .../experimental/pattern-errors.classic2021.stderr | 30 +-- .../experimental/pattern-errors.classic2024.stderr | 20 +- .../experimental/pattern-errors.rs | 106 ++++----- .../experimental/pattern-errors.stable2021.stderr | 48 ++-- .../pattern-errors.structural2021.stderr | 44 ++-- .../pattern-errors.structural2024.stderr | 38 +-- ...ef-binding-on-inh-ref-errors.classic2021.stderr | 2 +- ...ef-binding-on-inh-ref-errors.classic2024.stderr | 20 +- .../experimental/ref-binding-on-inh-ref-errors.rs | 8 +- ...ref-binding-on-inh-ref-errors.stable2021.stderr | 6 +- ...binding-on-inh-ref-errors.structural2021.stderr | 2 +- ...binding-on-inh-ref-errors.structural2024.stderr | 46 ++-- .../well-typed-edition-2024.classic2021.stderr | 16 +- .../experimental/well-typed-edition-2024.rs | 44 ++-- .../well-typed-edition-2024.stable2021.stderr | 44 ++-- .../well-typed-edition-2024.structural2021.stderr | 16 +- tests/ui/pattern/usefulness/issue-31561.rs | 4 +- tests/ui/pattern/usefulness/issue-31561.stderr | 4 +- tests/ui/pattern/usefulness/issue-39362.rs | 4 +- tests/ui/pattern/usefulness/issue-39362.stderr | 4 +- tests/ui/pattern/usefulness/issue-72377.rs | 3 +- .../pattern/usefulness/refutable-pattern-errors.rs | 6 +- .../usefulness/refutable-pattern-errors.stderr | 4 +- .../usefulness/refutable-pattern-in-fn-arg.rs | 3 +- tests/ui/pptypedef.rs | 6 +- tests/ui/pptypedef.stderr | 4 +- tests/ui/privacy/privacy2.rs | 3 +- tests/ui/privacy/privacy2.stderr | 16 +- tests/ui/ptr-coercion.rs | 20 +- tests/ui/ptr-coercion.stderr | 6 +- tests/ui/recursion_limit/empty.rs | 5 +- tests/ui/recursion_limit/invalid_digit.rs | 5 +- tests/ui/recursion_limit/overflow.rs | 5 +- tests/ui/repeat-expr/repeat_count.rs | 18 +- tests/ui/repeat-expr/repeat_count.stderr | 18 +- tests/ui/resolve/issue-23716.rs | 6 +- tests/ui/resolve/issue-23716.stderr | 4 +- tests/ui/resolve/issue-5035.rs | 4 +- tests/ui/resolve/issue-5035.stderr | 4 +- .../ui/resolve/resolve-conflict-item-vs-import.rs | 6 +- .../enum_same_crate_empty_match.rs | 14 +- .../enum_same_crate_empty_match.stderr | 12 +- .../rfc-2008-non-exhaustive/omitted-patterns.rs | 10 +- .../omitted-patterns.stderr | 40 ++-- tests/ui/simd/const-err-trumps-simd-err.rs | 4 +- tests/ui/simd/const-err-trumps-simd-err.stderr | 6 +- tests/ui/structs/default-field-values/failures.rs | 10 +- .../structs/default-field-values/failures.stderr | 28 +-- .../structs/structure-constructor-type-mismatch.rs | 14 +- .../structure-constructor-type-mismatch.stderr | 30 +-- .../const-pat-non-exaustive-let-new-var.rs | 6 +- .../const-pat-non-exaustive-let-new-var.stderr | 2 +- tests/ui/traits/bound/same-crate-name.rs | 8 +- tests/ui/traits/bound/same-crate-name.stderr | 8 +- tests/ui/traits/impl-method-mismatch.rs | 6 +- tests/ui/traits/impl-method-mismatch.stderr | 4 +- tests/ui/tuple/tuple-arity-mismatch.rs | 14 +- tests/ui/tuple/tuple-arity-mismatch.stderr | 8 +- tests/ui/type/type-mismatch-multiple.rs | 6 +- tests/ui/type/type-mismatch-multiple.stderr | 4 +- tests/ui/type/type-parameter-names.rs | 8 +- tests/ui/type/type-parameter-names.stderr | 2 +- tests/ui/type/type-params-in-different-spaces-1.rs | 8 +- .../type/type-params-in-different-spaces-1.stderr | 2 +- tests/ui/typeck/issue-16338.rs | 4 +- tests/ui/typeck/issue-16338.stderr | 2 +- tests/ui/typeck/suppressed-error.rs | 7 +- .../ui/typeck/tag-that-dare-not-speak-its-name.rs | 7 +- tests/ui/typeck/terr-in-field.rs | 4 +- tests/ui/typeck/terr-in-field.stderr | 4 +- tests/ui/typeck/terr-sorts.rs | 6 +- tests/ui/typeck/terr-sorts.stderr | 4 +- .../ui/typeck/typeck_type_placeholder_mismatch.rs | 14 +- .../typeck/typeck_type_placeholder_mismatch.stderr | 4 +- tests/ui/typeof/type_mismatch.rs | 5 +- tests/ui/typeof/type_mismatch.stderr | 4 +- tests/ui/ufcs/ufcs-explicit-self-bad.rs | 18 +- tests/ui/unsafe/unsafe-trait-impl.rs | 6 +- tests/ui/unsafe/unsafe-trait-impl.stderr | 4 +- .../wf/range-expr-root-of-constant-issue-40749.rs | 5 +- 372 files changed, 2377 insertions(+), 2107 deletions(-) (limited to 'src/tools') diff --git a/src/doc/rustc-dev-guide/src/tests/ui.md b/src/doc/rustc-dev-guide/src/tests/ui.md index 6232c8bcc0a..b31c861c947 100644 --- a/src/doc/rustc-dev-guide/src/tests/ui.md +++ b/src/doc/rustc-dev-guide/src/tests/ui.md @@ -372,9 +372,9 @@ E.g. use `//@ dont-require-annotations: NOTE` to annotate notes selectively. Avoid using this directive for `ERROR`s and `WARN`ings, unless there's a serious reason, like target-dependent compiler output. -Missing diagnostic kinds (`//~ message`) are currently accepted, but are being phased away. -They will match any compiler output kind, but will not force exhaustive annotations for that kind. -Prefer explicit kind and `//@ dont-require-annotations` to achieve the same effect. +Some diagnostics are never required to be line-annotated, regardless of their kind or directives, +for example secondary lines of multiline diagnostics, +or ubiquitous diagnostics like `aborting due to N previous errors`. UI tests use the `-A unused` flag by default to ignore all unused warnings, as unused warnings are usually not the focus of a test. However, simple code diff --git a/src/tools/compiletest/src/errors.rs b/src/tools/compiletest/src/errors.rs index 3bb98276bf5..a45f39b036c 100644 --- a/src/tools/compiletest/src/errors.rs +++ b/src/tools/compiletest/src/errors.rs @@ -30,24 +30,20 @@ impl ErrorKind { /// Either the canonical uppercase string, or some additional versions for compatibility. /// FIXME: consider keeping only the canonical versions here. - fn from_user_str(s: &str) -> Option { - Some(match s { + pub fn from_user_str(s: &str) -> ErrorKind { + match s { "HELP" | "help" => ErrorKind::Help, "ERROR" | "error" => ErrorKind::Error, - "NOTE" | "note" => ErrorKind::Note, + // `MONO_ITEM` makes annotations in `codegen-units` tests syntactically correct, + // but those tests never use the error kind later on. + "NOTE" | "note" | "MONO_ITEM" => ErrorKind::Note, "SUGGESTION" => ErrorKind::Suggestion, "WARN" | "WARNING" | "warn" | "warning" => ErrorKind::Warning, - _ => return None, - }) - } - - pub fn expect_from_user_str(s: &str) -> ErrorKind { - ErrorKind::from_user_str(s).unwrap_or_else(|| { - panic!( + _ => panic!( "unexpected diagnostic kind `{s}`, expected \ `ERROR`, `WARN`, `NOTE`, `HELP` or `SUGGESTION`" - ) - }) + ), + } } } @@ -67,8 +63,7 @@ impl fmt::Display for ErrorKind { pub struct Error { pub line_num: Option, /// What kind of message we expect (e.g., warning, error, suggestion). - /// `None` if not specified or unknown message kind. - pub kind: Option, + pub kind: ErrorKind, pub msg: String, /// For some `Error`s, like secondary lines of multi-line diagnostics, line annotations /// are not mandatory, even if they would otherwise be mandatory for primary errors. @@ -79,12 +74,7 @@ pub struct Error { impl Error { pub fn render_for_expected(&self) -> String { use colored::Colorize; - format!( - "{: <10}line {: >3}: {}", - self.kind.map(|kind| kind.to_string()).unwrap_or_default(), - self.line_num_str(), - self.msg.cyan(), - ) + format!("{: <10}line {: >3}: {}", self.kind, self.line_num_str(), self.msg.cyan()) } pub fn line_num_str(&self) -> String { @@ -173,9 +163,10 @@ fn parse_expected( // Get the part of the comment after the sigil (e.g. `~^^` or ~|). let tag = captures.get(0).unwrap(); let rest = line[tag.end()..].trim_start(); - let (kind_str, _) = rest.split_once(|c: char| !c.is_ascii_alphabetic()).unwrap_or((rest, "")); + let (kind_str, _) = + rest.split_once(|c: char| c != '_' && !c.is_ascii_alphabetic()).unwrap_or((rest, "")); let kind = ErrorKind::from_user_str(kind_str); - let untrimmed_msg = if kind.is_some() { &rest[kind_str.len()..] } else { rest }; + let untrimmed_msg = &rest[kind_str.len()..]; let msg = untrimmed_msg.strip_prefix(':').unwrap_or(untrimmed_msg).trim().to_owned(); let line_num_adjust = &captures["adjust"]; diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs index 2b203bb309c..8bee9caacc9 100644 --- a/src/tools/compiletest/src/header.rs +++ b/src/tools/compiletest/src/header.rs @@ -593,7 +593,7 @@ impl TestProps { config.parse_name_value_directive(ln, DONT_REQUIRE_ANNOTATIONS) { self.dont_require_annotations - .insert(ErrorKind::expect_from_user_str(err_kind.trim())); + .insert(ErrorKind::from_user_str(err_kind.trim())); } }, ); diff --git a/src/tools/compiletest/src/json.rs b/src/tools/compiletest/src/json.rs index 62fe538ee32..960f5ba5888 100644 --- a/src/tools/compiletest/src/json.rs +++ b/src/tools/compiletest/src/json.rs @@ -229,7 +229,7 @@ fn push_actual_errors( // Convert multi-line messages into multiple errors. // We expect to replace these with something more structured anyhow. let mut message_lines = diagnostic.message.lines(); - let kind = Some(ErrorKind::from_compiler_str(&diagnostic.level)); + let kind = ErrorKind::from_compiler_str(&diagnostic.level); let first_line = message_lines.next().unwrap_or(&diagnostic.message); if primary_spans.is_empty() { static RE: OnceLock = OnceLock::new(); @@ -278,7 +278,7 @@ fn push_actual_errors( for (index, line) in suggested_replacement.lines().enumerate() { errors.push(Error { line_num: Some(span.line_start + index), - kind: Some(ErrorKind::Suggestion), + kind: ErrorKind::Suggestion, msg: line.to_string(), require_annotation: true, }); @@ -297,7 +297,7 @@ fn push_actual_errors( for span in spans_in_this_file.iter().filter(|span| span.label.is_some()) { errors.push(Error { line_num: Some(span.line_start), - kind: Some(ErrorKind::Note), + kind: ErrorKind::Note, msg: span.label.clone().unwrap(), require_annotation: true, }); @@ -317,7 +317,7 @@ fn push_backtrace( if Path::new(&expansion.span.file_name) == Path::new(&file_name) { errors.push(Error { line_num: Some(expansion.span.line_start), - kind: Some(ErrorKind::Note), + kind: ErrorKind::Note, msg: format!("in this expansion of {}", expansion.macro_decl_name), require_annotation: true, }); diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index fe23cce81e9..97cb82c9e36 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -675,9 +675,7 @@ impl<'test> TestCx<'test> { "check_expected_errors: expected_errors={:?} proc_res.status={:?}", expected_errors, proc_res.status ); - if proc_res.status.success() - && expected_errors.iter().any(|x| x.kind == Some(ErrorKind::Error)) - { + if proc_res.status.success() && expected_errors.iter().any(|x| x.kind == ErrorKind::Error) { self.fatal_proc_rec("process did not return an error status", proc_res); } @@ -709,7 +707,7 @@ impl<'test> TestCx<'test> { // if one of them actually occurs in the test. let expected_kinds: HashSet<_> = [ErrorKind::Error, ErrorKind::Warning] .into_iter() - .chain(expected_errors.iter().filter_map(|e| e.kind)) + .chain(expected_errors.iter().map(|e| e.kind)) .collect(); // Parse the JSON output from the compiler and extract out the messages. @@ -723,8 +721,7 @@ impl<'test> TestCx<'test> { expected_errors.iter().enumerate().position(|(index, expected_error)| { !found[index] && actual_error.line_num == expected_error.line_num - && (expected_error.kind.is_none() - || actual_error.kind == expected_error.kind) + && actual_error.kind == expected_error.kind && actual_error.msg.contains(&expected_error.msg) }); @@ -737,19 +734,14 @@ impl<'test> TestCx<'test> { None => { if actual_error.require_annotation - && actual_error.kind.map_or(false, |kind| { - expected_kinds.contains(&kind) - && !self.props.dont_require_annotations.contains(&kind) - }) + && expected_kinds.contains(&actual_error.kind) + && !self.props.dont_require_annotations.contains(&actual_error.kind) { self.error(&format!( "{}:{}: unexpected {}: '{}'", file_name, actual_error.line_num_str(), - actual_error - .kind - .as_ref() - .map_or(String::from("message"), |k| k.to_string()), + actual_error.kind, actual_error.msg )); unexpected.push(actual_error); @@ -766,7 +758,7 @@ impl<'test> TestCx<'test> { "{}:{}: expected {} not found: {}", file_name, expected_error.line_num_str(), - expected_error.kind.as_ref().map_or("message".into(), |k| k.to_string()), + expected_error.kind, expected_error.msg )); not_found.push(expected_error); diff --git a/src/tools/compiletest/src/runtest/ui.rs b/src/tools/compiletest/src/runtest/ui.rs index e87b037cd28..cf0ae14f81b 100644 --- a/src/tools/compiletest/src/runtest/ui.rs +++ b/src/tools/compiletest/src/runtest/ui.rs @@ -6,8 +6,8 @@ use rustfix::{Filter, apply_suggestions, get_suggestions_from_json}; use tracing::debug; use super::{ - AllowUnused, Emit, ErrorKind, FailMode, LinkToAux, PassMode, TargetLocation, TestCx, - TestOutput, Truncated, UI_FIXED, WillExecute, + AllowUnused, Emit, FailMode, LinkToAux, PassMode, TargetLocation, TestCx, TestOutput, + Truncated, UI_FIXED, WillExecute, }; use crate::{errors, json}; @@ -176,7 +176,7 @@ impl TestCx<'_> { let msg = format!( "line {}: cannot combine `--error-format` with {} annotations; use `error-pattern` instead", expected_errors[0].line_num_str(), - expected_errors[0].kind.unwrap_or(ErrorKind::Error), + expected_errors[0].kind, ); self.fatal(&msg); } diff --git a/tests/rustdoc-ui/issues/ice-generic-type-alias-105742.rs b/tests/rustdoc-ui/issues/ice-generic-type-alias-105742.rs index 73a68777c6d..33f3c2ff506 100644 --- a/tests/rustdoc-ui/issues/ice-generic-type-alias-105742.rs +++ b/tests/rustdoc-ui/issues/ice-generic-type-alias-105742.rs @@ -1,12 +1,14 @@ //@ compile-flags: -Znormalize-docs +//@ dont-require-annotations: NOTE + // https://github.com/rust-lang/rust/issues/105742 use std::ops::Index; pub fn next<'a, T>(s: &'a mut dyn SVec) { - //~^ expected 1 lifetime argument - //~| expected 1 generic argument + //~^ NOTE expected 1 lifetime argument + //~| NOTE expected 1 generic argument //~| ERROR the trait `SVec` is not dyn compatible - //~| `SVec` is not dyn compatible + //~| NOTE `SVec` is not dyn compatible //~| ERROR missing generics for associated type `SVec::Item` //~| ERROR missing generics for associated type `SVec::Item` let _ = s; @@ -14,8 +16,8 @@ pub fn next<'a, T>(s: &'a mut dyn SVec) { pub trait SVec: Index< ::Item, - //~^ expected 1 lifetime argument - //~| expected 1 generic argument + //~^ NOTE expected 1 lifetime argument + //~| NOTE expected 1 generic argument //~| ERROR missing generics for associated type `SVec::Item` //~| ERROR missing generics for associated type `SVec::Item` //~| ERROR missing generics for associated type `SVec::Item` @@ -25,8 +27,8 @@ pub trait SVec: Index< //~| ERROR missing generics for associated type `SVec::Item` //~| ERROR missing generics for associated type `SVec::Item` Output = ::Item, - //~^ expected 1 lifetime argument - //~| expected 1 generic argument + //~^ NOTE expected 1 lifetime argument + //~| NOTE expected 1 generic argument //~| ERROR missing generics for associated type `SVec::Item` //~| ERROR missing generics for associated type `SVec::Item` //~| ERROR missing generics for associated type `SVec::Item` @@ -36,16 +38,16 @@ pub trait SVec: Index< //~| ERROR missing generics for associated type `SVec::Item` //~| ERROR missing generics for associated type `SVec::Item` Output = ::Item> as SVec>::Item, - //~^ expected 1 lifetime argument - //~| expected 1 generic argument - //~| expected 1 lifetime argument + //~^ NOTE expected 1 lifetime argument + //~| NOTE expected 1 generic argument + //~| NOTE expected 1 lifetime argument //~| ERROR missing generics for associated type `SVec::Item` //~| ERROR missing generics for associated type `SVec::Item` //~| ERROR missing generics for associated type `SVec::Item` //~| ERROR missing generics for associated type `SVec::Item` //~| ERROR missing generics for associated type `SVec::Item` //~| ERROR missing generics for associated type `SVec::Item` - //~| expected 1 generic argument + //~| NOTE expected 1 generic argument //~| ERROR missing generics for associated type `SVec::Item` //~| ERROR missing generics for associated type `SVec::Item` //~| ERROR missing generics for associated type `SVec::Item` @@ -60,8 +62,8 @@ pub trait SVec: Index< type Item<'a, T>; fn len(&self) -> ::Item; - //~^ expected 1 lifetime argument + //~^ NOTE expected 1 lifetime argument //~| ERROR missing generics for associated type `SVec::Item` - //~| expected 1 generic argument + //~| NOTE expected 1 generic argument //~| ERROR missing generics for associated type `SVec::Item` } diff --git a/tests/rustdoc-ui/issues/ice-generic-type-alias-105742.stderr b/tests/rustdoc-ui/issues/ice-generic-type-alias-105742.stderr index e4a84655486..642847733a8 100644 --- a/tests/rustdoc-ui/issues/ice-generic-type-alias-105742.stderr +++ b/tests/rustdoc-ui/issues/ice-generic-type-alias-105742.stderr @@ -1,11 +1,11 @@ error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/ice-generic-type-alias-105742.rs:16:21 + --> $DIR/ice-generic-type-alias-105742.rs:18:21 | LL | ::Item, | ^^^^ expected 1 lifetime argument | note: associated type defined here, with 1 lifetime parameter: `'a` - --> $DIR/ice-generic-type-alias-105742.rs:60:10 + --> $DIR/ice-generic-type-alias-105742.rs:62:10 | LL | type Item<'a, T>; | ^^^^ -- @@ -15,13 +15,13 @@ LL | ::Item<'a>, | ++++ error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/ice-generic-type-alias-105742.rs:16:21 + --> $DIR/ice-generic-type-alias-105742.rs:18:21 | LL | ::Item, | ^^^^ expected 1 generic argument | note: associated type defined here, with 1 generic parameter: `T` - --> $DIR/ice-generic-type-alias-105742.rs:60:10 + --> $DIR/ice-generic-type-alias-105742.rs:62:10 | LL | type Item<'a, T>; | ^^^^ - @@ -31,13 +31,13 @@ LL | ::Item, | +++ error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/ice-generic-type-alias-105742.rs:27:37 + --> $DIR/ice-generic-type-alias-105742.rs:29:37 | LL | Output = ::Item, | ^^^^ expected 1 lifetime argument | note: associated type defined here, with 1 lifetime parameter: `'a` - --> $DIR/ice-generic-type-alias-105742.rs:60:10 + --> $DIR/ice-generic-type-alias-105742.rs:62:10 | LL | type Item<'a, T>; | ^^^^ -- @@ -47,13 +47,13 @@ LL | Output = ::Item<'a>, | ++++ error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/ice-generic-type-alias-105742.rs:27:37 + --> $DIR/ice-generic-type-alias-105742.rs:29:37 | LL | Output = ::Item, | ^^^^ expected 1 generic argument | note: associated type defined here, with 1 generic parameter: `T` - --> $DIR/ice-generic-type-alias-105742.rs:60:10 + --> $DIR/ice-generic-type-alias-105742.rs:62:10 | LL | type Item<'a, T>; | ^^^^ - @@ -63,13 +63,13 @@ LL | Output = ::Item, | +++ error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/ice-generic-type-alias-105742.rs:38:30 + --> $DIR/ice-generic-type-alias-105742.rs:40:30 | LL | Output = ::Item> as SVec>::Item, | ^^^^ expected 1 lifetime argument | note: associated type defined here, with 1 lifetime parameter: `'a` - --> $DIR/ice-generic-type-alias-105742.rs:60:10 + --> $DIR/ice-generic-type-alias-105742.rs:62:10 | LL | type Item<'a, T>; | ^^^^ -- @@ -79,13 +79,13 @@ LL | Output = ::Item<'a>> as SVec>::Item, | ++++ error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/ice-generic-type-alias-105742.rs:38:30 + --> $DIR/ice-generic-type-alias-105742.rs:40:30 | LL | Output = ::Item> as SVec>::Item, | ^^^^ expected 1 generic argument | note: associated type defined here, with 1 generic parameter: `T` - --> $DIR/ice-generic-type-alias-105742.rs:60:10 + --> $DIR/ice-generic-type-alias-105742.rs:62:10 | LL | type Item<'a, T>; | ^^^^ - @@ -95,13 +95,13 @@ LL | Output = ::Item> as SVec>::Item, | +++ error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/ice-generic-type-alias-105742.rs:38:46 + --> $DIR/ice-generic-type-alias-105742.rs:40:46 | LL | Output = ::Item> as SVec>::Item, | ^^^^ expected 1 lifetime argument | note: associated type defined here, with 1 lifetime parameter: `'a` - --> $DIR/ice-generic-type-alias-105742.rs:60:10 + --> $DIR/ice-generic-type-alias-105742.rs:62:10 | LL | type Item<'a, T>; | ^^^^ -- @@ -111,13 +111,13 @@ LL | Output = ::Item> as SVec>::Item<'a>, | ++++ error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/ice-generic-type-alias-105742.rs:38:46 + --> $DIR/ice-generic-type-alias-105742.rs:40:46 | LL | Output = ::Item> as SVec>::Item, | ^^^^ expected 1 generic argument | note: associated type defined here, with 1 generic parameter: `T` - --> $DIR/ice-generic-type-alias-105742.rs:60:10 + --> $DIR/ice-generic-type-alias-105742.rs:62:10 | LL | type Item<'a, T>; | ^^^^ - @@ -127,13 +127,13 @@ LL | Output = ::Item> as SVec>::Item, | +++ error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/ice-generic-type-alias-105742.rs:5:40 + --> $DIR/ice-generic-type-alias-105742.rs:7:40 | LL | pub fn next<'a, T>(s: &'a mut dyn SVec) { | ^^^^ expected 1 lifetime argument | note: associated type defined here, with 1 lifetime parameter: `'a` - --> $DIR/ice-generic-type-alias-105742.rs:60:10 + --> $DIR/ice-generic-type-alias-105742.rs:62:10 | LL | type Item<'a, T>; | ^^^^ -- @@ -143,13 +143,13 @@ LL | pub fn next<'a, T>(s: &'a mut dyn SVec = T, Output = T>) { | ++++ error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/ice-generic-type-alias-105742.rs:5:40 + --> $DIR/ice-generic-type-alias-105742.rs:7:40 | LL | pub fn next<'a, T>(s: &'a mut dyn SVec) { | ^^^^ expected 1 generic argument | note: associated type defined here, with 1 generic parameter: `T` - --> $DIR/ice-generic-type-alias-105742.rs:60:10 + --> $DIR/ice-generic-type-alias-105742.rs:62:10 | LL | type Item<'a, T>; | ^^^^ - @@ -159,13 +159,13 @@ LL | pub fn next<'a, T>(s: &'a mut dyn SVec = T, Output = T>) { | +++ error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/ice-generic-type-alias-105742.rs:16:21 + --> $DIR/ice-generic-type-alias-105742.rs:18:21 | LL | ::Item, | ^^^^ expected 1 lifetime argument | note: associated type defined here, with 1 lifetime parameter: `'a` - --> $DIR/ice-generic-type-alias-105742.rs:60:10 + --> $DIR/ice-generic-type-alias-105742.rs:62:10 | LL | type Item<'a, T>; | ^^^^ -- @@ -176,13 +176,13 @@ LL | ::Item<'a>, | ++++ error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/ice-generic-type-alias-105742.rs:16:21 + --> $DIR/ice-generic-type-alias-105742.rs:18:21 | LL | ::Item, | ^^^^ expected 1 generic argument | note: associated type defined here, with 1 generic parameter: `T` - --> $DIR/ice-generic-type-alias-105742.rs:60:10 + --> $DIR/ice-generic-type-alias-105742.rs:62:10 | LL | type Item<'a, T>; | ^^^^ - @@ -193,13 +193,13 @@ LL | ::Item, | +++ error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/ice-generic-type-alias-105742.rs:27:37 + --> $DIR/ice-generic-type-alias-105742.rs:29:37 | LL | Output = ::Item, | ^^^^ expected 1 lifetime argument | note: associated type defined here, with 1 lifetime parameter: `'a` - --> $DIR/ice-generic-type-alias-105742.rs:60:10 + --> $DIR/ice-generic-type-alias-105742.rs:62:10 | LL | type Item<'a, T>; | ^^^^ -- @@ -210,13 +210,13 @@ LL | Output = ::Item<'a>, | ++++ error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/ice-generic-type-alias-105742.rs:27:37 + --> $DIR/ice-generic-type-alias-105742.rs:29:37 | LL | Output = ::Item, | ^^^^ expected 1 generic argument | note: associated type defined here, with 1 generic parameter: `T` - --> $DIR/ice-generic-type-alias-105742.rs:60:10 + --> $DIR/ice-generic-type-alias-105742.rs:62:10 | LL | type Item<'a, T>; | ^^^^ - @@ -227,13 +227,13 @@ LL | Output = ::Item, | +++ error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/ice-generic-type-alias-105742.rs:38:30 + --> $DIR/ice-generic-type-alias-105742.rs:40:30 | LL | Output = ::Item> as SVec>::Item, | ^^^^ expected 1 lifetime argument | note: associated type defined here, with 1 lifetime parameter: `'a` - --> $DIR/ice-generic-type-alias-105742.rs:60:10 + --> $DIR/ice-generic-type-alias-105742.rs:62:10 | LL | type Item<'a, T>; | ^^^^ -- @@ -244,13 +244,13 @@ LL | Output = ::Item<'a>> as SVec>::Item, | ++++ error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/ice-generic-type-alias-105742.rs:38:30 + --> $DIR/ice-generic-type-alias-105742.rs:40:30 | LL | Output = ::Item> as SVec>::Item, | ^^^^ expected 1 generic argument | note: associated type defined here, with 1 generic parameter: `T` - --> $DIR/ice-generic-type-alias-105742.rs:60:10 + --> $DIR/ice-generic-type-alias-105742.rs:62:10 | LL | type Item<'a, T>; | ^^^^ - @@ -261,13 +261,13 @@ LL | Output = ::Item> as SVec>::Item, | +++ error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/ice-generic-type-alias-105742.rs:38:46 + --> $DIR/ice-generic-type-alias-105742.rs:40:46 | LL | Output = ::Item> as SVec>::Item, | ^^^^ expected 1 lifetime argument | note: associated type defined here, with 1 lifetime parameter: `'a` - --> $DIR/ice-generic-type-alias-105742.rs:60:10 + --> $DIR/ice-generic-type-alias-105742.rs:62:10 | LL | type Item<'a, T>; | ^^^^ -- @@ -278,13 +278,13 @@ LL | Output = ::Item> as SVec>::Item<'a>, | ++++ error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/ice-generic-type-alias-105742.rs:38:46 + --> $DIR/ice-generic-type-alias-105742.rs:40:46 | LL | Output = ::Item> as SVec>::Item, | ^^^^ expected 1 generic argument | note: associated type defined here, with 1 generic parameter: `T` - --> $DIR/ice-generic-type-alias-105742.rs:60:10 + --> $DIR/ice-generic-type-alias-105742.rs:62:10 | LL | type Item<'a, T>; | ^^^^ - @@ -295,14 +295,14 @@ LL | Output = ::Item> as SVec>::Item, | +++ error[E0038]: the trait `SVec` is not dyn compatible - --> $DIR/ice-generic-type-alias-105742.rs:5:35 + --> $DIR/ice-generic-type-alias-105742.rs:7:35 | LL | pub fn next<'a, T>(s: &'a mut dyn SVec) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^ `SVec` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable for more information, visit - --> $DIR/ice-generic-type-alias-105742.rs:15:17 + --> $DIR/ice-generic-type-alias-105742.rs:17:17 | LL | pub trait SVec: Index< | ____________----__^ @@ -324,13 +324,13 @@ LL + pub fn next<'a, T>(s: &'a mut impl SVec) { | error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/ice-generic-type-alias-105742.rs:16:21 + --> $DIR/ice-generic-type-alias-105742.rs:18:21 | LL | ::Item, | ^^^^ expected 1 lifetime argument | note: associated type defined here, with 1 lifetime parameter: `'a` - --> $DIR/ice-generic-type-alias-105742.rs:60:10 + --> $DIR/ice-generic-type-alias-105742.rs:62:10 | LL | type Item<'a, T>; | ^^^^ -- @@ -341,13 +341,13 @@ LL | ::Item<'a>, | ++++ error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/ice-generic-type-alias-105742.rs:16:21 + --> $DIR/ice-generic-type-alias-105742.rs:18:21 | LL | ::Item, | ^^^^ expected 1 generic argument | note: associated type defined here, with 1 generic parameter: `T` - --> $DIR/ice-generic-type-alias-105742.rs:60:10 + --> $DIR/ice-generic-type-alias-105742.rs:62:10 | LL | type Item<'a, T>; | ^^^^ - @@ -358,13 +358,13 @@ LL | ::Item, | +++ error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/ice-generic-type-alias-105742.rs:27:37 + --> $DIR/ice-generic-type-alias-105742.rs:29:37 | LL | Output = ::Item, | ^^^^ expected 1 lifetime argument | note: associated type defined here, with 1 lifetime parameter: `'a` - --> $DIR/ice-generic-type-alias-105742.rs:60:10 + --> $DIR/ice-generic-type-alias-105742.rs:62:10 | LL | type Item<'a, T>; | ^^^^ -- @@ -375,13 +375,13 @@ LL | Output = ::Item<'a>, | ++++ error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/ice-generic-type-alias-105742.rs:27:37 + --> $DIR/ice-generic-type-alias-105742.rs:29:37 | LL | Output = ::Item, | ^^^^ expected 1 generic argument | note: associated type defined here, with 1 generic parameter: `T` - --> $DIR/ice-generic-type-alias-105742.rs:60:10 + --> $DIR/ice-generic-type-alias-105742.rs:62:10 | LL | type Item<'a, T>; | ^^^^ - @@ -392,13 +392,13 @@ LL | Output = ::Item, | +++ error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/ice-generic-type-alias-105742.rs:38:30 + --> $DIR/ice-generic-type-alias-105742.rs:40:30 | LL | Output = ::Item> as SVec>::Item, | ^^^^ expected 1 lifetime argument | note: associated type defined here, with 1 lifetime parameter: `'a` - --> $DIR/ice-generic-type-alias-105742.rs:60:10 + --> $DIR/ice-generic-type-alias-105742.rs:62:10 | LL | type Item<'a, T>; | ^^^^ -- @@ -409,13 +409,13 @@ LL | Output = ::Item<'a>> as SVec>::Item, | ++++ error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/ice-generic-type-alias-105742.rs:38:30 + --> $DIR/ice-generic-type-alias-105742.rs:40:30 | LL | Output = ::Item> as SVec>::Item, | ^^^^ expected 1 generic argument | note: associated type defined here, with 1 generic parameter: `T` - --> $DIR/ice-generic-type-alias-105742.rs:60:10 + --> $DIR/ice-generic-type-alias-105742.rs:62:10 | LL | type Item<'a, T>; | ^^^^ - @@ -426,13 +426,13 @@ LL | Output = ::Item> as SVec>::Item, | +++ error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/ice-generic-type-alias-105742.rs:38:46 + --> $DIR/ice-generic-type-alias-105742.rs:40:46 | LL | Output = ::Item> as SVec>::Item, | ^^^^ expected 1 lifetime argument | note: associated type defined here, with 1 lifetime parameter: `'a` - --> $DIR/ice-generic-type-alias-105742.rs:60:10 + --> $DIR/ice-generic-type-alias-105742.rs:62:10 | LL | type Item<'a, T>; | ^^^^ -- @@ -443,13 +443,13 @@ LL | Output = ::Item> as SVec>::Item<'a>, | ++++ error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/ice-generic-type-alias-105742.rs:38:46 + --> $DIR/ice-generic-type-alias-105742.rs:40:46 | LL | Output = ::Item> as SVec>::Item, | ^^^^ expected 1 generic argument | note: associated type defined here, with 1 generic parameter: `T` - --> $DIR/ice-generic-type-alias-105742.rs:60:10 + --> $DIR/ice-generic-type-alias-105742.rs:62:10 | LL | type Item<'a, T>; | ^^^^ - @@ -460,13 +460,13 @@ LL | Output = ::Item> as SVec>::Item, | +++ error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/ice-generic-type-alias-105742.rs:16:21 + --> $DIR/ice-generic-type-alias-105742.rs:18:21 | LL | ::Item, | ^^^^ expected 1 lifetime argument | note: associated type defined here, with 1 lifetime parameter: `'a` - --> $DIR/ice-generic-type-alias-105742.rs:60:10 + --> $DIR/ice-generic-type-alias-105742.rs:62:10 | LL | type Item<'a, T>; | ^^^^ -- @@ -477,13 +477,13 @@ LL | ::Item<'a>, | ++++ error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/ice-generic-type-alias-105742.rs:16:21 + --> $DIR/ice-generic-type-alias-105742.rs:18:21 | LL | ::Item, | ^^^^ expected 1 generic argument | note: associated type defined here, with 1 generic parameter: `T` - --> $DIR/ice-generic-type-alias-105742.rs:60:10 + --> $DIR/ice-generic-type-alias-105742.rs:62:10 | LL | type Item<'a, T>; | ^^^^ - @@ -494,13 +494,13 @@ LL | ::Item, | +++ error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/ice-generic-type-alias-105742.rs:27:37 + --> $DIR/ice-generic-type-alias-105742.rs:29:37 | LL | Output = ::Item, | ^^^^ expected 1 lifetime argument | note: associated type defined here, with 1 lifetime parameter: `'a` - --> $DIR/ice-generic-type-alias-105742.rs:60:10 + --> $DIR/ice-generic-type-alias-105742.rs:62:10 | LL | type Item<'a, T>; | ^^^^ -- @@ -511,13 +511,13 @@ LL | Output = ::Item<'a>, | ++++ error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/ice-generic-type-alias-105742.rs:27:37 + --> $DIR/ice-generic-type-alias-105742.rs:29:37 | LL | Output = ::Item, | ^^^^ expected 1 generic argument | note: associated type defined here, with 1 generic parameter: `T` - --> $DIR/ice-generic-type-alias-105742.rs:60:10 + --> $DIR/ice-generic-type-alias-105742.rs:62:10 | LL | type Item<'a, T>; | ^^^^ - @@ -528,13 +528,13 @@ LL | Output = ::Item, | +++ error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/ice-generic-type-alias-105742.rs:38:30 + --> $DIR/ice-generic-type-alias-105742.rs:40:30 | LL | Output = ::Item> as SVec>::Item, | ^^^^ expected 1 lifetime argument | note: associated type defined here, with 1 lifetime parameter: `'a` - --> $DIR/ice-generic-type-alias-105742.rs:60:10 + --> $DIR/ice-generic-type-alias-105742.rs:62:10 | LL | type Item<'a, T>; | ^^^^ -- @@ -545,13 +545,13 @@ LL | Output = ::Item<'a>> as SVec>::Item, | ++++ error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/ice-generic-type-alias-105742.rs:38:30 + --> $DIR/ice-generic-type-alias-105742.rs:40:30 | LL | Output = ::Item> as SVec>::Item, | ^^^^ expected 1 generic argument | note: associated type defined here, with 1 generic parameter: `T` - --> $DIR/ice-generic-type-alias-105742.rs:60:10 + --> $DIR/ice-generic-type-alias-105742.rs:62:10 | LL | type Item<'a, T>; | ^^^^ - @@ -562,13 +562,13 @@ LL | Output = ::Item> as SVec>::Item, | +++ error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/ice-generic-type-alias-105742.rs:38:46 + --> $DIR/ice-generic-type-alias-105742.rs:40:46 | LL | Output = ::Item> as SVec>::Item, | ^^^^ expected 1 lifetime argument | note: associated type defined here, with 1 lifetime parameter: `'a` - --> $DIR/ice-generic-type-alias-105742.rs:60:10 + --> $DIR/ice-generic-type-alias-105742.rs:62:10 | LL | type Item<'a, T>; | ^^^^ -- @@ -579,13 +579,13 @@ LL | Output = ::Item> as SVec>::Item<'a>, | ++++ error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/ice-generic-type-alias-105742.rs:38:46 + --> $DIR/ice-generic-type-alias-105742.rs:40:46 | LL | Output = ::Item> as SVec>::Item, | ^^^^ expected 1 generic argument | note: associated type defined here, with 1 generic parameter: `T` - --> $DIR/ice-generic-type-alias-105742.rs:60:10 + --> $DIR/ice-generic-type-alias-105742.rs:62:10 | LL | type Item<'a, T>; | ^^^^ - @@ -596,13 +596,13 @@ LL | Output = ::Item> as SVec>::Item, | +++ error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/ice-generic-type-alias-105742.rs:62:38 + --> $DIR/ice-generic-type-alias-105742.rs:64:38 | LL | fn len(&self) -> ::Item; | ^^^^ expected 1 lifetime argument | note: associated type defined here, with 1 lifetime parameter: `'a` - --> $DIR/ice-generic-type-alias-105742.rs:60:10 + --> $DIR/ice-generic-type-alias-105742.rs:62:10 | LL | type Item<'a, T>; | ^^^^ -- @@ -612,13 +612,13 @@ LL | fn len(&self) -> ::Item<'_>; | ++++ error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/ice-generic-type-alias-105742.rs:62:38 + --> $DIR/ice-generic-type-alias-105742.rs:64:38 | LL | fn len(&self) -> ::Item; | ^^^^ expected 1 generic argument | note: associated type defined here, with 1 generic parameter: `T` - --> $DIR/ice-generic-type-alias-105742.rs:60:10 + --> $DIR/ice-generic-type-alias-105742.rs:62:10 | LL | type Item<'a, T>; | ^^^^ - diff --git a/tests/ui/array-slice-vec/array-not-vector.rs b/tests/ui/array-slice-vec/array-not-vector.rs index d8b5b10d591..7345f721918 100644 --- a/tests/ui/array-slice-vec/array-not-vector.rs +++ b/tests/ui/array-slice-vec/array-not-vector.rs @@ -1,12 +1,14 @@ +//@ dont-require-annotations: NOTE + fn main() { let _x: i32 = [1, 2, 3]; //~^ ERROR mismatched types - //~| expected `i32`, found `[{integer}; 3]` + //~| NOTE expected `i32`, found `[{integer}; 3]` let x: &[i32] = &[1, 2, 3]; let _y: &i32 = x; //~^ ERROR mismatched types - //~| expected reference `&i32` - //~| found reference `&[i32]` - //~| expected `&i32`, found `&[i32]` + //~| NOTE expected reference `&i32` + //~| NOTE found reference `&[i32]` + //~| NOTE expected `&i32`, found `&[i32]` } diff --git a/tests/ui/array-slice-vec/array-not-vector.stderr b/tests/ui/array-slice-vec/array-not-vector.stderr index f20d99524dc..686c5dfe787 100644 --- a/tests/ui/array-slice-vec/array-not-vector.stderr +++ b/tests/ui/array-slice-vec/array-not-vector.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/array-not-vector.rs:2:19 + --> $DIR/array-not-vector.rs:4:19 | LL | let _x: i32 = [1, 2, 3]; | --- ^^^^^^^^^ expected `i32`, found `[{integer}; 3]` @@ -7,7 +7,7 @@ LL | let _x: i32 = [1, 2, 3]; | expected due to this error[E0308]: mismatched types - --> $DIR/array-not-vector.rs:7:20 + --> $DIR/array-not-vector.rs:9:20 | LL | let _y: &i32 = x; | ---- ^ expected `&i32`, found `&[i32]` diff --git a/tests/ui/array-slice-vec/slice-mut.rs b/tests/ui/array-slice-vec/slice-mut.rs index e9989f0f481..baa05c36a9d 100644 --- a/tests/ui/array-slice-vec/slice-mut.rs +++ b/tests/ui/array-slice-vec/slice-mut.rs @@ -6,7 +6,8 @@ fn main() { let y: &mut[_] = &x[2..4]; //~^ ERROR mismatched types - //~| expected mutable reference `&mut [_]` - //~| found reference `&[isize]` - //~| types differ in mutability + //~| NOTE expected mutable reference `&mut [_]` + //~| NOTE found reference `&[isize]` + //~| NOTE types differ in mutability + //~| NOTE expected due to this } diff --git a/tests/ui/associated-consts/defaults-not-assumed-fail.rs b/tests/ui/associated-consts/defaults-not-assumed-fail.rs index 3dc709cf633..830fd4ab0e9 100644 --- a/tests/ui/associated-consts/defaults-not-assumed-fail.rs +++ b/tests/ui/associated-consts/defaults-not-assumed-fail.rs @@ -1,4 +1,5 @@ //@ build-fail +//@ dont-require-annotations: NOTE trait Tr { const A: u8 = 255; @@ -31,7 +32,7 @@ impl Tr for u32 { fn main() { assert_eq!(<() as Tr>::A, 255); assert_eq!(<() as Tr>::B, 0); // causes the error above - //~^ constant + //~^ NOTE constant assert_eq!(::A, 254); assert_eq!(::B, 255); diff --git a/tests/ui/associated-consts/defaults-not-assumed-fail.stderr b/tests/ui/associated-consts/defaults-not-assumed-fail.stderr index 4b53603cfe8..3386e81dc98 100644 --- a/tests/ui/associated-consts/defaults-not-assumed-fail.stderr +++ b/tests/ui/associated-consts/defaults-not-assumed-fail.stderr @@ -1,17 +1,17 @@ error[E0080]: evaluation of `<() as Tr>::B` failed - --> $DIR/defaults-not-assumed-fail.rs:8:19 + --> $DIR/defaults-not-assumed-fail.rs:9:19 | LL | const B: u8 = Self::A + 1; | ^^^^^^^^^^^ attempt to compute `u8::MAX + 1_u8`, which would overflow note: erroneous constant encountered - --> $DIR/defaults-not-assumed-fail.rs:33:16 + --> $DIR/defaults-not-assumed-fail.rs:34:16 | LL | assert_eq!(<() as Tr>::B, 0); // causes the error above | ^^^^^^^^^^^^^ note: erroneous constant encountered - --> $DIR/defaults-not-assumed-fail.rs:33:16 + --> $DIR/defaults-not-assumed-fail.rs:34:16 | LL | assert_eq!(<() as Tr>::B, 0); // causes the error above | ^^^^^^^^^^^^^ @@ -19,7 +19,7 @@ LL | assert_eq!(<() as Tr>::B, 0); // causes the error above = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` note: erroneous constant encountered - --> $DIR/defaults-not-assumed-fail.rs:33:5 + --> $DIR/defaults-not-assumed-fail.rs:34:5 | LL | assert_eq!(<() as Tr>::B, 0); // causes the error above | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -27,7 +27,7 @@ LL | assert_eq!(<() as Tr>::B, 0); // causes the error above = note: this note originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info) note: erroneous constant encountered - --> $DIR/defaults-not-assumed-fail.rs:33:5 + --> $DIR/defaults-not-assumed-fail.rs:34:5 | LL | assert_eq!(<() as Tr>::B, 0); // causes the error above | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/associated-types/associated-types-eq-3.rs b/tests/ui/associated-types/associated-types-eq-3.rs index 380d0e95c13..082a7325466 100644 --- a/tests/ui/associated-types/associated-types-eq-3.rs +++ b/tests/ui/associated-types/associated-types-eq-3.rs @@ -1,6 +1,8 @@ // Test equality constraints on associated types. Check we get type errors // where we should. +//@ dont-require-annotations: NOTE + pub trait Foo { type A; fn boo(&self) -> ::A; @@ -22,9 +24,9 @@ fn foo1>(x: I) { fn foo2(x: I) { let _: Bar = x.boo(); //~^ ERROR mismatched types - //~| found associated type `::A` - //~| expected `Bar`, found - //~| expected struct `Bar` + //~| NOTE found associated type `::A` + //~| NOTE expected `Bar`, found + //~| NOTE expected struct `Bar` } diff --git a/tests/ui/associated-types/associated-types-eq-3.stderr b/tests/ui/associated-types/associated-types-eq-3.stderr index c3377eed20a..5fef2a020b8 100644 --- a/tests/ui/associated-types/associated-types-eq-3.stderr +++ b/tests/ui/associated-types/associated-types-eq-3.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/associated-types-eq-3.rs:23:18 + --> $DIR/associated-types-eq-3.rs:25:18 | LL | let _: Bar = x.boo(); | --- ^^^^^^^ expected `Bar`, found associated type @@ -14,7 +14,7 @@ LL | fn foo2>(x: I) { | +++++++++ error[E0271]: type mismatch resolving `::A == Bar` - --> $DIR/associated-types-eq-3.rs:38:10 + --> $DIR/associated-types-eq-3.rs:40:10 | LL | foo1(a); | ---- ^ type mismatch resolving `::A == Bar` @@ -22,24 +22,24 @@ LL | foo1(a); | required by a bound introduced by this call | note: expected this to be `Bar` - --> $DIR/associated-types-eq-3.rs:12:14 + --> $DIR/associated-types-eq-3.rs:14:14 | LL | type A = usize; | ^^^^^ note: required by a bound in `foo1` - --> $DIR/associated-types-eq-3.rs:18:16 + --> $DIR/associated-types-eq-3.rs:20:16 | LL | fn foo1>(x: I) { | ^^^^^ required by this bound in `foo1` error[E0271]: type mismatch resolving `::A == Bar` - --> $DIR/associated-types-eq-3.rs:40:9 + --> $DIR/associated-types-eq-3.rs:42:9 | LL | baz(&a); | ^^ type mismatch resolving `::A == Bar` | note: expected this to be `Bar` - --> $DIR/associated-types-eq-3.rs:12:14 + --> $DIR/associated-types-eq-3.rs:14:14 | LL | type A = usize; | ^^^^^ diff --git a/tests/ui/associated-types/associated-types-path-2.rs b/tests/ui/associated-types/associated-types-path-2.rs index c993e1d2720..b81aa990bcd 100644 --- a/tests/ui/associated-types/associated-types-path-2.rs +++ b/tests/ui/associated-types/associated-types-path-2.rs @@ -1,5 +1,7 @@ // Test type checking of uses of associated types via sugary paths. +//@ dont-require-annotations: NOTE + pub trait Foo { type A; @@ -18,7 +20,7 @@ pub fn f2(a: T) -> T::A { pub fn f1_int_int() { f1(2i32, 4i32); //~^ ERROR mismatched types - //~| expected `u32`, found `i32` + //~| NOTE expected `u32`, found `i32` } pub fn f1_int_uint() { @@ -40,7 +42,7 @@ pub fn f1_uint_int() { pub fn f2_int() { let _: i32 = f2(2i32); //~^ ERROR mismatched types - //~| expected `i32`, found `u32` + //~| NOTE expected `i32`, found `u32` } pub fn main() { } diff --git a/tests/ui/associated-types/associated-types-path-2.stderr b/tests/ui/associated-types/associated-types-path-2.stderr index 897eb75e3e3..46e34b0809f 100644 --- a/tests/ui/associated-types/associated-types-path-2.stderr +++ b/tests/ui/associated-types/associated-types-path-2.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/associated-types-path-2.rs:19:14 + --> $DIR/associated-types-path-2.rs:21:14 | LL | f1(2i32, 4i32); | -- ^^^^ expected `u32`, found `i32` @@ -7,7 +7,7 @@ LL | f1(2i32, 4i32); | arguments to this function are incorrect | note: function defined here - --> $DIR/associated-types-path-2.rs:13:8 + --> $DIR/associated-types-path-2.rs:15:8 | LL | pub fn f1(a: T, x: T::A) {} | ^^ ------- @@ -18,7 +18,7 @@ LL + f1(2i32, 4u32); | error[E0277]: the trait bound `u32: Foo` is not satisfied - --> $DIR/associated-types-path-2.rs:29:8 + --> $DIR/associated-types-path-2.rs:31:8 | LL | f1(2u32, 4u32); | -- ^^^^ the trait `Foo` is not implemented for `u32` @@ -27,13 +27,13 @@ LL | f1(2u32, 4u32); | = help: the trait `Foo` is implemented for `i32` note: required by a bound in `f1` - --> $DIR/associated-types-path-2.rs:13:14 + --> $DIR/associated-types-path-2.rs:15:14 | LL | pub fn f1(a: T, x: T::A) {} | ^^^ required by this bound in `f1` error[E0277]: the trait bound `u32: Foo` is not satisfied - --> $DIR/associated-types-path-2.rs:29:14 + --> $DIR/associated-types-path-2.rs:31:14 | LL | f1(2u32, 4u32); | ^^^^ the trait `Foo` is not implemented for `u32` @@ -41,7 +41,7 @@ LL | f1(2u32, 4u32); = help: the trait `Foo` is implemented for `i32` error[E0277]: the trait bound `u32: Foo` is not satisfied - --> $DIR/associated-types-path-2.rs:35:8 + --> $DIR/associated-types-path-2.rs:37:8 | LL | f1(2u32, 4i32); | -- ^^^^ the trait `Foo` is not implemented for `u32` @@ -50,13 +50,13 @@ LL | f1(2u32, 4i32); | = help: the trait `Foo` is implemented for `i32` note: required by a bound in `f1` - --> $DIR/associated-types-path-2.rs:13:14 + --> $DIR/associated-types-path-2.rs:15:14 | LL | pub fn f1(a: T, x: T::A) {} | ^^^ required by this bound in `f1` error[E0277]: the trait bound `u32: Foo` is not satisfied - --> $DIR/associated-types-path-2.rs:35:14 + --> $DIR/associated-types-path-2.rs:37:14 | LL | f1(2u32, 4i32); | ^^^^ the trait `Foo` is not implemented for `u32` @@ -64,7 +64,7 @@ LL | f1(2u32, 4i32); = help: the trait `Foo` is implemented for `i32` error[E0308]: mismatched types - --> $DIR/associated-types-path-2.rs:41:18 + --> $DIR/associated-types-path-2.rs:43:18 | LL | let _: i32 = f2(2i32); | --- ^^^^^^^^ expected `i32`, found `u32` diff --git a/tests/ui/associated-types/substs-ppaux.normal.stderr b/tests/ui/associated-types/substs-ppaux.normal.stderr index 1ea8ab23556..aa2aca7426e 100644 --- a/tests/ui/associated-types/substs-ppaux.normal.stderr +++ b/tests/ui/associated-types/substs-ppaux.normal.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/substs-ppaux.rs:23:17 + --> $DIR/substs-ppaux.rs:22:17 | LL | / fn bar<'a, T>() LL | | where @@ -19,7 +19,7 @@ LL | let x: () = >::bar::<'static, char>(); | ++ error[E0308]: mismatched types - --> $DIR/substs-ppaux.rs:31:17 + --> $DIR/substs-ppaux.rs:30:17 | LL | / fn bar<'a, T>() LL | | where @@ -39,7 +39,7 @@ LL | let x: () = >::bar::<'static, char>(); | ++ error[E0308]: mismatched types - --> $DIR/substs-ppaux.rs:39:17 + --> $DIR/substs-ppaux.rs:38:17 | LL | fn baz() {} | -------- associated function `baz` defined here @@ -57,7 +57,7 @@ LL | let x: () = >::baz(); | ++ error[E0308]: mismatched types - --> $DIR/substs-ppaux.rs:47:17 + --> $DIR/substs-ppaux.rs:46:17 | LL | / fn foo<'z>() LL | | where @@ -77,13 +77,13 @@ LL | let x: () = foo::<'static>(); | ++ error[E0277]: the trait bound `str: Foo<'_, '_, u8>` is not satisfied - --> $DIR/substs-ppaux.rs:55:6 + --> $DIR/substs-ppaux.rs:54:6 | LL | >::bar; | ^^^ the trait `Sized` is not implemented for `str` | note: required for `str` to implement `Foo<'_, '_, u8>` - --> $DIR/substs-ppaux.rs:15:20 + --> $DIR/substs-ppaux.rs:14:20 | LL | impl<'a, 'b, T, S> Foo<'a, 'b, S> for T {} | - ^^^^^^^^^^^^^^ ^ diff --git a/tests/ui/associated-types/substs-ppaux.rs b/tests/ui/associated-types/substs-ppaux.rs index 302a6b345e4..ceec9978b1c 100644 --- a/tests/ui/associated-types/substs-ppaux.rs +++ b/tests/ui/associated-types/substs-ppaux.rs @@ -1,7 +1,6 @@ -// //@ revisions: verbose normal -// //@[verbose] compile-flags: -Z verbose-internals +//@ dont-require-annotations: NOTE trait Foo<'b, 'c, S = u32> { fn bar<'a, T>() @@ -22,35 +21,35 @@ where { let x: () = >::bar::<'static, char>; //[verbose]~^ ERROR mismatched types - //[verbose]~| expected unit type `()` - //[verbose]~| found fn item `fn() {>::bar::<'static, char>}` + //[verbose]~| NOTE expected unit type `()` + //[verbose]~| NOTE found fn item `fn() {>::bar::<'static, char>}` //[normal]~^^^^ ERROR mismatched types - //[normal]~| expected unit type `()` - //[normal]~| found fn item `fn() {>::bar::<'static, char>}` + //[normal]~| NOTE expected unit type `()` + //[normal]~| NOTE found fn item `fn() {>::bar::<'static, char>}` let x: () = >::bar::<'static, char>; //[verbose]~^ ERROR mismatched types - //[verbose]~| expected unit type `()` - //[verbose]~| found fn item `fn() {>::bar::<'static, char>}` + //[verbose]~| NOTE expected unit type `()` + //[verbose]~| NOTE found fn item `fn() {>::bar::<'static, char>}` //[normal]~^^^^ ERROR mismatched types - //[normal]~| expected unit type `()` - //[normal]~| found fn item `fn() {>::bar::<'static, char>}` + //[normal]~| NOTE expected unit type `()` + //[normal]~| NOTE found fn item `fn() {>::bar::<'static, char>}` let x: () = >::baz; //[verbose]~^ ERROR mismatched types - //[verbose]~| expected unit type `()` - //[verbose]~| found fn item `fn() {>::baz}` + //[verbose]~| NOTE expected unit type `()` + //[verbose]~| NOTE found fn item `fn() {>::baz}` //[normal]~^^^^ ERROR mismatched types - //[normal]~| expected unit type `()` - //[normal]~| found fn item `fn() {>::baz}` + //[normal]~| NOTE expected unit type `()` + //[normal]~| NOTE found fn item `fn() {>::baz}` let x: () = foo::<'static>; //[verbose]~^ ERROR mismatched types - //[verbose]~| expected unit type `()` - //[verbose]~| found fn item `fn() {foo::<'static>}` + //[verbose]~| NOTE expected unit type `()` + //[verbose]~| NOTE found fn item `fn() {foo::<'static>}` //[normal]~^^^^ ERROR mismatched types - //[normal]~| expected unit type `()` - //[normal]~| found fn item `fn() {foo::<'static>}` + //[normal]~| NOTE expected unit type `()` + //[normal]~| NOTE found fn item `fn() {foo::<'static>}` >::bar; //[verbose]~^ ERROR the trait bound `str: Foo<'?0, '?1, u8>` is not satisfied diff --git a/tests/ui/associated-types/substs-ppaux.verbose.stderr b/tests/ui/associated-types/substs-ppaux.verbose.stderr index 05cd971c882..23cf222a1d3 100644 --- a/tests/ui/associated-types/substs-ppaux.verbose.stderr +++ b/tests/ui/associated-types/substs-ppaux.verbose.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/substs-ppaux.rs:23:17 + --> $DIR/substs-ppaux.rs:22:17 | LL | / fn bar<'a, T>() LL | | where @@ -19,7 +19,7 @@ LL | let x: () = >::bar::<'static, char>(); | ++ error[E0308]: mismatched types - --> $DIR/substs-ppaux.rs:31:17 + --> $DIR/substs-ppaux.rs:30:17 | LL | / fn bar<'a, T>() LL | | where @@ -39,7 +39,7 @@ LL | let x: () = >::bar::<'static, char>(); | ++ error[E0308]: mismatched types - --> $DIR/substs-ppaux.rs:39:17 + --> $DIR/substs-ppaux.rs:38:17 | LL | fn baz() {} | -------- associated function `baz` defined here @@ -57,7 +57,7 @@ LL | let x: () = >::baz(); | ++ error[E0308]: mismatched types - --> $DIR/substs-ppaux.rs:47:17 + --> $DIR/substs-ppaux.rs:46:17 | LL | / fn foo<'z>() LL | | where @@ -77,13 +77,13 @@ LL | let x: () = foo::<'static>(); | ++ error[E0277]: the trait bound `str: Foo<'?0, '?1, u8>` is not satisfied - --> $DIR/substs-ppaux.rs:55:6 + --> $DIR/substs-ppaux.rs:54:6 | LL | >::bar; | ^^^ the trait `Sized` is not implemented for `str` | note: required for `str` to implement `Foo<'?0, '?1, u8>` - --> $DIR/substs-ppaux.rs:15:20 + --> $DIR/substs-ppaux.rs:14:20 | LL | impl<'a, 'b, T, S> Foo<'a, 'b, S> for T {} | - ^^^^^^^^^^^^^^ ^ diff --git a/tests/ui/binop/shift-various-bad-types.rs b/tests/ui/binop/shift-various-bad-types.rs index 31224bbca1e..025cd922d78 100644 --- a/tests/ui/binop/shift-various-bad-types.rs +++ b/tests/ui/binop/shift-various-bad-types.rs @@ -1,5 +1,7 @@ // Test that we can do shifts by any integral type. +//@ dont-require-annotations: NOTE + struct Panolpy { char: char, str: &'static str, @@ -24,7 +26,7 @@ fn foo(p: &Panolpy) { // Type of the result follows the LHS, not the RHS: let _: i32 = 22_i64 >> 1_i32; //~^ ERROR mismatched types - //~| expected `i32`, found `i64` + //~| NOTE expected `i32`, found `i64` } fn main() { diff --git a/tests/ui/binop/shift-various-bad-types.stderr b/tests/ui/binop/shift-various-bad-types.stderr index d7c9eb5f9df..5d16ed7e50b 100644 --- a/tests/ui/binop/shift-various-bad-types.stderr +++ b/tests/ui/binop/shift-various-bad-types.stderr @@ -1,5 +1,5 @@ error[E0277]: no implementation for `{integer} >> char` - --> $DIR/shift-various-bad-types.rs:9:8 + --> $DIR/shift-various-bad-types.rs:11:8 | LL | 22 >> p.char; | ^^ no implementation for `{integer} >> char` @@ -17,7 +17,7 @@ LL | 22 >> p.char; and 568 others error[E0277]: no implementation for `{integer} >> &str` - --> $DIR/shift-various-bad-types.rs:12:8 + --> $DIR/shift-various-bad-types.rs:14:8 | LL | 22 >> p.str; | ^^ no implementation for `{integer} >> &str` @@ -35,7 +35,7 @@ LL | 22 >> p.str; and 568 others error[E0277]: no implementation for `{integer} >> &Panolpy` - --> $DIR/shift-various-bad-types.rs:15:8 + --> $DIR/shift-various-bad-types.rs:17:8 | LL | 22 >> p; | ^^ no implementation for `{integer} >> &Panolpy` @@ -53,7 +53,7 @@ LL | 22 >> p; and 568 others error[E0308]: mismatched types - --> $DIR/shift-various-bad-types.rs:25:18 + --> $DIR/shift-various-bad-types.rs:27:18 | LL | let _: i32 = 22_i64 >> 1_i32; | --- ^^^^^^^^^^^^^^^ expected `i32`, found `i64` diff --git a/tests/ui/blind/blind-item-item-shadow.rs b/tests/ui/blind/blind-item-item-shadow.rs index 82d07ea7091..43841569417 100644 --- a/tests/ui/blind/blind-item-item-shadow.rs +++ b/tests/ui/blind/blind-item-item-shadow.rs @@ -1,7 +1,9 @@ +//@ dont-require-annotations: NOTE + mod foo { pub mod foo { } } use foo::foo; //~^ ERROR the name `foo` is defined multiple times -//~| `foo` reimported here +//~| NOTE `foo` reimported here fn main() {} diff --git a/tests/ui/blind/blind-item-item-shadow.stderr b/tests/ui/blind/blind-item-item-shadow.stderr index 08f5f5b47ed..7d13fbea37b 100644 --- a/tests/ui/blind/blind-item-item-shadow.stderr +++ b/tests/ui/blind/blind-item-item-shadow.stderr @@ -1,5 +1,5 @@ error[E0255]: the name `foo` is defined multiple times - --> $DIR/blind-item-item-shadow.rs:3:5 + --> $DIR/blind-item-item-shadow.rs:5:5 | LL | mod foo { pub mod foo { } } | ------- previous definition of the module `foo` here diff --git a/tests/ui/block-result/block-must-not-have-result-while.rs b/tests/ui/block-result/block-must-not-have-result-while.rs index 418059bf280..ada4e1778a5 100644 --- a/tests/ui/block-result/block-must-not-have-result-while.rs +++ b/tests/ui/block-result/block-must-not-have-result-while.rs @@ -1,6 +1,8 @@ +//@ dont-require-annotations: NOTE + fn main() { while true { //~ WARN denote infinite loops with true //~ ERROR mismatched types - //~| expected `()`, found `bool` + //~| NOTE expected `()`, found `bool` } } diff --git a/tests/ui/block-result/block-must-not-have-result-while.stderr b/tests/ui/block-result/block-must-not-have-result-while.stderr index 94a4b33da5d..0b9941ea96e 100644 --- a/tests/ui/block-result/block-must-not-have-result-while.stderr +++ b/tests/ui/block-result/block-must-not-have-result-while.stderr @@ -1,5 +1,5 @@ warning: denote infinite loops with `loop { ... }` - --> $DIR/block-must-not-have-result-while.rs:2:5 + --> $DIR/block-must-not-have-result-while.rs:4:5 | LL | while true { | ^^^^^^^^^^ help: use `loop` @@ -7,7 +7,7 @@ LL | while true { = note: `#[warn(while_true)]` on by default error[E0308]: mismatched types - --> $DIR/block-must-not-have-result-while.rs:3:9 + --> $DIR/block-must-not-have-result-while.rs:5:9 | LL | / while true { LL | | true diff --git a/tests/ui/block-result/issue-13624.rs b/tests/ui/block-result/issue-13624.rs index 8f93e5a356f..f9f7c33e411 100644 --- a/tests/ui/block-result/issue-13624.rs +++ b/tests/ui/block-result/issue-13624.rs @@ -1,3 +1,5 @@ +//@ dont-require-annotations: NOTE + mod a { pub enum Enum { EnumStructVariant { x: u8, y: u8, z: u8 } @@ -6,7 +8,7 @@ mod a { pub fn get_enum_struct_variant() -> () { Enum::EnumStructVariant { x: 1, y: 2, z: 3 } //~^ ERROR mismatched types - //~| expected `()`, found `Enum` + //~| NOTE expected `()`, found `Enum` } } @@ -19,7 +21,7 @@ mod b { match enum_struct_variant { a::Enum::EnumStructVariant { x, y, z } => { //~^ ERROR mismatched types - //~| expected `()`, found `Enum` + //~| NOTE expected `()`, found `Enum` } } } diff --git a/tests/ui/block-result/issue-13624.stderr b/tests/ui/block-result/issue-13624.stderr index d41bd057f82..16f5233a041 100644 --- a/tests/ui/block-result/issue-13624.stderr +++ b/tests/ui/block-result/issue-13624.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/issue-13624.rs:7:5 + --> $DIR/issue-13624.rs:9:5 | LL | pub fn get_enum_struct_variant() -> () { | -- expected `()` because of return type @@ -7,7 +7,7 @@ LL | Enum::EnumStructVariant { x: 1, y: 2, z: 3 } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found `Enum` error[E0308]: mismatched types - --> $DIR/issue-13624.rs:20:9 + --> $DIR/issue-13624.rs:22:9 | LL | match enum_struct_variant { | ------------------- this expression has type `()` diff --git a/tests/ui/block-result/issue-5500.rs b/tests/ui/block-result/issue-5500.rs index de7fd39a20c..cbad6a27c1d 100644 --- a/tests/ui/block-result/issue-5500.rs +++ b/tests/ui/block-result/issue-5500.rs @@ -1,7 +1,7 @@ -fn main() { +fn main() { //~ NOTE expected `()` because of default return type &panic!() //~^ ERROR mismatched types - //~| expected unit type `()` - //~| found reference `&_` - //~| expected `()`, found `&_` + //~| NOTE expected unit type `()` + //~| NOTE found reference `&_` + //~| NOTE expected `()`, found `&_` } diff --git a/tests/ui/borrowck/borrowck-report-with-custom-diagnostic.rs b/tests/ui/borrowck/borrowck-report-with-custom-diagnostic.rs index 9d323bf0324..caa312edd71 100644 --- a/tests/ui/borrowck/borrowck-report-with-custom-diagnostic.rs +++ b/tests/ui/borrowck/borrowck-report-with-custom-diagnostic.rs @@ -1,11 +1,13 @@ +//@ dont-require-annotations: NOTE + #![allow(dead_code)] fn main() { // Original borrow ends at end of function let mut x = 1; let y = &mut x; - //~^ mutable borrow occurs here + //~^ NOTE mutable borrow occurs here let z = &x; //~ ERROR cannot borrow - //~^ immutable borrow occurs here + //~^ NOTE immutable borrow occurs here z.use_ref(); y.use_mut(); } @@ -16,9 +18,9 @@ fn foo() { // Original borrow ends at end of match arm let mut x = 1; let y = &x; - //~^ immutable borrow occurs here + //~^ NOTE immutable borrow occurs here let z = &mut x; //~ ERROR cannot borrow - //~^ mutable borrow occurs here + //~^ NOTE mutable borrow occurs here z.use_mut(); y.use_ref(); } @@ -31,9 +33,9 @@ fn bar() { || { let mut x = 1; let y = &mut x; - //~^ first mutable borrow occurs here + //~^ NOTE first mutable borrow occurs here let z = &mut x; //~ ERROR cannot borrow - //~^ second mutable borrow occurs here + //~^ NOTE second mutable borrow occurs here z.use_mut(); y.use_mut(); }; diff --git a/tests/ui/borrowck/borrowck-report-with-custom-diagnostic.stderr b/tests/ui/borrowck/borrowck-report-with-custom-diagnostic.stderr index 444a74cbfcf..e2474737aad 100644 --- a/tests/ui/borrowck/borrowck-report-with-custom-diagnostic.stderr +++ b/tests/ui/borrowck/borrowck-report-with-custom-diagnostic.stderr @@ -1,5 +1,5 @@ error[E0502]: cannot borrow `x` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-report-with-custom-diagnostic.rs:7:13 + --> $DIR/borrowck-report-with-custom-diagnostic.rs:9:13 | LL | let y = &mut x; | ------ mutable borrow occurs here @@ -11,7 +11,7 @@ LL | y.use_mut(); | - mutable borrow later used here error[E0502]: cannot borrow `x` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-report-with-custom-diagnostic.rs:20:21 + --> $DIR/borrowck-report-with-custom-diagnostic.rs:22:21 | LL | let y = &x; | -- immutable borrow occurs here @@ -23,7 +23,7 @@ LL | y.use_ref(); | - immutable borrow later used here error[E0499]: cannot borrow `x` as mutable more than once at a time - --> $DIR/borrowck-report-with-custom-diagnostic.rs:35:17 + --> $DIR/borrowck-report-with-custom-diagnostic.rs:37:17 | LL | let y = &mut x; | ------ first mutable borrow occurs here diff --git a/tests/ui/borrowck/issue-81899.rs b/tests/ui/borrowck/issue-81899.rs index 380c03751f5..11755620d86 100644 --- a/tests/ui/borrowck/issue-81899.rs +++ b/tests/ui/borrowck/issue-81899.rs @@ -1,14 +1,16 @@ // Regression test for #81899. // The `panic!()` below is important to trigger the fixed ICE. +//@ dont-require-annotations: NOTE + const _CONST: &[u8] = &f(&[], |_| {}); //~ ERROR evaluation of constant value failed -//~^ constant +//~^ NOTE constant const fn f(_: &[u8], _: F) -> &[u8] where F: FnMut(&u8), { - panic!() //~ inside `f + panic!() //~ NOTE inside `f } fn main() {} diff --git a/tests/ui/borrowck/issue-81899.stderr b/tests/ui/borrowck/issue-81899.stderr index b5cd5e4abf3..97d463cb6a7 100644 --- a/tests/ui/borrowck/issue-81899.stderr +++ b/tests/ui/borrowck/issue-81899.stderr @@ -1,17 +1,17 @@ error[E0080]: evaluation of constant value failed - --> $DIR/issue-81899.rs:4:24 + --> $DIR/issue-81899.rs:6:24 | LL | const _CONST: &[u8] = &f(&[], |_| {}); | ^^^^^^^^^^^^^^ evaluation panicked: explicit panic | -note: inside `f::<{closure@$DIR/issue-81899.rs:4:31: 4:34}>` - --> $DIR/issue-81899.rs:11:5 +note: inside `f::<{closure@$DIR/issue-81899.rs:6:31: 6:34}>` + --> $DIR/issue-81899.rs:13:5 | LL | panic!() | ^^^^^^^^ the failure occurred here note: erroneous constant encountered - --> $DIR/issue-81899.rs:4:23 + --> $DIR/issue-81899.rs:6:23 | LL | const _CONST: &[u8] = &f(&[], |_| {}); | ^^^^^^^^^^^^^^^ diff --git a/tests/ui/borrowck/issue-88434-minimal-example.rs b/tests/ui/borrowck/issue-88434-minimal-example.rs index ebaa9a92273..7482b3fd612 100644 --- a/tests/ui/borrowck/issue-88434-minimal-example.rs +++ b/tests/ui/borrowck/issue-88434-minimal-example.rs @@ -1,13 +1,15 @@ // Regression test related to issue 88434 +//@ dont-require-annotations: NOTE + const _CONST: &() = &f(&|_| {}); //~ ERROR evaluation of constant value failed -//~^ constant +//~^ NOTE constant const fn f(_: &F) where F: FnMut(&u8), { - panic!() //~ inside `f + panic!() //~ NOTE inside `f } fn main() { } diff --git a/tests/ui/borrowck/issue-88434-minimal-example.stderr b/tests/ui/borrowck/issue-88434-minimal-example.stderr index d9f3b4dcb90..4c525b9ea2c 100644 --- a/tests/ui/borrowck/issue-88434-minimal-example.stderr +++ b/tests/ui/borrowck/issue-88434-minimal-example.stderr @@ -1,17 +1,17 @@ error[E0080]: evaluation of constant value failed - --> $DIR/issue-88434-minimal-example.rs:3:22 + --> $DIR/issue-88434-minimal-example.rs:5:22 | LL | const _CONST: &() = &f(&|_| {}); | ^^^^^^^^^^ evaluation panicked: explicit panic | -note: inside `f::<{closure@$DIR/issue-88434-minimal-example.rs:3:25: 3:28}>` - --> $DIR/issue-88434-minimal-example.rs:10:5 +note: inside `f::<{closure@$DIR/issue-88434-minimal-example.rs:5:25: 5:28}>` + --> $DIR/issue-88434-minimal-example.rs:12:5 | LL | panic!() | ^^^^^^^^ the failure occurred here note: erroneous constant encountered - --> $DIR/issue-88434-minimal-example.rs:3:21 + --> $DIR/issue-88434-minimal-example.rs:5:21 | LL | const _CONST: &() = &f(&|_| {}); | ^^^^^^^^^^^ diff --git a/tests/ui/borrowck/issue-88434-removal-index-should-be-less.rs b/tests/ui/borrowck/issue-88434-removal-index-should-be-less.rs index 8d042630424..09b1f59c449 100644 --- a/tests/ui/borrowck/issue-88434-removal-index-should-be-less.rs +++ b/tests/ui/borrowck/issue-88434-removal-index-should-be-less.rs @@ -1,13 +1,15 @@ // Regression test for issue 88434 +//@ dont-require-annotations: NOTE + const _CONST: &[u8] = &f(&[], |_| {}); //~ ERROR evaluation of constant value failed -//~^ constant +//~^ NOTE constant const fn f(_: &[u8], _: F) -> &[u8] where F: FnMut(&u8), { - panic!() //~ inside `f + panic!() //~ NOTE inside `f } fn main() { } diff --git a/tests/ui/borrowck/issue-88434-removal-index-should-be-less.stderr b/tests/ui/borrowck/issue-88434-removal-index-should-be-less.stderr index c82b5cf786d..a22621c9c1b 100644 --- a/tests/ui/borrowck/issue-88434-removal-index-should-be-less.stderr +++ b/tests/ui/borrowck/issue-88434-removal-index-should-be-less.stderr @@ -1,17 +1,17 @@ error[E0080]: evaluation of constant value failed - --> $DIR/issue-88434-removal-index-should-be-less.rs:3:24 + --> $DIR/issue-88434-removal-index-should-be-less.rs:5:24 | LL | const _CONST: &[u8] = &f(&[], |_| {}); | ^^^^^^^^^^^^^^ evaluation panicked: explicit panic | -note: inside `f::<{closure@$DIR/issue-88434-removal-index-should-be-less.rs:3:31: 3:34}>` - --> $DIR/issue-88434-removal-index-should-be-less.rs:10:5 +note: inside `f::<{closure@$DIR/issue-88434-removal-index-should-be-less.rs:5:31: 5:34}>` + --> $DIR/issue-88434-removal-index-should-be-less.rs:12:5 | LL | panic!() | ^^^^^^^^ the failure occurred here note: erroneous constant encountered - --> $DIR/issue-88434-removal-index-should-be-less.rs:3:23 + --> $DIR/issue-88434-removal-index-should-be-less.rs:5:23 | LL | const _CONST: &[u8] = &f(&[], |_| {}); | ^^^^^^^^^^^^^^^ diff --git a/tests/ui/cast/ptr-to-trait-obj-different-regions-misc.rs b/tests/ui/cast/ptr-to-trait-obj-different-regions-misc.rs index f8910c944c6..ce94ba657b8 100644 --- a/tests/ui/cast/ptr-to-trait-obj-different-regions-misc.rs +++ b/tests/ui/cast/ptr-to-trait-obj-different-regions-misc.rs @@ -1,4 +1,5 @@ //@ check-fail +//@ dont-require-annotations: NOTE trait Trait<'a> {} @@ -18,7 +19,7 @@ fn change_lt_ba<'a, 'b: 'a>(x: *mut dyn Trait<'a>) -> *mut dyn Trait<'b> { fn change_lt_hr<'a>(x: *mut dyn Trait<'a>) -> *mut dyn for<'b> Trait<'b> { x as _ //~ error: lifetime may not live long enough //~^ error: mismatched types - //~| one type is more general than the other + //~| NOTE one type is more general than the other } trait Assocked { diff --git a/tests/ui/cast/ptr-to-trait-obj-different-regions-misc.stderr b/tests/ui/cast/ptr-to-trait-obj-different-regions-misc.stderr index faaa6325f34..88a89dc4ac1 100644 --- a/tests/ui/cast/ptr-to-trait-obj-different-regions-misc.stderr +++ b/tests/ui/cast/ptr-to-trait-obj-different-regions-misc.stderr @@ -1,5 +1,5 @@ error: lifetime may not live long enough - --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:6:5 + --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:7:5 | LL | fn change_lt<'a, 'b>(x: *mut dyn Trait<'a>) -> *mut dyn Trait<'b> { | -- -- lifetime `'b` defined here @@ -14,7 +14,7 @@ LL | x as _ = help: see for more information about variance error: lifetime may not live long enough - --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:6:5 + --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:7:5 | LL | fn change_lt<'a, 'b>(x: *mut dyn Trait<'a>) -> *mut dyn Trait<'b> { | -- -- lifetime `'b` defined here @@ -31,7 +31,7 @@ LL | x as _ help: `'b` and `'a` must be the same: replace one with the other error: lifetime may not live long enough - --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:11:5 + --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:12:5 | LL | fn change_lt_ab<'a: 'b, 'b>(x: *mut dyn Trait<'a>) -> *mut dyn Trait<'b> { | -- -- lifetime `'b` defined here @@ -46,7 +46,7 @@ LL | x as _ = help: see for more information about variance error: lifetime may not live long enough - --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:15:5 + --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:16:5 | LL | fn change_lt_ba<'a, 'b: 'a>(x: *mut dyn Trait<'a>) -> *mut dyn Trait<'b> { | -- -- lifetime `'b` defined here @@ -61,7 +61,7 @@ LL | x as _ = help: see for more information about variance error: lifetime may not live long enough - --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:19:5 + --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:20:5 | LL | fn change_lt_hr<'a>(x: *mut dyn Trait<'a>) -> *mut dyn for<'b> Trait<'b> { | -- lifetime `'a` defined here @@ -74,7 +74,7 @@ LL | fn change_lt_hr<'a>(x: *mut dyn Trait<'a>) -> *mut dyn for<'b> Trait<'b> + | ++++ error[E0308]: mismatched types - --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:19:5 + --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:20:5 | LL | x as _ | ^^^^^^ one type is more general than the other @@ -83,7 +83,7 @@ LL | x as _ found trait object `dyn Trait<'_>` error: lifetime may not live long enough - --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:31:5 + --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:32:5 | LL | fn change_assoc_0<'a, 'b>( | -- -- lifetime `'b` defined here @@ -99,7 +99,7 @@ LL | x as _ = help: see for more information about variance error: lifetime may not live long enough - --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:31:5 + --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:32:5 | LL | fn change_assoc_0<'a, 'b>( | -- -- lifetime `'b` defined here @@ -119,7 +119,7 @@ help: `'b` and `'a` must be the same: replace one with the other = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: lifetime may not live long enough - --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:38:5 + --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:39:5 | LL | fn change_assoc_1<'a, 'b>( | -- -- lifetime `'b` defined here @@ -135,7 +135,7 @@ LL | x as _ = help: see for more information about variance error: lifetime may not live long enough - --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:38:5 + --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:39:5 | LL | fn change_assoc_1<'a, 'b>( | -- -- lifetime `'b` defined here @@ -155,7 +155,7 @@ help: `'b` and `'a` must be the same: replace one with the other = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0521]: borrowed data escapes outside of function - --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:45:5 + --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:46:5 | LL | fn extend_to_static<'a>(ptr: *const dyn Trait<'a>) { | -- --- diff --git a/tests/ui/coercion/coerce-mut.rs b/tests/ui/coercion/coerce-mut.rs index 43f0b55856d..d3ed0a52303 100644 --- a/tests/ui/coercion/coerce-mut.rs +++ b/tests/ui/coercion/coerce-mut.rs @@ -1,10 +1,12 @@ +//@ dont-require-annotations: NOTE + fn f(x: &mut i32) {} fn main() { let x = 0; f(&x); //~^ ERROR mismatched types - //~| expected mutable reference `&mut i32` - //~| found reference `&{integer}` - //~| types differ in mutability + //~| NOTE expected mutable reference `&mut i32` + //~| NOTE found reference `&{integer}` + //~| NOTE types differ in mutability } diff --git a/tests/ui/coercion/coerce-mut.stderr b/tests/ui/coercion/coerce-mut.stderr index 9bbfcc29e61..0e2a2d04467 100644 --- a/tests/ui/coercion/coerce-mut.stderr +++ b/tests/ui/coercion/coerce-mut.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/coerce-mut.rs:5:7 + --> $DIR/coerce-mut.rs:7:7 | LL | f(&x); | - ^^ types differ in mutability @@ -9,7 +9,7 @@ LL | f(&x); = note: expected mutable reference `&mut i32` found reference `&{integer}` note: function defined here - --> $DIR/coerce-mut.rs:1:4 + --> $DIR/coerce-mut.rs:3:4 | LL | fn f(x: &mut i32) {} | ^ ----------- diff --git a/tests/ui/coercion/coercion-slice.rs b/tests/ui/coercion/coercion-slice.rs index b99235dd37f..a0795e8316f 100644 --- a/tests/ui/coercion/coercion-slice.rs +++ b/tests/ui/coercion/coercion-slice.rs @@ -3,5 +3,6 @@ fn main() { let _: &[i32] = [0]; //~^ ERROR mismatched types - //~| expected `&[i32]`, found `[{integer}; 1]` + //~| NOTE expected `&[i32]`, found `[{integer}; 1]` + //~| NOTE expected due to this } diff --git a/tests/ui/coercion/mut-mut-wont-coerce.rs b/tests/ui/coercion/mut-mut-wont-coerce.rs index 33016e1e48a..6b00bfd583d 100644 --- a/tests/ui/coercion/mut-mut-wont-coerce.rs +++ b/tests/ui/coercion/mut-mut-wont-coerce.rs @@ -2,6 +2,9 @@ // Making this compile was a feature request in rust-lang/rust#34117 but this is currently // "working as intended". Allowing "deep pointer coercion" seems footgun-prone, and would // require proceeding carefully. + +//@ dont-require-annotations: NOTE + use std::ops::{Deref, DerefMut}; struct Foo(i32); @@ -34,7 +37,7 @@ fn make_foo(_: *mut *mut Foo) { fn main() { let mut result: SmartPtr = SmartPtr(std::ptr::null_mut()); make_foo(&mut &mut *result); //~ ERROR mismatched types - //~^ expected `*mut *mut Foo`, found `&mut &mut Foo` + //~^ NOTE expected `*mut *mut Foo`, found `&mut &mut Foo` make_foo(out(&mut result)); // works, but makes one wonder why above coercion cannot happen } diff --git a/tests/ui/coercion/mut-mut-wont-coerce.stderr b/tests/ui/coercion/mut-mut-wont-coerce.stderr index 5daf9cbd3d3..c37ea6af5a8 100644 --- a/tests/ui/coercion/mut-mut-wont-coerce.stderr +++ b/tests/ui/coercion/mut-mut-wont-coerce.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/mut-mut-wont-coerce.rs:36:14 + --> $DIR/mut-mut-wont-coerce.rs:39:14 | LL | make_foo(&mut &mut *result); | -------- ^^^^^^^^^^^^^^^^^ expected `*mut *mut Foo`, found `&mut &mut Foo` @@ -9,7 +9,7 @@ LL | make_foo(&mut &mut *result); = note: expected raw pointer `*mut *mut Foo` found mutable reference `&mut &mut Foo` note: function defined here - --> $DIR/mut-mut-wont-coerce.rs:30:4 + --> $DIR/mut-mut-wont-coerce.rs:33:4 | LL | fn make_foo(_: *mut *mut Foo) { | ^^^^^^^^ ---------------- diff --git a/tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.rs b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.rs index 761a6387a24..e743b78fd13 100644 --- a/tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.rs +++ b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.rs @@ -9,11 +9,11 @@ struct CantParam(ImplementsConstParamTy); impl std::marker::UnsizedConstParamTy for CantParam {} //~^ error: the type `CantParam` does not `#[derive(PartialEq)]` -//~| the trait bound `CantParam: Eq` is not satisfied +//~| ERROR the trait bound `CantParam: Eq` is not satisfied #[derive(std::marker::UnsizedConstParamTy)] //~^ error: the type `CantParamDerive` does not `#[derive(PartialEq)]` -//~| the trait bound `CantParamDerive: Eq` is not satisfied +//~| ERROR the trait bound `CantParamDerive: Eq` is not satisfied struct CantParamDerive(ImplementsConstParamTy); fn check() {} diff --git a/tests/ui/const-generics/defaults/mismatch.rs b/tests/ui/const-generics/defaults/mismatch.rs index 3e35c2060b1..bbedf247bd0 100644 --- a/tests/ui/const-generics/defaults/mismatch.rs +++ b/tests/ui/const-generics/defaults/mismatch.rs @@ -1,3 +1,5 @@ +//@ dont-require-annotations: NOTE + pub struct Example; pub struct Example2(T); pub struct Example3(T); @@ -6,17 +8,17 @@ pub struct Example4; fn main() { let e: Example<13> = (); //~^ ERROR mismatched types - //~| expected struct `Example` + //~| NOTE expected struct `Example` let e: Example2 = (); //~^ ERROR mismatched types - //~| expected struct `Example2` + //~| NOTE expected struct `Example2` let e: Example3<13, u32> = (); //~^ ERROR mismatched types - //~| expected struct `Example3` + //~| NOTE expected struct `Example3` let e: Example3<7> = (); //~^ ERROR mismatched types - //~| expected struct `Example3<7>` + //~| NOTE expected struct `Example3<7>` let e: Example4<7> = (); //~^ ERROR mismatched types - //~| expected struct `Example4<7>` + //~| NOTE expected struct `Example4<7>` } diff --git a/tests/ui/const-generics/defaults/mismatch.stderr b/tests/ui/const-generics/defaults/mismatch.stderr index 9c4f0bc950b..8cedd1a28c4 100644 --- a/tests/ui/const-generics/defaults/mismatch.stderr +++ b/tests/ui/const-generics/defaults/mismatch.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/mismatch.rs:7:26 + --> $DIR/mismatch.rs:9:26 | LL | let e: Example<13> = (); | ----------- ^^ expected `Example`, found `()` @@ -10,7 +10,7 @@ LL | let e: Example<13> = (); found unit type `()` error[E0308]: mismatched types - --> $DIR/mismatch.rs:10:32 + --> $DIR/mismatch.rs:12:32 | LL | let e: Example2 = (); | ----------------- ^^ expected `Example2`, found `()` @@ -21,7 +21,7 @@ LL | let e: Example2 = (); found unit type `()` error[E0308]: mismatched types - --> $DIR/mismatch.rs:13:32 + --> $DIR/mismatch.rs:15:32 | LL | let e: Example3<13, u32> = (); | ----------------- ^^ expected `Example3`, found `()` @@ -32,7 +32,7 @@ LL | let e: Example3<13, u32> = (); found unit type `()` error[E0308]: mismatched types - --> $DIR/mismatch.rs:16:26 + --> $DIR/mismatch.rs:18:26 | LL | let e: Example3<7> = (); | ----------- ^^ expected `Example3<7>`, found `()` @@ -43,7 +43,7 @@ LL | let e: Example3<7> = (); found unit type `()` error[E0308]: mismatched types - --> $DIR/mismatch.rs:19:26 + --> $DIR/mismatch.rs:21:26 | LL | let e: Example4<7> = (); | ----------- ^^ expected `Example4<7>`, found `()` diff --git a/tests/ui/const-generics/issues/issue-100313.rs b/tests/ui/const-generics/issues/issue-100313.rs index 7ce2a3b908c..7d43d7bee34 100644 --- a/tests/ui/const-generics/issues/issue-100313.rs +++ b/tests/ui/const-generics/issues/issue-100313.rs @@ -1,3 +1,5 @@ +//@ dont-require-annotations: NOTE + #![allow(incomplete_features)] #![feature(adt_const_params, unsized_const_params)] @@ -6,7 +8,7 @@ struct T; impl T { const fn set_false(&self) { unsafe { - *(B as *const bool as *mut bool) = false; //~ inside `T + *(B as *const bool as *mut bool) = false; //~ NOTE inside `T } } } diff --git a/tests/ui/const-generics/issues/issue-100313.stderr b/tests/ui/const-generics/issues/issue-100313.stderr index 03a658a83af..98c3ec5379b 100644 --- a/tests/ui/const-generics/issues/issue-100313.stderr +++ b/tests/ui/const-generics/issues/issue-100313.stderr @@ -1,11 +1,11 @@ error[E0080]: evaluation of constant value failed - --> $DIR/issue-100313.rs:16:5 + --> $DIR/issue-100313.rs:18:5 | LL | x.set_false(); | ^^^^^^^^^^^^^ writing to ALLOC0 which is read-only | note: inside `T::<&true>::set_false` - --> $DIR/issue-100313.rs:9:13 + --> $DIR/issue-100313.rs:11:13 | LL | *(B as *const bool as *mut bool) = false; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the failure occurred here diff --git a/tests/ui/const-generics/min_const_generics/invalid-patterns.32bit.stderr b/tests/ui/const-generics/min_const_generics/invalid-patterns.32bit.stderr index 11a824ba73b..d1f3b08dd36 100644 --- a/tests/ui/const-generics/min_const_generics/invalid-patterns.32bit.stderr +++ b/tests/ui/const-generics/min_const_generics/invalid-patterns.32bit.stderr @@ -1,11 +1,11 @@ error[E0080]: evaluation of constant value failed - --> $DIR/invalid-patterns.rs:38:32 + --> $DIR/invalid-patterns.rs:40:32 | LL | get_flag::(); | ^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory error[E0080]: it is undefined behavior to use this value - --> $DIR/invalid-patterns.rs:41:14 + --> $DIR/invalid-patterns.rs:43:14 | LL | get_flag::<{ unsafe { bool_raw.boolean } }, 'z'>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0x42, but expected a boolean @@ -16,7 +16,7 @@ LL | get_flag::<{ unsafe { bool_raw.boolean } }, 'z'>(); } error[E0080]: it is undefined behavior to use this value - --> $DIR/invalid-patterns.rs:43:14 + --> $DIR/invalid-patterns.rs:45:14 | LL | get_flag::<{ unsafe { bool_raw.boolean } }, { unsafe { char_raw.character } }>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0x42, but expected a boolean @@ -27,31 +27,31 @@ LL | get_flag::<{ unsafe { bool_raw.boolean } }, { unsafe { char_raw.character } error[E0080]: evaluation of constant value failed - --> $DIR/invalid-patterns.rs:43:58 + --> $DIR/invalid-patterns.rs:45:58 | LL | get_flag::<{ unsafe { bool_raw.boolean } }, { unsafe { char_raw.character } }>(); | ^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory error[E0308]: mismatched types - --> $DIR/invalid-patterns.rs:29:21 + --> $DIR/invalid-patterns.rs:31:21 | LL | get_flag::(); | ^^^^ expected `char`, found `u8` error[E0308]: mismatched types - --> $DIR/invalid-patterns.rs:31:14 + --> $DIR/invalid-patterns.rs:33:14 | LL | get_flag::<7, 'c'>(); | ^ expected `bool`, found integer error[E0308]: mismatched types - --> $DIR/invalid-patterns.rs:33:14 + --> $DIR/invalid-patterns.rs:35:14 | LL | get_flag::<42, 0x5ad>(); | ^^ expected `bool`, found integer error[E0308]: mismatched types - --> $DIR/invalid-patterns.rs:33:18 + --> $DIR/invalid-patterns.rs:35:18 | LL | get_flag::<42, 0x5ad>(); | ^^^^^ expected `char`, found `u8` diff --git a/tests/ui/const-generics/min_const_generics/invalid-patterns.64bit.stderr b/tests/ui/const-generics/min_const_generics/invalid-patterns.64bit.stderr index 11a824ba73b..d1f3b08dd36 100644 --- a/tests/ui/const-generics/min_const_generics/invalid-patterns.64bit.stderr +++ b/tests/ui/const-generics/min_const_generics/invalid-patterns.64bit.stderr @@ -1,11 +1,11 @@ error[E0080]: evaluation of constant value failed - --> $DIR/invalid-patterns.rs:38:32 + --> $DIR/invalid-patterns.rs:40:32 | LL | get_flag::(); | ^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory error[E0080]: it is undefined behavior to use this value - --> $DIR/invalid-patterns.rs:41:14 + --> $DIR/invalid-patterns.rs:43:14 | LL | get_flag::<{ unsafe { bool_raw.boolean } }, 'z'>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0x42, but expected a boolean @@ -16,7 +16,7 @@ LL | get_flag::<{ unsafe { bool_raw.boolean } }, 'z'>(); } error[E0080]: it is undefined behavior to use this value - --> $DIR/invalid-patterns.rs:43:14 + --> $DIR/invalid-patterns.rs:45:14 | LL | get_flag::<{ unsafe { bool_raw.boolean } }, { unsafe { char_raw.character } }>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0x42, but expected a boolean @@ -27,31 +27,31 @@ LL | get_flag::<{ unsafe { bool_raw.boolean } }, { unsafe { char_raw.character } error[E0080]: evaluation of constant value failed - --> $DIR/invalid-patterns.rs:43:58 + --> $DIR/invalid-patterns.rs:45:58 | LL | get_flag::<{ unsafe { bool_raw.boolean } }, { unsafe { char_raw.character } }>(); | ^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory error[E0308]: mismatched types - --> $DIR/invalid-patterns.rs:29:21 + --> $DIR/invalid-patterns.rs:31:21 | LL | get_flag::(); | ^^^^ expected `char`, found `u8` error[E0308]: mismatched types - --> $DIR/invalid-patterns.rs:31:14 + --> $DIR/invalid-patterns.rs:33:14 | LL | get_flag::<7, 'c'>(); | ^ expected `bool`, found integer error[E0308]: mismatched types - --> $DIR/invalid-patterns.rs:33:14 + --> $DIR/invalid-patterns.rs:35:14 | LL | get_flag::<42, 0x5ad>(); | ^^ expected `bool`, found integer error[E0308]: mismatched types - --> $DIR/invalid-patterns.rs:33:18 + --> $DIR/invalid-patterns.rs:35:18 | LL | get_flag::<42, 0x5ad>(); | ^^^^^ expected `char`, found `u8` diff --git a/tests/ui/const-generics/min_const_generics/invalid-patterns.rs b/tests/ui/const-generics/min_const_generics/invalid-patterns.rs index a9d2a8a5dd7..10b0d742a0a 100644 --- a/tests/ui/const-generics/min_const_generics/invalid-patterns.rs +++ b/tests/ui/const-generics/min_const_generics/invalid-patterns.rs @@ -1,4 +1,6 @@ //@ stderr-per-bitwidth +//@ dont-require-annotations: NOTE + use std::mem::transmute; fn get_flag() -> Option { @@ -37,11 +39,11 @@ fn main() { get_flag::(); //~^ ERROR evaluation of constant value failed - //~| uninitialized + //~| NOTE uninitialized get_flag::<{ unsafe { bool_raw.boolean } }, 'z'>(); //~^ ERROR it is undefined behavior get_flag::<{ unsafe { bool_raw.boolean } }, { unsafe { char_raw.character } }>(); //~^ ERROR evaluation of constant value failed - //~| uninitialized + //~| NOTE uninitialized //~| ERROR it is undefined behavior } diff --git a/tests/ui/consts/const-array-oob.rs b/tests/ui/consts/const-array-oob.rs index cf3db077e36..4b457d1c23c 100644 --- a/tests/ui/consts/const-array-oob.rs +++ b/tests/ui/consts/const-array-oob.rs @@ -1,10 +1,11 @@ const FOO: [usize; 3] = [1, 2, 3]; const BAR: usize = FOO[5]; //~^ ERROR: evaluation of constant value failed +//~| NOTE index out of bounds: the length is 3 but the index is 5 const BLUB: [u32; FOO[4]] = [5, 6]; //~^ ERROR evaluation of constant value failed [E0080] -//~| index out of bounds: the length is 3 but the index is 4 +//~| NOTE index out of bounds: the length is 3 but the index is 4 fn main() { let _ = BAR; diff --git a/tests/ui/consts/const-array-oob.stderr b/tests/ui/consts/const-array-oob.stderr index be31f183b9a..89427c051e7 100644 --- a/tests/ui/consts/const-array-oob.stderr +++ b/tests/ui/consts/const-array-oob.stderr @@ -1,5 +1,5 @@ error[E0080]: evaluation of constant value failed - --> $DIR/const-array-oob.rs:5:19 + --> $DIR/const-array-oob.rs:6:19 | LL | const BLUB: [u32; FOO[4]] = [5, 6]; | ^^^^^^ index out of bounds: the length is 3 but the index is 4 diff --git a/tests/ui/consts/const-err-late.rs b/tests/ui/consts/const-err-late.rs index 6dff2c101a0..f8bea388109 100644 --- a/tests/ui/consts/const-err-late.rs +++ b/tests/ui/consts/const-err-late.rs @@ -1,5 +1,6 @@ //@ build-fail //@ compile-flags: -C overflow-checks=on +//@ dont-require-annotations: NOTE #![allow(arithmetic_overflow, unconditional_panic)] @@ -16,5 +17,5 @@ impl S { } fn main() { - black_box((S::::FOO, S::::FOO)); //~ constant + black_box((S::::FOO, S::::FOO)); //~ NOTE constant } diff --git a/tests/ui/consts/const-err-late.stderr b/tests/ui/consts/const-err-late.stderr index 53badeafa35..0c021e8761e 100644 --- a/tests/ui/consts/const-err-late.stderr +++ b/tests/ui/consts/const-err-late.stderr @@ -1,29 +1,29 @@ error[E0080]: evaluation of `S::::FOO` failed - --> $DIR/const-err-late.rs:13:21 + --> $DIR/const-err-late.rs:14:21 | LL | const FOO: u8 = [5u8][1]; | ^^^^^^^^ index out of bounds: the length is 1 but the index is 1 note: erroneous constant encountered - --> $DIR/const-err-late.rs:19:16 + --> $DIR/const-err-late.rs:20:16 | LL | black_box((S::::FOO, S::::FOO)); | ^^^^^^^^^^^^^ error[E0080]: evaluation of `S::::FOO` failed - --> $DIR/const-err-late.rs:13:21 + --> $DIR/const-err-late.rs:14:21 | LL | const FOO: u8 = [5u8][1]; | ^^^^^^^^ index out of bounds: the length is 1 but the index is 1 note: erroneous constant encountered - --> $DIR/const-err-late.rs:19:31 + --> $DIR/const-err-late.rs:20:31 | LL | black_box((S::::FOO, S::::FOO)); | ^^^^^^^^^^^^^ note: erroneous constant encountered - --> $DIR/const-err-late.rs:19:16 + --> $DIR/const-err-late.rs:20:16 | LL | black_box((S::::FOO, S::::FOO)); | ^^^^^^^^^^^^^ @@ -31,7 +31,7 @@ LL | black_box((S::::FOO, S::::FOO)); = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` note: erroneous constant encountered - --> $DIR/const-err-late.rs:19:31 + --> $DIR/const-err-late.rs:20:31 | LL | black_box((S::::FOO, S::::FOO)); | ^^^^^^^^^^^^^ diff --git a/tests/ui/consts/const-err-multi.rs b/tests/ui/consts/const-err-multi.rs index b265bc4c4d8..f21cc97345c 100644 --- a/tests/ui/consts/const-err-multi.rs +++ b/tests/ui/consts/const-err-multi.rs @@ -1,11 +1,12 @@ pub const A: i8 = -i8::MIN; //~^ ERROR constant +//~| NOTE attempt to negate `i8::MIN`, which would overflow pub const B: i8 = A; -//~^ constant +//~^ NOTE constant pub const C: u8 = A as u8; -//~^ constant +//~^ NOTE constant pub const D: i8 = 50 - A; -//~^ constant +//~^ NOTE constant fn main() { let _ = (A, B, C, D); diff --git a/tests/ui/consts/const-err-multi.stderr b/tests/ui/consts/const-err-multi.stderr index 2fe0b9bb463..c60be59b87d 100644 --- a/tests/ui/consts/const-err-multi.stderr +++ b/tests/ui/consts/const-err-multi.stderr @@ -5,19 +5,19 @@ LL | pub const A: i8 = -i8::MIN; | ^^^^^^^^ attempt to negate `i8::MIN`, which would overflow note: erroneous constant encountered - --> $DIR/const-err-multi.rs:3:19 + --> $DIR/const-err-multi.rs:4:19 | LL | pub const B: i8 = A; | ^ note: erroneous constant encountered - --> $DIR/const-err-multi.rs:5:19 + --> $DIR/const-err-multi.rs:6:19 | LL | pub const C: u8 = A as u8; | ^ note: erroneous constant encountered - --> $DIR/const-err-multi.rs:7:24 + --> $DIR/const-err-multi.rs:8:24 | LL | pub const D: i8 = 50 - A; | ^ diff --git a/tests/ui/consts/const-eval/const-eval-overflow-4b.rs b/tests/ui/consts/const-eval/const-eval-overflow-4b.rs index ce9c980de0d..3ad23a515a7 100644 --- a/tests/ui/consts/const-eval/const-eval-overflow-4b.rs +++ b/tests/ui/consts/const-eval/const-eval-overflow-4b.rs @@ -3,12 +3,14 @@ // // This test is checking the count in an array type. +//@ dont-require-annotations: NOTE + #![allow(unused_imports)] const A_I8_T : [u32; (i8::MAX as i8 + 1u8) as usize] //~^ ERROR mismatched types - //~| expected `i8`, found `u8` + //~| NOTE expected `i8`, found `u8` //~| ERROR cannot add `u8` to `i8` = [0; (i8::MAX as usize) + 1]; diff --git a/tests/ui/consts/const-eval/const-eval-overflow-4b.stderr b/tests/ui/consts/const-eval/const-eval-overflow-4b.stderr index 399f21a9894..1a0832b8ba0 100644 --- a/tests/ui/consts/const-eval/const-eval-overflow-4b.stderr +++ b/tests/ui/consts/const-eval/const-eval-overflow-4b.stderr @@ -1,11 +1,11 @@ error[E0308]: mismatched types - --> $DIR/const-eval-overflow-4b.rs:9:30 + --> $DIR/const-eval-overflow-4b.rs:11:30 | LL | : [u32; (i8::MAX as i8 + 1u8) as usize] | ^^^ expected `i8`, found `u8` error[E0277]: cannot add `u8` to `i8` - --> $DIR/const-eval-overflow-4b.rs:9:28 + --> $DIR/const-eval-overflow-4b.rs:11:28 | LL | : [u32; (i8::MAX as i8 + 1u8) as usize] | ^ no implementation for `i8 + u8` @@ -18,13 +18,13 @@ LL | : [u32; (i8::MAX as i8 + 1u8) as usize] `i8` implements `Add` error[E0604]: only `u8` can be cast as `char`, not `i8` - --> $DIR/const-eval-overflow-4b.rs:22:13 + --> $DIR/const-eval-overflow-4b.rs:24:13 | LL | : [u32; 5i8 as char as usize] | ^^^^^^^^^^^ invalid cast | help: try casting from `u8` instead - --> $DIR/const-eval-overflow-4b.rs:22:13 + --> $DIR/const-eval-overflow-4b.rs:24:13 | LL | : [u32; 5i8 as char as usize] | ^^^^^^^^^^^ diff --git a/tests/ui/consts/const-eval/const-pointer-values-in-various-types.64bit.stderr b/tests/ui/consts/const-eval/const-pointer-values-in-various-types.64bit.stderr index f099bc7ef7c..3eccd596274 100644 --- a/tests/ui/consts/const-eval/const-pointer-values-in-various-types.64bit.stderr +++ b/tests/ui/consts/const-eval/const-pointer-values-in-various-types.64bit.stderr @@ -1,5 +1,5 @@ error[E0080]: evaluation of constant value failed - --> $DIR/const-pointer-values-in-various-types.rs:26:49 + --> $DIR/const-pointer-values-in-various-types.rs:27:49 | LL | const I32_REF_USIZE_UNION: usize = unsafe { Nonsense { int_32_ref: &3 }.u }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into integer @@ -8,7 +8,7 @@ LL | const I32_REF_USIZE_UNION: usize = unsafe { Nonsense { int_32_ref: &3 } = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported error[E0080]: evaluation of constant value failed - --> $DIR/const-pointer-values-in-various-types.rs:29:43 + --> $DIR/const-pointer-values-in-various-types.rs:30:43 | LL | const I32_REF_U8_UNION: u8 = unsafe { Nonsense { int_32_ref: &3 }.uint_8 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into integer @@ -17,7 +17,7 @@ LL | const I32_REF_U8_UNION: u8 = unsafe { Nonsense { int_32_ref: &3 }.uint_ = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported error[E0080]: evaluation of constant value failed - --> $DIR/const-pointer-values-in-various-types.rs:32:45 + --> $DIR/const-pointer-values-in-various-types.rs:33:45 | LL | const I32_REF_U16_UNION: u16 = unsafe { Nonsense { int_32_ref: &3 }.uint_16 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into integer @@ -26,7 +26,7 @@ LL | const I32_REF_U16_UNION: u16 = unsafe { Nonsense { int_32_ref: &3 }.uin = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported error[E0080]: evaluation of constant value failed - --> $DIR/const-pointer-values-in-various-types.rs:35:45 + --> $DIR/const-pointer-values-in-various-types.rs:36:45 | LL | const I32_REF_U32_UNION: u32 = unsafe { Nonsense { int_32_ref: &3 }.uint_32 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into integer @@ -35,7 +35,7 @@ LL | const I32_REF_U32_UNION: u32 = unsafe { Nonsense { int_32_ref: &3 }.uin = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported error[E0080]: evaluation of constant value failed - --> $DIR/const-pointer-values-in-various-types.rs:38:45 + --> $DIR/const-pointer-values-in-various-types.rs:39:45 | LL | const I32_REF_U64_UNION: u64 = unsafe { Nonsense { int_32_ref: &3 }.uint_64 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into integer @@ -44,13 +44,13 @@ LL | const I32_REF_U64_UNION: u64 = unsafe { Nonsense { int_32_ref: &3 }.uin = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported error[E0080]: evaluation of constant value failed - --> $DIR/const-pointer-values-in-various-types.rs:41:47 + --> $DIR/const-pointer-values-in-various-types.rs:42:47 | LL | const I32_REF_U128_UNION: u128 = unsafe { Nonsense { int_32_ref: &3 }.uint_128 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory error[E0080]: evaluation of constant value failed - --> $DIR/const-pointer-values-in-various-types.rs:45:43 + --> $DIR/const-pointer-values-in-various-types.rs:46:43 | LL | const I32_REF_I8_UNION: i8 = unsafe { Nonsense { int_32_ref: &3 }.int_8 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into integer @@ -59,7 +59,7 @@ LL | const I32_REF_I8_UNION: i8 = unsafe { Nonsense { int_32_ref: &3 }.int_8 = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported error[E0080]: evaluation of constant value failed - --> $DIR/const-pointer-values-in-various-types.rs:48:45 + --> $DIR/const-pointer-values-in-various-types.rs:49:45 | LL | const I32_REF_I16_UNION: i16 = unsafe { Nonsense { int_32_ref: &3 }.int_16 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into integer @@ -68,7 +68,7 @@ LL | const I32_REF_I16_UNION: i16 = unsafe { Nonsense { int_32_ref: &3 }.int = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported error[E0080]: evaluation of constant value failed - --> $DIR/const-pointer-values-in-various-types.rs:51:45 + --> $DIR/const-pointer-values-in-various-types.rs:52:45 | LL | const I32_REF_I32_UNION: i32 = unsafe { Nonsense { int_32_ref: &3 }.int_32 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into integer @@ -77,7 +77,7 @@ LL | const I32_REF_I32_UNION: i32 = unsafe { Nonsense { int_32_ref: &3 }.int = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported error[E0080]: evaluation of constant value failed - --> $DIR/const-pointer-values-in-various-types.rs:54:45 + --> $DIR/const-pointer-values-in-various-types.rs:55:45 | LL | const I32_REF_I64_UNION: i64 = unsafe { Nonsense { int_32_ref: &3 }.int_64 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into integer @@ -86,13 +86,13 @@ LL | const I32_REF_I64_UNION: i64 = unsafe { Nonsense { int_32_ref: &3 }.int = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported error[E0080]: evaluation of constant value failed - --> $DIR/const-pointer-values-in-various-types.rs:57:47 + --> $DIR/const-pointer-values-in-various-types.rs:58:47 | LL | const I32_REF_I128_UNION: i128 = unsafe { Nonsense { int_32_ref: &3 }.int_128 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory error[E0080]: evaluation of constant value failed - --> $DIR/const-pointer-values-in-various-types.rs:61:45 + --> $DIR/const-pointer-values-in-various-types.rs:62:45 | LL | const I32_REF_F32_UNION: f32 = unsafe { Nonsense { int_32_ref: &3 }.float_32 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into integer @@ -101,7 +101,7 @@ LL | const I32_REF_F32_UNION: f32 = unsafe { Nonsense { int_32_ref: &3 }.flo = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported error[E0080]: evaluation of constant value failed - --> $DIR/const-pointer-values-in-various-types.rs:64:45 + --> $DIR/const-pointer-values-in-various-types.rs:65:45 | LL | const I32_REF_F64_UNION: f64 = unsafe { Nonsense { int_32_ref: &3 }.float_64 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into integer @@ -110,7 +110,7 @@ LL | const I32_REF_F64_UNION: f64 = unsafe { Nonsense { int_32_ref: &3 }.flo = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported error[E0080]: evaluation of constant value failed - --> $DIR/const-pointer-values-in-various-types.rs:67:47 + --> $DIR/const-pointer-values-in-various-types.rs:68:47 | LL | const I32_REF_BOOL_UNION: bool = unsafe { Nonsense { int_32_ref: &3 }.truthy_falsey }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into integer @@ -119,7 +119,7 @@ LL | const I32_REF_BOOL_UNION: bool = unsafe { Nonsense { int_32_ref: &3 }.t = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported error[E0080]: evaluation of constant value failed - --> $DIR/const-pointer-values-in-various-types.rs:70:47 + --> $DIR/const-pointer-values-in-various-types.rs:71:47 | LL | const I32_REF_CHAR_UNION: char = unsafe { Nonsense { int_32_ref: &3 }.character }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into integer @@ -128,7 +128,7 @@ LL | const I32_REF_CHAR_UNION: char = unsafe { Nonsense { int_32_ref: &3 }.c = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported error[E0080]: evaluation of constant value failed - --> $DIR/const-pointer-values-in-various-types.rs:73:39 + --> $DIR/const-pointer-values-in-various-types.rs:74:39 | LL | const STR_U8_UNION: u8 = unsafe { Nonsense { stringy: "3" }.uint_8 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into integer @@ -137,7 +137,7 @@ LL | const STR_U8_UNION: u8 = unsafe { Nonsense { stringy: "3" }.uint_8 }; = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported error[E0080]: evaluation of constant value failed - --> $DIR/const-pointer-values-in-various-types.rs:76:41 + --> $DIR/const-pointer-values-in-various-types.rs:77:41 | LL | const STR_U16_UNION: u16 = unsafe { Nonsense { stringy: "3" }.uint_16 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into integer @@ -146,7 +146,7 @@ LL | const STR_U16_UNION: u16 = unsafe { Nonsense { stringy: "3" }.uint_16 } = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported error[E0080]: evaluation of constant value failed - --> $DIR/const-pointer-values-in-various-types.rs:79:41 + --> $DIR/const-pointer-values-in-various-types.rs:80:41 | LL | const STR_U32_UNION: u32 = unsafe { Nonsense { stringy: "3" }.uint_32 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into integer @@ -155,7 +155,7 @@ LL | const STR_U32_UNION: u32 = unsafe { Nonsense { stringy: "3" }.uint_32 } = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported error[E0080]: evaluation of constant value failed - --> $DIR/const-pointer-values-in-various-types.rs:82:41 + --> $DIR/const-pointer-values-in-various-types.rs:83:41 | LL | const STR_U64_UNION: u64 = unsafe { Nonsense { stringy: "3" }.uint_64 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into integer @@ -164,7 +164,7 @@ LL | const STR_U64_UNION: u64 = unsafe { Nonsense { stringy: "3" }.uint_64 } = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported error[E0080]: evaluation of constant value failed - --> $DIR/const-pointer-values-in-various-types.rs:85:43 + --> $DIR/const-pointer-values-in-various-types.rs:86:43 | LL | const STR_U128_UNION: u128 = unsafe { Nonsense { stringy: "3" }.uint_128 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into integer @@ -173,7 +173,7 @@ LL | const STR_U128_UNION: u128 = unsafe { Nonsense { stringy: "3" }.uint_12 = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported error[E0080]: evaluation of constant value failed - --> $DIR/const-pointer-values-in-various-types.rs:88:39 + --> $DIR/const-pointer-values-in-various-types.rs:89:39 | LL | const STR_I8_UNION: i8 = unsafe { Nonsense { stringy: "3" }.int_8 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into integer @@ -182,7 +182,7 @@ LL | const STR_I8_UNION: i8 = unsafe { Nonsense { stringy: "3" }.int_8 }; = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported error[E0080]: evaluation of constant value failed - --> $DIR/const-pointer-values-in-various-types.rs:91:41 + --> $DIR/const-pointer-values-in-various-types.rs:92:41 | LL | const STR_I16_UNION: i16 = unsafe { Nonsense { stringy: "3" }.int_16 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into integer @@ -191,7 +191,7 @@ LL | const STR_I16_UNION: i16 = unsafe { Nonsense { stringy: "3" }.int_16 }; = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported error[E0080]: evaluation of constant value failed - --> $DIR/const-pointer-values-in-various-types.rs:94:41 + --> $DIR/const-pointer-values-in-various-types.rs:95:41 | LL | const STR_I32_UNION: i32 = unsafe { Nonsense { stringy: "3" }.int_32 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into integer @@ -200,7 +200,7 @@ LL | const STR_I32_UNION: i32 = unsafe { Nonsense { stringy: "3" }.int_32 }; = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported error[E0080]: evaluation of constant value failed - --> $DIR/const-pointer-values-in-various-types.rs:97:41 + --> $DIR/const-pointer-values-in-various-types.rs:98:41 | LL | const STR_I64_UNION: i64 = unsafe { Nonsense { stringy: "3" }.int_64 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into integer @@ -209,7 +209,7 @@ LL | const STR_I64_UNION: i64 = unsafe { Nonsense { stringy: "3" }.int_64 }; = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported error[E0080]: evaluation of constant value failed - --> $DIR/const-pointer-values-in-various-types.rs:100:43 + --> $DIR/const-pointer-values-in-various-types.rs:101:43 | LL | const STR_I128_UNION: i128 = unsafe { Nonsense { stringy: "3" }.int_128 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into integer @@ -218,7 +218,7 @@ LL | const STR_I128_UNION: i128 = unsafe { Nonsense { stringy: "3" }.int_128 = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported error[E0080]: evaluation of constant value failed - --> $DIR/const-pointer-values-in-various-types.rs:103:41 + --> $DIR/const-pointer-values-in-various-types.rs:104:41 | LL | const STR_F32_UNION: f32 = unsafe { Nonsense { stringy: "3" }.float_32 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into integer @@ -227,7 +227,7 @@ LL | const STR_F32_UNION: f32 = unsafe { Nonsense { stringy: "3" }.float_32 = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported error[E0080]: evaluation of constant value failed - --> $DIR/const-pointer-values-in-various-types.rs:106:41 + --> $DIR/const-pointer-values-in-various-types.rs:107:41 | LL | const STR_F64_UNION: f64 = unsafe { Nonsense { stringy: "3" }.float_64 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into integer @@ -236,7 +236,7 @@ LL | const STR_F64_UNION: f64 = unsafe { Nonsense { stringy: "3" }.float_64 = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported error[E0080]: evaluation of constant value failed - --> $DIR/const-pointer-values-in-various-types.rs:109:43 + --> $DIR/const-pointer-values-in-various-types.rs:110:43 | LL | const STR_BOOL_UNION: bool = unsafe { Nonsense { stringy: "3" }.truthy_falsey }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into integer @@ -245,7 +245,7 @@ LL | const STR_BOOL_UNION: bool = unsafe { Nonsense { stringy: "3" }.truthy_ = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported error[E0080]: evaluation of constant value failed - --> $DIR/const-pointer-values-in-various-types.rs:112:43 + --> $DIR/const-pointer-values-in-various-types.rs:113:43 | LL | const STR_CHAR_UNION: char = unsafe { Nonsense { stringy: "3" }.character }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into integer diff --git a/tests/ui/consts/const-eval/const-pointer-values-in-various-types.rs b/tests/ui/consts/const-eval/const-pointer-values-in-various-types.rs index d6b6d427807..ce7380cd155 100644 --- a/tests/ui/consts/const-eval/const-pointer-values-in-various-types.rs +++ b/tests/ui/consts/const-eval/const-pointer-values-in-various-types.rs @@ -1,5 +1,6 @@ //@ only-x86_64 //@ stderr-per-bitwidth +//@ dont-require-annotations: NOTE #[repr(C)] union Nonsense { @@ -40,7 +41,7 @@ fn main() { const I32_REF_U128_UNION: u128 = unsafe { Nonsense { int_32_ref: &3 }.uint_128 }; //~^ ERROR evaluation of constant value failed - //~| uninitialized + //~| NOTE uninitialized const I32_REF_I8_UNION: i8 = unsafe { Nonsense { int_32_ref: &3 }.int_8 }; //~^ ERROR evaluation of constant value failed @@ -56,7 +57,7 @@ fn main() { const I32_REF_I128_UNION: i128 = unsafe { Nonsense { int_32_ref: &3 }.int_128 }; //~^ ERROR evaluation of constant value failed - //~| uninitialized + //~| NOTE uninitialized const I32_REF_F32_UNION: f32 = unsafe { Nonsense { int_32_ref: &3 }.float_32 }; //~^ ERROR evaluation of constant value failed diff --git a/tests/ui/consts/const-eval/heap/alloc_intrinsic_errors.rs b/tests/ui/consts/const-eval/heap/alloc_intrinsic_errors.rs index c1a544031c2..b47e2b3c1ed 100644 --- a/tests/ui/consts/const-eval/heap/alloc_intrinsic_errors.rs +++ b/tests/ui/consts/const-eval/heap/alloc_intrinsic_errors.rs @@ -1,11 +1,13 @@ +//@ dont-require-annotations: NOTE + #![feature(core_intrinsics)] #![feature(const_heap)] use std::intrinsics; -const FOO: i32 = foo(); //~ error: evaluation of constant value failed +const FOO: i32 = foo(); //~ ERROR evaluation of constant value failed const fn foo() -> i32 { unsafe { - let _ = intrinsics::const_allocate(4, 3) as *mut i32; //~ inside `foo` + let _ = intrinsics::const_allocate(4, 3) as *mut i32; //~ NOTE inside `foo` } 1 } diff --git a/tests/ui/consts/const-eval/heap/alloc_intrinsic_errors.stderr b/tests/ui/consts/const-eval/heap/alloc_intrinsic_errors.stderr index e1cb7a83996..9f7546df3a2 100644 --- a/tests/ui/consts/const-eval/heap/alloc_intrinsic_errors.stderr +++ b/tests/ui/consts/const-eval/heap/alloc_intrinsic_errors.stderr @@ -1,11 +1,11 @@ error[E0080]: evaluation of constant value failed - --> $DIR/alloc_intrinsic_errors.rs:5:18 + --> $DIR/alloc_intrinsic_errors.rs:7:18 | LL | const FOO: i32 = foo(); | ^^^^^ invalid align passed to `const_allocate`: 3 is not a power of 2 | note: inside `foo` - --> $DIR/alloc_intrinsic_errors.rs:8:17 + --> $DIR/alloc_intrinsic_errors.rs:10:17 | LL | let _ = intrinsics::const_allocate(4, 3) as *mut i32; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the failure occurred here diff --git a/tests/ui/consts/const-eval/issue-44578.rs b/tests/ui/consts/const-eval/issue-44578.rs index 945bf93f8fa..565e1d3825b 100644 --- a/tests/ui/consts/const-eval/issue-44578.rs +++ b/tests/ui/consts/const-eval/issue-44578.rs @@ -1,4 +1,5 @@ //@ build-fail +//@ dont-require-annotations: NOTE trait Foo { const AMT: usize; @@ -23,5 +24,5 @@ impl Foo for u16 { fn main() { println!("{}", as Foo>::AMT); - //~^ constant + //~^ NOTE constant } diff --git a/tests/ui/consts/const-eval/issue-44578.stderr b/tests/ui/consts/const-eval/issue-44578.stderr index 7d5cf86d396..5093cec81c7 100644 --- a/tests/ui/consts/const-eval/issue-44578.stderr +++ b/tests/ui/consts/const-eval/issue-44578.stderr @@ -1,17 +1,17 @@ error[E0080]: evaluation of ` as Foo>::AMT` failed - --> $DIR/issue-44578.rs:13:24 + --> $DIR/issue-44578.rs:14:24 | LL | const AMT: usize = [A::AMT][(A::AMT > B::AMT) as usize]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ index out of bounds: the length is 1 but the index is 1 note: erroneous constant encountered - --> $DIR/issue-44578.rs:25:20 + --> $DIR/issue-44578.rs:26:20 | LL | println!("{}", as Foo>::AMT); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ note: erroneous constant encountered - --> $DIR/issue-44578.rs:25:20 + --> $DIR/issue-44578.rs:26:20 | LL | println!("{}", as Foo>::AMT); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -19,7 +19,7 @@ LL | println!("{}", as Foo>::AMT); = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` note: erroneous constant encountered - --> $DIR/issue-44578.rs:25:20 + --> $DIR/issue-44578.rs:26:20 | LL | println!("{}", as Foo>::AMT); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -27,7 +27,7 @@ LL | println!("{}", as Foo>::AMT); = note: this note originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) note: erroneous constant encountered - --> $DIR/issue-44578.rs:25:20 + --> $DIR/issue-44578.rs:26:20 | LL | println!("{}", as Foo>::AMT); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/consts/const-eval/issue-50814-2.mir-opt.stderr b/tests/ui/consts/const-eval/issue-50814-2.mir-opt.stderr index 2de68d3fee9..1f4f217b175 100644 --- a/tests/ui/consts/const-eval/issue-50814-2.mir-opt.stderr +++ b/tests/ui/consts/const-eval/issue-50814-2.mir-opt.stderr @@ -1,23 +1,23 @@ error[E0080]: evaluation of ` as Foo<()>>::BAR` failed - --> $DIR/issue-50814-2.rs:16:24 + --> $DIR/issue-50814-2.rs:17:24 | LL | const BAR: usize = [5, 6, 7][T::BOO]; | ^^^^^^^^^^^^^^^^^ index out of bounds: the length is 3 but the index is 42 note: erroneous constant encountered - --> $DIR/issue-50814-2.rs:20:6 + --> $DIR/issue-50814-2.rs:21:6 | LL | & as Foo>::BAR | ^^^^^^^^^^^^^^^^^^^^^ note: erroneous constant encountered - --> $DIR/issue-50814-2.rs:20:5 + --> $DIR/issue-50814-2.rs:21:5 | LL | & as Foo>::BAR | ^^^^^^^^^^^^^^^^^^^^^^ note: erroneous constant encountered - --> $DIR/issue-50814-2.rs:20:5 + --> $DIR/issue-50814-2.rs:21:5 | LL | & as Foo>::BAR | ^^^^^^^^^^^^^^^^^^^^^^ @@ -25,7 +25,7 @@ LL | & as Foo>::BAR = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` note: erroneous constant encountered - --> $DIR/issue-50814-2.rs:20:5 + --> $DIR/issue-50814-2.rs:21:5 | LL | & as Foo>::BAR | ^^^^^^^^^^^^^^^^^^^^^^ @@ -33,7 +33,7 @@ LL | & as Foo>::BAR = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` note: erroneous constant encountered - --> $DIR/issue-50814-2.rs:20:5 + --> $DIR/issue-50814-2.rs:21:5 | LL | & as Foo>::BAR | ^^^^^^^^^^^^^^^^^^^^^^ @@ -41,7 +41,7 @@ LL | & as Foo>::BAR = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` note: erroneous constant encountered - --> $DIR/issue-50814-2.rs:20:6 + --> $DIR/issue-50814-2.rs:21:6 | LL | & as Foo>::BAR | ^^^^^^^^^^^^^^^^^^^^^ @@ -49,7 +49,7 @@ LL | & as Foo>::BAR = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` note: erroneous constant encountered - --> $DIR/issue-50814-2.rs:20:6 + --> $DIR/issue-50814-2.rs:21:6 | LL | & as Foo>::BAR | ^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/consts/const-eval/issue-50814-2.normal.stderr b/tests/ui/consts/const-eval/issue-50814-2.normal.stderr index 4a7dfb19304..f790862aef1 100644 --- a/tests/ui/consts/const-eval/issue-50814-2.normal.stderr +++ b/tests/ui/consts/const-eval/issue-50814-2.normal.stderr @@ -1,23 +1,23 @@ error[E0080]: evaluation of ` as Foo<()>>::BAR` failed - --> $DIR/issue-50814-2.rs:16:24 + --> $DIR/issue-50814-2.rs:17:24 | LL | const BAR: usize = [5, 6, 7][T::BOO]; | ^^^^^^^^^^^^^^^^^ index out of bounds: the length is 3 but the index is 42 note: erroneous constant encountered - --> $DIR/issue-50814-2.rs:20:6 + --> $DIR/issue-50814-2.rs:21:6 | LL | & as Foo>::BAR | ^^^^^^^^^^^^^^^^^^^^^ note: erroneous constant encountered - --> $DIR/issue-50814-2.rs:20:5 + --> $DIR/issue-50814-2.rs:21:5 | LL | & as Foo>::BAR | ^^^^^^^^^^^^^^^^^^^^^^ note: erroneous constant encountered - --> $DIR/issue-50814-2.rs:20:6 + --> $DIR/issue-50814-2.rs:21:6 | LL | & as Foo>::BAR | ^^^^^^^^^^^^^^^^^^^^^ @@ -25,7 +25,7 @@ LL | & as Foo>::BAR = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` note: the above error was encountered while instantiating `fn foo::<()>` - --> $DIR/issue-50814-2.rs:32:22 + --> $DIR/issue-50814-2.rs:33:22 | LL | println!("{:x}", foo::<()>() as *const usize as usize); | ^^^^^^^^^^^ diff --git a/tests/ui/consts/const-eval/issue-50814-2.rs b/tests/ui/consts/const-eval/issue-50814-2.rs index c2e2de67a65..261dcd3aa4c 100644 --- a/tests/ui/consts/const-eval/issue-50814-2.rs +++ b/tests/ui/consts/const-eval/issue-50814-2.rs @@ -1,6 +1,7 @@ //@ build-fail //@ revisions: normal mir-opt //@ [mir-opt]compile-flags: -Zmir-opt-level=4 +//@ dont-require-annotations: NOTE trait C { const BOO: usize; @@ -17,7 +18,7 @@ impl Foo for A { } fn foo() -> &'static usize { - & as Foo>::BAR //~ constant + & as Foo>::BAR //~ NOTE constant } impl C for () { diff --git a/tests/ui/consts/const-eval/issue-50814.rs b/tests/ui/consts/const-eval/issue-50814.rs index 27b5b39ad73..5495fb43bba 100644 --- a/tests/ui/consts/const-eval/issue-50814.rs +++ b/tests/ui/consts/const-eval/issue-50814.rs @@ -1,4 +1,5 @@ //@ build-fail +//@ dont-require-annotations: NOTE trait Unsigned { const MAX: u8; @@ -19,7 +20,7 @@ impl Unsigned for Sum { fn foo(_: T) -> &'static u8 { &Sum::::MAX - //~^ constant + //~^ NOTE constant } fn main() { diff --git a/tests/ui/consts/const-eval/issue-50814.stderr b/tests/ui/consts/const-eval/issue-50814.stderr index fe0e25b820f..5b23c48e450 100644 --- a/tests/ui/consts/const-eval/issue-50814.stderr +++ b/tests/ui/consts/const-eval/issue-50814.stderr @@ -1,17 +1,17 @@ error[E0080]: evaluation of ` as Unsigned>::MAX` failed - --> $DIR/issue-50814.rs:15:21 + --> $DIR/issue-50814.rs:16:21 | LL | const MAX: u8 = A::MAX + B::MAX; | ^^^^^^^^^^^^^^^ attempt to compute `u8::MAX + u8::MAX`, which would overflow note: erroneous constant encountered - --> $DIR/issue-50814.rs:21:6 + --> $DIR/issue-50814.rs:22:6 | LL | &Sum::::MAX | ^^^^^^^^^^^^^^^^^^ error[E0080]: evaluation of ` as Unsigned>::MAX` failed - --> $DIR/issue-50814.rs:15:21 + --> $DIR/issue-50814.rs:16:21 | LL | const MAX: u8 = A::MAX + B::MAX; | ^^^^^^^^^^^^^^^ attempt to compute `u8::MAX + u8::MAX`, which would overflow @@ -19,7 +19,7 @@ LL | const MAX: u8 = A::MAX + B::MAX; = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` note: erroneous constant encountered - --> $DIR/issue-50814.rs:21:6 + --> $DIR/issue-50814.rs:22:6 | LL | &Sum::::MAX | ^^^^^^^^^^^^^^^^^^ @@ -27,13 +27,13 @@ LL | &Sum::::MAX = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` note: erroneous constant encountered - --> $DIR/issue-50814.rs:21:5 + --> $DIR/issue-50814.rs:22:5 | LL | &Sum::::MAX | ^^^^^^^^^^^^^^^^^^^ note: erroneous constant encountered - --> $DIR/issue-50814.rs:21:6 + --> $DIR/issue-50814.rs:22:6 | LL | &Sum::::MAX | ^^^^^^^^^^^^^^^^^^ @@ -41,7 +41,7 @@ LL | &Sum::::MAX = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` note: the above error was encountered while instantiating `fn foo::` - --> $DIR/issue-50814.rs:26:5 + --> $DIR/issue-50814.rs:27:5 | LL | foo(0); | ^^^^^^ diff --git a/tests/ui/consts/const-eval/panic-assoc-never-type.rs b/tests/ui/consts/const-eval/panic-assoc-never-type.rs index bdaa51494b9..79b5dafaf15 100644 --- a/tests/ui/consts/const-eval/panic-assoc-never-type.rs +++ b/tests/ui/consts/const-eval/panic-assoc-never-type.rs @@ -1,4 +1,5 @@ //@ build-fail +//@ dont-require-annotations: NOTE // Regression test for #66975 #![feature(never_type)] @@ -11,5 +12,5 @@ impl PrintName { } fn main() { - let _ = PrintName::VOID; //~ erroneous constant encountered + let _ = PrintName::VOID; //~ NOTE erroneous constant encountered } diff --git a/tests/ui/consts/const-eval/panic-assoc-never-type.stderr b/tests/ui/consts/const-eval/panic-assoc-never-type.stderr index 71b33d8d0d5..03413f46b20 100644 --- a/tests/ui/consts/const-eval/panic-assoc-never-type.stderr +++ b/tests/ui/consts/const-eval/panic-assoc-never-type.stderr @@ -1,17 +1,17 @@ error[E0080]: evaluation of constant value failed - --> $DIR/panic-assoc-never-type.rs:9:21 + --> $DIR/panic-assoc-never-type.rs:10:21 | LL | const VOID: ! = panic!(); | ^^^^^^^^ evaluation panicked: explicit panic note: erroneous constant encountered - --> $DIR/panic-assoc-never-type.rs:14:13 + --> $DIR/panic-assoc-never-type.rs:15:13 | LL | let _ = PrintName::VOID; | ^^^^^^^^^^^^^^^ note: erroneous constant encountered - --> $DIR/panic-assoc-never-type.rs:14:13 + --> $DIR/panic-assoc-never-type.rs:15:13 | LL | let _ = PrintName::VOID; | ^^^^^^^^^^^^^^^ diff --git a/tests/ui/consts/const-eval/raw-bytes.32bit.stderr b/tests/ui/consts/const-eval/raw-bytes.32bit.stderr index 27c85cc8ce4..120a08acc33 100644 --- a/tests/ui/consts/const-eval/raw-bytes.32bit.stderr +++ b/tests/ui/consts/const-eval/raw-bytes.32bit.stderr @@ -1,5 +1,5 @@ error[E0080]: it is undefined behavior to use this value - --> $DIR/raw-bytes.rs:21:1 + --> $DIR/raw-bytes.rs:23:1 | LL | const BAD_ENUM: Enum = unsafe { mem::transmute(1usize) }; | ^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .: encountered 0x00000001, but expected a valid enum tag @@ -10,7 +10,7 @@ LL | const BAD_ENUM: Enum = unsafe { mem::transmute(1usize) }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/raw-bytes.rs:29:1 + --> $DIR/raw-bytes.rs:31:1 | LL | const BAD_ENUM2: Enum2 = unsafe { mem::transmute(0usize) }; | ^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .: encountered 0x00000000, but expected a valid enum tag @@ -21,7 +21,7 @@ LL | const BAD_ENUM2: Enum2 = unsafe { mem::transmute(0usize) }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/raw-bytes.rs:43:1 + --> $DIR/raw-bytes.rs:45:1 | LL | const BAD_UNINHABITED_VARIANT1: UninhDiscriminant = unsafe { mem::transmute(1u8) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .: encountered an uninhabited enum variant @@ -32,7 +32,7 @@ LL | const BAD_UNINHABITED_VARIANT1: UninhDiscriminant = unsafe { mem::transmute } error[E0080]: it is undefined behavior to use this value - --> $DIR/raw-bytes.rs:45:1 + --> $DIR/raw-bytes.rs:47:1 | LL | const BAD_UNINHABITED_VARIANT2: UninhDiscriminant = unsafe { mem::transmute(3u8) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .: encountered an uninhabited enum variant @@ -43,7 +43,7 @@ LL | const BAD_UNINHABITED_VARIANT2: UninhDiscriminant = unsafe { mem::transmute } error[E0080]: it is undefined behavior to use this value - --> $DIR/raw-bytes.rs:51:1 + --> $DIR/raw-bytes.rs:53:1 | LL | const BAD_OPTION_CHAR: Option<(char, char)> = Some(('x', unsafe { mem::transmute(!0u32) })); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at ..0.1: encountered 0xffffffff, but expected a valid unicode scalar value (in `0..=0x10FFFF` but not in `0xD800..=0xDFFF`) @@ -54,7 +54,7 @@ LL | const BAD_OPTION_CHAR: Option<(char, char)> = Some(('x', unsafe { mem::tran } error[E0080]: it is undefined behavior to use this value - --> $DIR/raw-bytes.rs:56:1 + --> $DIR/raw-bytes.rs:58:1 | LL | const NULL_PTR: NonNull = unsafe { mem::transmute(0usize) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0, but expected something greater or equal to 1 @@ -65,7 +65,7 @@ LL | const NULL_PTR: NonNull = unsafe { mem::transmute(0usize) }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/raw-bytes.rs:59:1 + --> $DIR/raw-bytes.rs:61:1 | LL | const NULL_U8: NonZero = unsafe { mem::transmute(0u8) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered 0, but expected something greater or equal to 1 @@ -76,7 +76,7 @@ LL | const NULL_U8: NonZero = unsafe { mem::transmute(0u8) }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/raw-bytes.rs:61:1 + --> $DIR/raw-bytes.rs:63:1 | LL | const NULL_USIZE: NonZero = unsafe { mem::transmute(0usize) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered 0, but expected something greater or equal to 1 @@ -87,7 +87,7 @@ LL | const NULL_USIZE: NonZero = unsafe { mem::transmute(0usize) }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/raw-bytes.rs:67:1 + --> $DIR/raw-bytes.rs:69:1 | LL | const BAD_RANGE1: RestrictedRange1 = unsafe { RestrictedRange1(42) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 42, but expected something in the range 10..=30 @@ -98,7 +98,7 @@ LL | const BAD_RANGE1: RestrictedRange1 = unsafe { RestrictedRange1(42) }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/raw-bytes.rs:73:1 + --> $DIR/raw-bytes.rs:75:1 | LL | const BAD_RANGE2: RestrictedRange2 = unsafe { RestrictedRange2(20) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 20, but expected something less or equal to 10, or greater or equal to 30 @@ -109,7 +109,7 @@ LL | const BAD_RANGE2: RestrictedRange2 = unsafe { RestrictedRange2(20) }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/raw-bytes.rs:76:1 + --> $DIR/raw-bytes.rs:78:1 | LL | const NULL_FAT_PTR: NonNull = unsafe { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0, but expected something greater or equal to 1 @@ -120,7 +120,7 @@ LL | const NULL_FAT_PTR: NonNull = unsafe { } error[E0080]: it is undefined behavior to use this value - --> $DIR/raw-bytes.rs:84:1 + --> $DIR/raw-bytes.rs:86:1 | LL | const UNALIGNED: &u16 = unsafe { mem::transmute(&[0u8; 4]) }; | ^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered an unaligned reference (required 2 byte alignment but found 1) @@ -131,7 +131,7 @@ LL | const UNALIGNED: &u16 = unsafe { mem::transmute(&[0u8; 4]) }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/raw-bytes.rs:88:1 + --> $DIR/raw-bytes.rs:90:1 | LL | const UNALIGNED_BOX: Box = unsafe { mem::transmute(&[0u8; 4]) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered an unaligned box (required 2 byte alignment but found 1) @@ -142,7 +142,7 @@ LL | const UNALIGNED_BOX: Box = unsafe { mem::transmute(&[0u8; 4]) }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/raw-bytes.rs:92:1 + --> $DIR/raw-bytes.rs:94:1 | LL | const NULL: &u16 = unsafe { mem::transmute(0usize) }; | ^^^^^^^^^^^^^^^^ constructing invalid value: encountered a null reference @@ -153,7 +153,7 @@ LL | const NULL: &u16 = unsafe { mem::transmute(0usize) }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/raw-bytes.rs:95:1 + --> $DIR/raw-bytes.rs:97:1 | LL | const NULL_BOX: Box = unsafe { mem::transmute(0usize) }; | ^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a null box @@ -164,7 +164,7 @@ LL | const NULL_BOX: Box = unsafe { mem::transmute(0usize) }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/raw-bytes.rs:98:1 + --> $DIR/raw-bytes.rs:100:1 | LL | const USIZE_AS_REF: &'static u8 = unsafe { mem::transmute(1337usize) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a dangling reference (0x539[noalloc] has no provenance) @@ -175,7 +175,7 @@ LL | const USIZE_AS_REF: &'static u8 = unsafe { mem::transmute(1337usize) }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/raw-bytes.rs:101:1 + --> $DIR/raw-bytes.rs:103:1 | LL | const USIZE_AS_BOX: Box = unsafe { mem::transmute(1337usize) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a dangling box (0x539[noalloc] has no provenance) @@ -186,7 +186,7 @@ LL | const USIZE_AS_BOX: Box = unsafe { mem::transmute(1337usize) }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/raw-bytes.rs:104:1 + --> $DIR/raw-bytes.rs:106:1 | LL | const NULL_FN_PTR: fn() = unsafe { mem::transmute(0usize) }; | ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered null pointer, but expected a function pointer @@ -197,7 +197,7 @@ LL | const NULL_FN_PTR: fn() = unsafe { mem::transmute(0usize) }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/raw-bytes.rs:106:1 + --> $DIR/raw-bytes.rs:108:1 | LL | const DANGLING_FN_PTR: fn() = unsafe { mem::transmute(13usize) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0xd[noalloc], but expected a function pointer @@ -208,7 +208,7 @@ LL | const DANGLING_FN_PTR: fn() = unsafe { mem::transmute(13usize) }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/raw-bytes.rs:108:1 + --> $DIR/raw-bytes.rs:110:1 | LL | const DATA_FN_PTR: fn() = unsafe { mem::transmute(&13) }; | ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered ALLOC3, but expected a function pointer @@ -219,7 +219,7 @@ LL | const DATA_FN_PTR: fn() = unsafe { mem::transmute(&13) }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/raw-bytes.rs:114:1 + --> $DIR/raw-bytes.rs:116:1 | LL | const BAD_BAD_REF: &Bar = unsafe { mem::transmute(1usize) }; | ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a reference pointing to uninhabited type Bar @@ -230,7 +230,7 @@ LL | const BAD_BAD_REF: &Bar = unsafe { mem::transmute(1usize) }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/raw-bytes.rs:139:1 + --> $DIR/raw-bytes.rs:141:1 | LL | const STR_TOO_LONG: &str = unsafe { mem::transmute((&42u8, 999usize)) }; | ^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a dangling reference (going beyond the bounds of its allocation) @@ -241,7 +241,7 @@ LL | const STR_TOO_LONG: &str = unsafe { mem::transmute((&42u8, 999usize)) }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/raw-bytes.rs:141:1 + --> $DIR/raw-bytes.rs:143:1 | LL | const NESTED_STR_MUCH_TOO_LONG: (&str,) = (unsafe { mem::transmute((&42, usize::MAX)) },); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered invalid reference metadata: slice is bigger than largest supported object @@ -252,7 +252,7 @@ LL | const NESTED_STR_MUCH_TOO_LONG: (&str,) = (unsafe { mem::transmute((&42, us } error[E0080]: it is undefined behavior to use this value - --> $DIR/raw-bytes.rs:143:1 + --> $DIR/raw-bytes.rs:145:1 | LL | const MY_STR_MUCH_TOO_LONG: &MyStr = unsafe { mem::transmute((&42u8, usize::MAX)) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered invalid reference metadata: slice is bigger than largest supported object @@ -263,7 +263,7 @@ LL | const MY_STR_MUCH_TOO_LONG: &MyStr = unsafe { mem::transmute((&42u8, usize: } error[E0080]: it is undefined behavior to use this value - --> $DIR/raw-bytes.rs:146:1 + --> $DIR/raw-bytes.rs:148:1 | LL | const STR_NO_INIT: &str = unsafe { mem::transmute::<&[_], _>(&[MaybeUninit:: { uninit: () }]) }; | ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .: encountered uninitialized memory, but expected a string @@ -274,7 +274,7 @@ LL | const STR_NO_INIT: &str = unsafe { mem::transmute::<&[_], _>(&[MaybeUninit: } error[E0080]: it is undefined behavior to use this value - --> $DIR/raw-bytes.rs:148:1 + --> $DIR/raw-bytes.rs:150:1 | LL | const MYSTR_NO_INIT: &MyStr = unsafe { mem::transmute::<&[_], _>(&[MaybeUninit:: { uninit: () }]) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at ..0: encountered uninitialized memory, but expected a string @@ -285,7 +285,7 @@ LL | const MYSTR_NO_INIT: &MyStr = unsafe { mem::transmute::<&[_], _>(&[MaybeUni } error[E0080]: it is undefined behavior to use this value - --> $DIR/raw-bytes.rs:150:1 + --> $DIR/raw-bytes.rs:152:1 | LL | const MYSTR_NO_INIT_ISSUE83182: &MyStr = unsafe { mem::transmute::<&[_], _>(&[&()]) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at ..0: encountered a pointer, but expected a string @@ -298,7 +298,7 @@ LL | const MYSTR_NO_INIT_ISSUE83182: &MyStr = unsafe { mem::transmute::<&[_], _> = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported error[E0080]: it is undefined behavior to use this value - --> $DIR/raw-bytes.rs:154:1 + --> $DIR/raw-bytes.rs:156:1 | LL | const SLICE_TOO_LONG: &[u8] = unsafe { mem::transmute((&42u8, 999usize)) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a dangling reference (going beyond the bounds of its allocation) @@ -309,7 +309,7 @@ LL | const SLICE_TOO_LONG: &[u8] = unsafe { mem::transmute((&42u8, 999usize)) }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/raw-bytes.rs:156:1 + --> $DIR/raw-bytes.rs:158:1 | LL | const SLICE_TOO_LONG_OVERFLOW: &[u32] = unsafe { mem::transmute((&42u32, isize::MAX)) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered invalid reference metadata: slice is bigger than largest supported object @@ -320,7 +320,7 @@ LL | const SLICE_TOO_LONG_OVERFLOW: &[u32] = unsafe { mem::transmute((&42u32, is } error[E0080]: it is undefined behavior to use this value - --> $DIR/raw-bytes.rs:159:1 + --> $DIR/raw-bytes.rs:161:1 | LL | const SLICE_TOO_LONG_BOX: Box<[u8]> = unsafe { mem::transmute((&42u8, 999usize)) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a dangling box (going beyond the bounds of its allocation) @@ -331,7 +331,7 @@ LL | const SLICE_TOO_LONG_BOX: Box<[u8]> = unsafe { mem::transmute((&42u8, 999us } error[E0080]: it is undefined behavior to use this value - --> $DIR/raw-bytes.rs:162:1 + --> $DIR/raw-bytes.rs:164:1 | LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .[0]: encountered 0x03, but expected a boolean @@ -342,13 +342,13 @@ LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }]; } note: erroneous constant encountered - --> $DIR/raw-bytes.rs:162:40 + --> $DIR/raw-bytes.rs:164:40 | LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0080]: it is undefined behavior to use this value - --> $DIR/raw-bytes.rs:168:1 + --> $DIR/raw-bytes.rs:170:1 | LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3u8) }, [false]); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at ..0: encountered 0x03, but expected a boolean @@ -359,13 +359,13 @@ LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3 } note: erroneous constant encountered - --> $DIR/raw-bytes.rs:168:42 + --> $DIR/raw-bytes.rs:170:42 | LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3u8) }, [false]); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0080]: it is undefined behavior to use this value - --> $DIR/raw-bytes.rs:172:1 + --> $DIR/raw-bytes.rs:174:1 | LL | const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::transmute(3u8) }]); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at ..1[0]: encountered 0x03, but expected a boolean @@ -376,13 +376,13 @@ LL | const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::tran } note: erroneous constant encountered - --> $DIR/raw-bytes.rs:172:42 + --> $DIR/raw-bytes.rs:174:42 | LL | const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::transmute(3u8) }]); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0080]: it is undefined behavior to use this value - --> $DIR/raw-bytes.rs:177:1 + --> $DIR/raw-bytes.rs:179:1 | LL | const TRAIT_OBJ_SHORT_VTABLE_1: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, &3u8))) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered ALLOC17, but expected a vtable pointer @@ -393,7 +393,7 @@ LL | const TRAIT_OBJ_SHORT_VTABLE_1: W<&dyn Trait> = unsafe { mem::transmute(W(( } error[E0080]: it is undefined behavior to use this value - --> $DIR/raw-bytes.rs:181:1 + --> $DIR/raw-bytes.rs:183:1 | LL | const TRAIT_OBJ_SHORT_VTABLE_2: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, &3u64))) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered ALLOC19, but expected a vtable pointer @@ -404,7 +404,7 @@ LL | const TRAIT_OBJ_SHORT_VTABLE_2: W<&dyn Trait> = unsafe { mem::transmute(W(( } error[E0080]: it is undefined behavior to use this value - --> $DIR/raw-bytes.rs:185:1 + --> $DIR/raw-bytes.rs:187:1 | LL | const TRAIT_OBJ_INT_VTABLE: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, 4usize))) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered 0x4[noalloc], but expected a vtable pointer @@ -415,7 +415,7 @@ LL | const TRAIT_OBJ_INT_VTABLE: W<&dyn Trait> = unsafe { mem::transmute(W((&92u } error[E0080]: it is undefined behavior to use this value - --> $DIR/raw-bytes.rs:188:1 + --> $DIR/raw-bytes.rs:190:1 | LL | const TRAIT_OBJ_BAD_DROP_FN_NOT_FN_PTR: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, &[&42u8; 8]))) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered ALLOC22, but expected a vtable pointer @@ -426,7 +426,7 @@ LL | const TRAIT_OBJ_BAD_DROP_FN_NOT_FN_PTR: W<&dyn Trait> = unsafe { mem::trans } error[E0080]: it is undefined behavior to use this value - --> $DIR/raw-bytes.rs:192:1 + --> $DIR/raw-bytes.rs:194:1 | LL | const TRAIT_OBJ_CONTENT_INVALID: &dyn Trait = unsafe { mem::transmute::<_, &bool>(&3u8) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at ..: encountered 0x03, but expected a boolean @@ -437,7 +437,7 @@ LL | const TRAIT_OBJ_CONTENT_INVALID: &dyn Trait = unsafe { mem::transmute::<_, } error[E0080]: it is undefined behavior to use this value - --> $DIR/raw-bytes.rs:196:1 + --> $DIR/raw-bytes.rs:198:1 | LL | const RAW_TRAIT_OBJ_VTABLE_NULL: *const dyn Trait = unsafe { mem::transmute((&92u8, 0usize)) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered null pointer, but expected a vtable pointer @@ -448,7 +448,7 @@ LL | const RAW_TRAIT_OBJ_VTABLE_NULL: *const dyn Trait = unsafe { mem::transmute } error[E0080]: it is undefined behavior to use this value - --> $DIR/raw-bytes.rs:199:1 + --> $DIR/raw-bytes.rs:201:1 | LL | const RAW_TRAIT_OBJ_VTABLE_INVALID: *const dyn Trait = unsafe { mem::transmute((&92u8, &3u64)) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered ALLOC27, but expected a vtable pointer @@ -459,7 +459,7 @@ LL | const RAW_TRAIT_OBJ_VTABLE_INVALID: *const dyn Trait = unsafe { mem::transm } error[E0080]: it is undefined behavior to use this value - --> $DIR/raw-bytes.rs:204:1 + --> $DIR/raw-bytes.rs:206:1 | LL | const _: &[!; 1] = unsafe { &*(1_usize as *const [!; 1]) }; | ^^^^^^^^^^^^^^^^ constructing invalid value: encountered a reference pointing to uninhabited type [!; 1] @@ -470,7 +470,7 @@ LL | const _: &[!; 1] = unsafe { &*(1_usize as *const [!; 1]) }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/raw-bytes.rs:205:1 + --> $DIR/raw-bytes.rs:207:1 | LL | const _: &[!] = unsafe { &*(1_usize as *const [!; 1]) }; | ^^^^^^^^^^^^^ constructing invalid value at .[0]: encountered a value of the never type `!` @@ -481,7 +481,7 @@ LL | const _: &[!] = unsafe { &*(1_usize as *const [!; 1]) }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/raw-bytes.rs:206:1 + --> $DIR/raw-bytes.rs:208:1 | LL | const _: &[!] = unsafe { &*(1_usize as *const [!; 42]) }; | ^^^^^^^^^^^^^ constructing invalid value at .[0]: encountered a value of the never type `!` @@ -492,7 +492,7 @@ LL | const _: &[!] = unsafe { &*(1_usize as *const [!; 42]) }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/raw-bytes.rs:210:1 + --> $DIR/raw-bytes.rs:212:1 | LL | pub static S4: &[u8] = unsafe { from_raw_parts((&D1) as *const _ as _, 1) }; | ^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .[0]: encountered uninitialized memory, but expected an integer @@ -503,7 +503,7 @@ LL | pub static S4: &[u8] = unsafe { from_raw_parts((&D1) as *const _ as _, 1) } } error[E0080]: it is undefined behavior to use this value - --> $DIR/raw-bytes.rs:213:1 + --> $DIR/raw-bytes.rs:215:1 | LL | pub static S5: &[u8] = unsafe { from_raw_parts((&D3) as *const _ as _, mem::size_of::<&u32>()) }; | ^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .[0]: encountered a pointer, but expected an integer @@ -516,7 +516,7 @@ LL | pub static S5: &[u8] = unsafe { from_raw_parts((&D3) as *const _ as _, mem: = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported error[E0080]: it is undefined behavior to use this value - --> $DIR/raw-bytes.rs:216:1 + --> $DIR/raw-bytes.rs:218:1 | LL | pub static S6: &[bool] = unsafe { from_raw_parts((&D0) as *const _ as _, 4) }; | ^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .[0]: encountered 0x11, but expected a boolean @@ -527,7 +527,7 @@ LL | pub static S6: &[bool] = unsafe { from_raw_parts((&D0) as *const _ as _, 4) } error[E0080]: it is undefined behavior to use this value - --> $DIR/raw-bytes.rs:220:1 + --> $DIR/raw-bytes.rs:222:1 | LL | pub static S7: &[u16] = unsafe { | ^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .[1]: encountered uninitialized memory, but expected an integer @@ -538,7 +538,7 @@ LL | pub static S7: &[u16] = unsafe { } error[E0080]: it is undefined behavior to use this value - --> $DIR/raw-bytes.rs:227:1 + --> $DIR/raw-bytes.rs:229:1 | LL | pub static R4: &[u8] = unsafe { | ^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .[0]: encountered uninitialized memory, but expected an integer @@ -549,7 +549,7 @@ LL | pub static R4: &[u8] = unsafe { } error[E0080]: it is undefined behavior to use this value - --> $DIR/raw-bytes.rs:232:1 + --> $DIR/raw-bytes.rs:234:1 | LL | pub static R5: &[u8] = unsafe { | ^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .[0]: encountered a pointer, but expected an integer @@ -562,7 +562,7 @@ LL | pub static R5: &[u8] = unsafe { = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported error[E0080]: it is undefined behavior to use this value - --> $DIR/raw-bytes.rs:237:1 + --> $DIR/raw-bytes.rs:239:1 | LL | pub static R6: &[bool] = unsafe { | ^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .[0]: encountered 0x11, but expected a boolean diff --git a/tests/ui/consts/const-eval/raw-bytes.64bit.stderr b/tests/ui/consts/const-eval/raw-bytes.64bit.stderr index 2b0ce99a881..d54ad7c8546 100644 --- a/tests/ui/consts/const-eval/raw-bytes.64bit.stderr +++ b/tests/ui/consts/const-eval/raw-bytes.64bit.stderr @@ -1,5 +1,5 @@ error[E0080]: it is undefined behavior to use this value - --> $DIR/raw-bytes.rs:21:1 + --> $DIR/raw-bytes.rs:23:1 | LL | const BAD_ENUM: Enum = unsafe { mem::transmute(1usize) }; | ^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .: encountered 0x0000000000000001, but expected a valid enum tag @@ -10,7 +10,7 @@ LL | const BAD_ENUM: Enum = unsafe { mem::transmute(1usize) }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/raw-bytes.rs:29:1 + --> $DIR/raw-bytes.rs:31:1 | LL | const BAD_ENUM2: Enum2 = unsafe { mem::transmute(0usize) }; | ^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .: encountered 0x0000000000000000, but expected a valid enum tag @@ -21,7 +21,7 @@ LL | const BAD_ENUM2: Enum2 = unsafe { mem::transmute(0usize) }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/raw-bytes.rs:43:1 + --> $DIR/raw-bytes.rs:45:1 | LL | const BAD_UNINHABITED_VARIANT1: UninhDiscriminant = unsafe { mem::transmute(1u8) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .: encountered an uninhabited enum variant @@ -32,7 +32,7 @@ LL | const BAD_UNINHABITED_VARIANT1: UninhDiscriminant = unsafe { mem::transmute } error[E0080]: it is undefined behavior to use this value - --> $DIR/raw-bytes.rs:45:1 + --> $DIR/raw-bytes.rs:47:1 | LL | const BAD_UNINHABITED_VARIANT2: UninhDiscriminant = unsafe { mem::transmute(3u8) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .: encountered an uninhabited enum variant @@ -43,7 +43,7 @@ LL | const BAD_UNINHABITED_VARIANT2: UninhDiscriminant = unsafe { mem::transmute } error[E0080]: it is undefined behavior to use this value - --> $DIR/raw-bytes.rs:51:1 + --> $DIR/raw-bytes.rs:53:1 | LL | const BAD_OPTION_CHAR: Option<(char, char)> = Some(('x', unsafe { mem::transmute(!0u32) })); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at ..0.1: encountered 0xffffffff, but expected a valid unicode scalar value (in `0..=0x10FFFF` but not in `0xD800..=0xDFFF`) @@ -54,7 +54,7 @@ LL | const BAD_OPTION_CHAR: Option<(char, char)> = Some(('x', unsafe { mem::tran } error[E0080]: it is undefined behavior to use this value - --> $DIR/raw-bytes.rs:56:1 + --> $DIR/raw-bytes.rs:58:1 | LL | const NULL_PTR: NonNull = unsafe { mem::transmute(0usize) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0, but expected something greater or equal to 1 @@ -65,7 +65,7 @@ LL | const NULL_PTR: NonNull = unsafe { mem::transmute(0usize) }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/raw-bytes.rs:59:1 + --> $DIR/raw-bytes.rs:61:1 | LL | const NULL_U8: NonZero = unsafe { mem::transmute(0u8) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered 0, but expected something greater or equal to 1 @@ -76,7 +76,7 @@ LL | const NULL_U8: NonZero = unsafe { mem::transmute(0u8) }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/raw-bytes.rs:61:1 + --> $DIR/raw-bytes.rs:63:1 | LL | const NULL_USIZE: NonZero = unsafe { mem::transmute(0usize) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered 0, but expected something greater or equal to 1 @@ -87,7 +87,7 @@ LL | const NULL_USIZE: NonZero = unsafe { mem::transmute(0usize) }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/raw-bytes.rs:67:1 + --> $DIR/raw-bytes.rs:69:1 | LL | const BAD_RANGE1: RestrictedRange1 = unsafe { RestrictedRange1(42) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 42, but expected something in the range 10..=30 @@ -98,7 +98,7 @@ LL | const BAD_RANGE1: RestrictedRange1 = unsafe { RestrictedRange1(42) }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/raw-bytes.rs:73:1 + --> $DIR/raw-bytes.rs:75:1 | LL | const BAD_RANGE2: RestrictedRange2 = unsafe { RestrictedRange2(20) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 20, but expected something less or equal to 10, or greater or equal to 30 @@ -109,7 +109,7 @@ LL | const BAD_RANGE2: RestrictedRange2 = unsafe { RestrictedRange2(20) }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/raw-bytes.rs:76:1 + --> $DIR/raw-bytes.rs:78:1 | LL | const NULL_FAT_PTR: NonNull = unsafe { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0, but expected something greater or equal to 1 @@ -120,7 +120,7 @@ LL | const NULL_FAT_PTR: NonNull = unsafe { } error[E0080]: it is undefined behavior to use this value - --> $DIR/raw-bytes.rs:84:1 + --> $DIR/raw-bytes.rs:86:1 | LL | const UNALIGNED: &u16 = unsafe { mem::transmute(&[0u8; 4]) }; | ^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered an unaligned reference (required 2 byte alignment but found 1) @@ -131,7 +131,7 @@ LL | const UNALIGNED: &u16 = unsafe { mem::transmute(&[0u8; 4]) }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/raw-bytes.rs:88:1 + --> $DIR/raw-bytes.rs:90:1 | LL | const UNALIGNED_BOX: Box = unsafe { mem::transmute(&[0u8; 4]) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered an unaligned box (required 2 byte alignment but found 1) @@ -142,7 +142,7 @@ LL | const UNALIGNED_BOX: Box = unsafe { mem::transmute(&[0u8; 4]) }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/raw-bytes.rs:92:1 + --> $DIR/raw-bytes.rs:94:1 | LL | const NULL: &u16 = unsafe { mem::transmute(0usize) }; | ^^^^^^^^^^^^^^^^ constructing invalid value: encountered a null reference @@ -153,7 +153,7 @@ LL | const NULL: &u16 = unsafe { mem::transmute(0usize) }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/raw-bytes.rs:95:1 + --> $DIR/raw-bytes.rs:97:1 | LL | const NULL_BOX: Box = unsafe { mem::transmute(0usize) }; | ^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a null box @@ -164,7 +164,7 @@ LL | const NULL_BOX: Box = unsafe { mem::transmute(0usize) }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/raw-bytes.rs:98:1 + --> $DIR/raw-bytes.rs:100:1 | LL | const USIZE_AS_REF: &'static u8 = unsafe { mem::transmute(1337usize) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a dangling reference (0x539[noalloc] has no provenance) @@ -175,7 +175,7 @@ LL | const USIZE_AS_REF: &'static u8 = unsafe { mem::transmute(1337usize) }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/raw-bytes.rs:101:1 + --> $DIR/raw-bytes.rs:103:1 | LL | const USIZE_AS_BOX: Box = unsafe { mem::transmute(1337usize) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a dangling box (0x539[noalloc] has no provenance) @@ -186,7 +186,7 @@ LL | const USIZE_AS_BOX: Box = unsafe { mem::transmute(1337usize) }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/raw-bytes.rs:104:1 + --> $DIR/raw-bytes.rs:106:1 | LL | const NULL_FN_PTR: fn() = unsafe { mem::transmute(0usize) }; | ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered null pointer, but expected a function pointer @@ -197,7 +197,7 @@ LL | const NULL_FN_PTR: fn() = unsafe { mem::transmute(0usize) }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/raw-bytes.rs:106:1 + --> $DIR/raw-bytes.rs:108:1 | LL | const DANGLING_FN_PTR: fn() = unsafe { mem::transmute(13usize) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0xd[noalloc], but expected a function pointer @@ -208,7 +208,7 @@ LL | const DANGLING_FN_PTR: fn() = unsafe { mem::transmute(13usize) }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/raw-bytes.rs:108:1 + --> $DIR/raw-bytes.rs:110:1 | LL | const DATA_FN_PTR: fn() = unsafe { mem::transmute(&13) }; | ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered ALLOC3, but expected a function pointer @@ -219,7 +219,7 @@ LL | const DATA_FN_PTR: fn() = unsafe { mem::transmute(&13) }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/raw-bytes.rs:114:1 + --> $DIR/raw-bytes.rs:116:1 | LL | const BAD_BAD_REF: &Bar = unsafe { mem::transmute(1usize) }; | ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a reference pointing to uninhabited type Bar @@ -230,7 +230,7 @@ LL | const BAD_BAD_REF: &Bar = unsafe { mem::transmute(1usize) }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/raw-bytes.rs:139:1 + --> $DIR/raw-bytes.rs:141:1 | LL | const STR_TOO_LONG: &str = unsafe { mem::transmute((&42u8, 999usize)) }; | ^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a dangling reference (going beyond the bounds of its allocation) @@ -241,7 +241,7 @@ LL | const STR_TOO_LONG: &str = unsafe { mem::transmute((&42u8, 999usize)) }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/raw-bytes.rs:141:1 + --> $DIR/raw-bytes.rs:143:1 | LL | const NESTED_STR_MUCH_TOO_LONG: (&str,) = (unsafe { mem::transmute((&42, usize::MAX)) },); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered invalid reference metadata: slice is bigger than largest supported object @@ -252,7 +252,7 @@ LL | const NESTED_STR_MUCH_TOO_LONG: (&str,) = (unsafe { mem::transmute((&42, us } error[E0080]: it is undefined behavior to use this value - --> $DIR/raw-bytes.rs:143:1 + --> $DIR/raw-bytes.rs:145:1 | LL | const MY_STR_MUCH_TOO_LONG: &MyStr = unsafe { mem::transmute((&42u8, usize::MAX)) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered invalid reference metadata: slice is bigger than largest supported object @@ -263,7 +263,7 @@ LL | const MY_STR_MUCH_TOO_LONG: &MyStr = unsafe { mem::transmute((&42u8, usize: } error[E0080]: it is undefined behavior to use this value - --> $DIR/raw-bytes.rs:146:1 + --> $DIR/raw-bytes.rs:148:1 | LL | const STR_NO_INIT: &str = unsafe { mem::transmute::<&[_], _>(&[MaybeUninit:: { uninit: () }]) }; | ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .: encountered uninitialized memory, but expected a string @@ -274,7 +274,7 @@ LL | const STR_NO_INIT: &str = unsafe { mem::transmute::<&[_], _>(&[MaybeUninit: } error[E0080]: it is undefined behavior to use this value - --> $DIR/raw-bytes.rs:148:1 + --> $DIR/raw-bytes.rs:150:1 | LL | const MYSTR_NO_INIT: &MyStr = unsafe { mem::transmute::<&[_], _>(&[MaybeUninit:: { uninit: () }]) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at ..0: encountered uninitialized memory, but expected a string @@ -285,7 +285,7 @@ LL | const MYSTR_NO_INIT: &MyStr = unsafe { mem::transmute::<&[_], _>(&[MaybeUni } error[E0080]: it is undefined behavior to use this value - --> $DIR/raw-bytes.rs:150:1 + --> $DIR/raw-bytes.rs:152:1 | LL | const MYSTR_NO_INIT_ISSUE83182: &MyStr = unsafe { mem::transmute::<&[_], _>(&[&()]) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at ..0: encountered a pointer, but expected a string @@ -298,7 +298,7 @@ LL | const MYSTR_NO_INIT_ISSUE83182: &MyStr = unsafe { mem::transmute::<&[_], _> = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported error[E0080]: it is undefined behavior to use this value - --> $DIR/raw-bytes.rs:154:1 + --> $DIR/raw-bytes.rs:156:1 | LL | const SLICE_TOO_LONG: &[u8] = unsafe { mem::transmute((&42u8, 999usize)) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a dangling reference (going beyond the bounds of its allocation) @@ -309,7 +309,7 @@ LL | const SLICE_TOO_LONG: &[u8] = unsafe { mem::transmute((&42u8, 999usize)) }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/raw-bytes.rs:156:1 + --> $DIR/raw-bytes.rs:158:1 | LL | const SLICE_TOO_LONG_OVERFLOW: &[u32] = unsafe { mem::transmute((&42u32, isize::MAX)) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered invalid reference metadata: slice is bigger than largest supported object @@ -320,7 +320,7 @@ LL | const SLICE_TOO_LONG_OVERFLOW: &[u32] = unsafe { mem::transmute((&42u32, is } error[E0080]: it is undefined behavior to use this value - --> $DIR/raw-bytes.rs:159:1 + --> $DIR/raw-bytes.rs:161:1 | LL | const SLICE_TOO_LONG_BOX: Box<[u8]> = unsafe { mem::transmute((&42u8, 999usize)) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a dangling box (going beyond the bounds of its allocation) @@ -331,7 +331,7 @@ LL | const SLICE_TOO_LONG_BOX: Box<[u8]> = unsafe { mem::transmute((&42u8, 999us } error[E0080]: it is undefined behavior to use this value - --> $DIR/raw-bytes.rs:162:1 + --> $DIR/raw-bytes.rs:164:1 | LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .[0]: encountered 0x03, but expected a boolean @@ -342,13 +342,13 @@ LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }]; } note: erroneous constant encountered - --> $DIR/raw-bytes.rs:162:40 + --> $DIR/raw-bytes.rs:164:40 | LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0080]: it is undefined behavior to use this value - --> $DIR/raw-bytes.rs:168:1 + --> $DIR/raw-bytes.rs:170:1 | LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3u8) }, [false]); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at ..0: encountered 0x03, but expected a boolean @@ -359,13 +359,13 @@ LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3 } note: erroneous constant encountered - --> $DIR/raw-bytes.rs:168:42 + --> $DIR/raw-bytes.rs:170:42 | LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3u8) }, [false]); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0080]: it is undefined behavior to use this value - --> $DIR/raw-bytes.rs:172:1 + --> $DIR/raw-bytes.rs:174:1 | LL | const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::transmute(3u8) }]); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at ..1[0]: encountered 0x03, but expected a boolean @@ -376,13 +376,13 @@ LL | const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::tran } note: erroneous constant encountered - --> $DIR/raw-bytes.rs:172:42 + --> $DIR/raw-bytes.rs:174:42 | LL | const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::transmute(3u8) }]); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0080]: it is undefined behavior to use this value - --> $DIR/raw-bytes.rs:177:1 + --> $DIR/raw-bytes.rs:179:1 | LL | const TRAIT_OBJ_SHORT_VTABLE_1: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, &3u8))) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered ALLOC17, but expected a vtable pointer @@ -393,7 +393,7 @@ LL | const TRAIT_OBJ_SHORT_VTABLE_1: W<&dyn Trait> = unsafe { mem::transmute(W(( } error[E0080]: it is undefined behavior to use this value - --> $DIR/raw-bytes.rs:181:1 + --> $DIR/raw-bytes.rs:183:1 | LL | const TRAIT_OBJ_SHORT_VTABLE_2: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, &3u64))) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered ALLOC19, but expected a vtable pointer @@ -404,7 +404,7 @@ LL | const TRAIT_OBJ_SHORT_VTABLE_2: W<&dyn Trait> = unsafe { mem::transmute(W(( } error[E0080]: it is undefined behavior to use this value - --> $DIR/raw-bytes.rs:185:1 + --> $DIR/raw-bytes.rs:187:1 | LL | const TRAIT_OBJ_INT_VTABLE: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, 4usize))) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered 0x4[noalloc], but expected a vtable pointer @@ -415,7 +415,7 @@ LL | const TRAIT_OBJ_INT_VTABLE: W<&dyn Trait> = unsafe { mem::transmute(W((&92u } error[E0080]: it is undefined behavior to use this value - --> $DIR/raw-bytes.rs:188:1 + --> $DIR/raw-bytes.rs:190:1 | LL | const TRAIT_OBJ_BAD_DROP_FN_NOT_FN_PTR: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, &[&42u8; 8]))) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered ALLOC22, but expected a vtable pointer @@ -426,7 +426,7 @@ LL | const TRAIT_OBJ_BAD_DROP_FN_NOT_FN_PTR: W<&dyn Trait> = unsafe { mem::trans } error[E0080]: it is undefined behavior to use this value - --> $DIR/raw-bytes.rs:192:1 + --> $DIR/raw-bytes.rs:194:1 | LL | const TRAIT_OBJ_CONTENT_INVALID: &dyn Trait = unsafe { mem::transmute::<_, &bool>(&3u8) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at ..: encountered 0x03, but expected a boolean @@ -437,7 +437,7 @@ LL | const TRAIT_OBJ_CONTENT_INVALID: &dyn Trait = unsafe { mem::transmute::<_, } error[E0080]: it is undefined behavior to use this value - --> $DIR/raw-bytes.rs:196:1 + --> $DIR/raw-bytes.rs:198:1 | LL | const RAW_TRAIT_OBJ_VTABLE_NULL: *const dyn Trait = unsafe { mem::transmute((&92u8, 0usize)) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered null pointer, but expected a vtable pointer @@ -448,7 +448,7 @@ LL | const RAW_TRAIT_OBJ_VTABLE_NULL: *const dyn Trait = unsafe { mem::transmute } error[E0080]: it is undefined behavior to use this value - --> $DIR/raw-bytes.rs:199:1 + --> $DIR/raw-bytes.rs:201:1 | LL | const RAW_TRAIT_OBJ_VTABLE_INVALID: *const dyn Trait = unsafe { mem::transmute((&92u8, &3u64)) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered ALLOC27, but expected a vtable pointer @@ -459,7 +459,7 @@ LL | const RAW_TRAIT_OBJ_VTABLE_INVALID: *const dyn Trait = unsafe { mem::transm } error[E0080]: it is undefined behavior to use this value - --> $DIR/raw-bytes.rs:204:1 + --> $DIR/raw-bytes.rs:206:1 | LL | const _: &[!; 1] = unsafe { &*(1_usize as *const [!; 1]) }; | ^^^^^^^^^^^^^^^^ constructing invalid value: encountered a reference pointing to uninhabited type [!; 1] @@ -470,7 +470,7 @@ LL | const _: &[!; 1] = unsafe { &*(1_usize as *const [!; 1]) }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/raw-bytes.rs:205:1 + --> $DIR/raw-bytes.rs:207:1 | LL | const _: &[!] = unsafe { &*(1_usize as *const [!; 1]) }; | ^^^^^^^^^^^^^ constructing invalid value at .[0]: encountered a value of the never type `!` @@ -481,7 +481,7 @@ LL | const _: &[!] = unsafe { &*(1_usize as *const [!; 1]) }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/raw-bytes.rs:206:1 + --> $DIR/raw-bytes.rs:208:1 | LL | const _: &[!] = unsafe { &*(1_usize as *const [!; 42]) }; | ^^^^^^^^^^^^^ constructing invalid value at .[0]: encountered a value of the never type `!` @@ -492,7 +492,7 @@ LL | const _: &[!] = unsafe { &*(1_usize as *const [!; 42]) }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/raw-bytes.rs:210:1 + --> $DIR/raw-bytes.rs:212:1 | LL | pub static S4: &[u8] = unsafe { from_raw_parts((&D1) as *const _ as _, 1) }; | ^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .[0]: encountered uninitialized memory, but expected an integer @@ -503,7 +503,7 @@ LL | pub static S4: &[u8] = unsafe { from_raw_parts((&D1) as *const _ as _, 1) } } error[E0080]: it is undefined behavior to use this value - --> $DIR/raw-bytes.rs:213:1 + --> $DIR/raw-bytes.rs:215:1 | LL | pub static S5: &[u8] = unsafe { from_raw_parts((&D3) as *const _ as _, mem::size_of::<&u32>()) }; | ^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .[0]: encountered a pointer, but expected an integer @@ -516,7 +516,7 @@ LL | pub static S5: &[u8] = unsafe { from_raw_parts((&D3) as *const _ as _, mem: = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported error[E0080]: it is undefined behavior to use this value - --> $DIR/raw-bytes.rs:216:1 + --> $DIR/raw-bytes.rs:218:1 | LL | pub static S6: &[bool] = unsafe { from_raw_parts((&D0) as *const _ as _, 4) }; | ^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .[0]: encountered 0x11, but expected a boolean @@ -527,7 +527,7 @@ LL | pub static S6: &[bool] = unsafe { from_raw_parts((&D0) as *const _ as _, 4) } error[E0080]: it is undefined behavior to use this value - --> $DIR/raw-bytes.rs:220:1 + --> $DIR/raw-bytes.rs:222:1 | LL | pub static S7: &[u16] = unsafe { | ^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .[1]: encountered uninitialized memory, but expected an integer @@ -538,7 +538,7 @@ LL | pub static S7: &[u16] = unsafe { } error[E0080]: it is undefined behavior to use this value - --> $DIR/raw-bytes.rs:227:1 + --> $DIR/raw-bytes.rs:229:1 | LL | pub static R4: &[u8] = unsafe { | ^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .[0]: encountered uninitialized memory, but expected an integer @@ -549,7 +549,7 @@ LL | pub static R4: &[u8] = unsafe { } error[E0080]: it is undefined behavior to use this value - --> $DIR/raw-bytes.rs:232:1 + --> $DIR/raw-bytes.rs:234:1 | LL | pub static R5: &[u8] = unsafe { | ^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .[0]: encountered a pointer, but expected an integer @@ -562,7 +562,7 @@ LL | pub static R5: &[u8] = unsafe { = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported error[E0080]: it is undefined behavior to use this value - --> $DIR/raw-bytes.rs:237:1 + --> $DIR/raw-bytes.rs:239:1 | LL | pub static R6: &[bool] = unsafe { | ^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .[0]: encountered 0x11, but expected a boolean diff --git a/tests/ui/consts/const-eval/raw-bytes.rs b/tests/ui/consts/const-eval/raw-bytes.rs index 20f1a9aae70..1a585d55a5f 100644 --- a/tests/ui/consts/const-eval/raw-bytes.rs +++ b/tests/ui/consts/const-eval/raw-bytes.rs @@ -2,6 +2,8 @@ //@ ignore-endian-big // ignore-tidy-linelength //@ normalize-stderr: "╾─*ALLOC[0-9]+(\+[a-z0-9]+)?()?─*╼" -> "╾ALLOC_ID$1╼" +//@ dont-require-annotations: NOTE + #![allow(invalid_value, unnecessary_transmutes)] #![feature(never_type, rustc_attrs, ptr_metadata, slice_from_ptr_range, const_slice_from_ptr_range)] @@ -83,11 +85,11 @@ const NULL_FAT_PTR: NonNull = unsafe { const UNALIGNED: &u16 = unsafe { mem::transmute(&[0u8; 4]) }; //~^ ERROR it is undefined behavior to use this value -//~| constructing invalid value: encountered an unaligned reference (required 2 byte alignment but found 1) +//~| NOTE constructing invalid value: encountered an unaligned reference (required 2 byte alignment but found 1) const UNALIGNED_BOX: Box = unsafe { mem::transmute(&[0u8; 4]) }; //~^ ERROR it is undefined behavior to use this value -//~| constructing invalid value: encountered an unaligned box (required 2 byte alignment but found 1) +//~| NOTE constructing invalid value: encountered an unaligned box (required 2 byte alignment but found 1) const NULL: &u16 = unsafe { mem::transmute(0usize) }; //~^ ERROR it is undefined behavior to use this value @@ -161,44 +163,44 @@ const SLICE_TOO_LONG_BOX: Box<[u8]> = unsafe { mem::transmute((&42u8, 999usize)) // bad data *inside* the slice const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }]; //~^ ERROR it is undefined behavior to use this value -//~| constant +//~| NOTE constant // bad: sized field is not okay const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3u8) }, [false]); //~^ ERROR it is undefined behavior to use this value -//~| constant +//~| NOTE constant // bad: unsized part is not okay const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::transmute(3u8) }]); //~^ ERROR it is undefined behavior to use this value -//~| constant +//~| NOTE constant // bad trait object const TRAIT_OBJ_SHORT_VTABLE_1: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, &3u8))) }; //~^ ERROR it is undefined behavior to use this value -//~| expected a vtable +//~| NOTE expected a vtable // bad trait object const TRAIT_OBJ_SHORT_VTABLE_2: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, &3u64))) }; //~^ ERROR it is undefined behavior to use this value -//~| expected a vtable +//~| NOTE expected a vtable // bad trait object const TRAIT_OBJ_INT_VTABLE: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, 4usize))) }; //~^ ERROR it is undefined behavior to use this value -//~| expected a vtable +//~| NOTE expected a vtable const TRAIT_OBJ_BAD_DROP_FN_NOT_FN_PTR: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, &[&42u8; 8]))) }; //~^ ERROR it is undefined behavior to use this value -//~| expected a vtable +//~| NOTE expected a vtable // bad data *inside* the trait object const TRAIT_OBJ_CONTENT_INVALID: &dyn Trait = unsafe { mem::transmute::<_, &bool>(&3u8) }; //~^ ERROR it is undefined behavior to use this value -//~| expected a boolean +//~| NOTE expected a boolean const RAW_TRAIT_OBJ_VTABLE_NULL: *const dyn Trait = unsafe { mem::transmute((&92u8, 0usize)) }; //~^ ERROR it is undefined behavior to use this value -//~| null pointer +//~| NOTE null pointer const RAW_TRAIT_OBJ_VTABLE_INVALID: *const dyn Trait = unsafe { mem::transmute((&92u8, &3u64)) }; //~^ ERROR it is undefined behavior to use this value -//~| vtable +//~| NOTE vtable // Uninhabited types const _: &[!; 1] = unsafe { &*(1_usize as *const [!; 1]) }; //~ ERROR undefined behavior diff --git a/tests/ui/consts/const-eval/ub-enum.rs b/tests/ui/consts/const-eval/ub-enum.rs index a5255ef95aa..ac543430da9 100644 --- a/tests/ui/consts/const-eval/ub-enum.rs +++ b/tests/ui/consts/const-eval/ub-enum.rs @@ -2,6 +2,8 @@ //@ normalize-stderr: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" //@ normalize-stderr: "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" //@ normalize-stderr: "0x0+" -> "0x0" +//@ dont-require-annotations: NOTE + #![feature(never_type)] #![allow(invalid_value, unnecessary_transmutes)] @@ -58,7 +60,7 @@ union MaybeUninit { } const BAD_ENUM2_UNDEF : Enum2 = unsafe { MaybeUninit { uninit: () }.init }; //~^ ERROR evaluation of constant value failed -//~| uninitialized +//~| NOTE uninitialized // Pointer value in an enum with a niche that is not just 0. const BAD_ENUM2_OPTION_PTR: Option = unsafe { mem::transmute(&0) }; diff --git a/tests/ui/consts/const-eval/ub-enum.stderr b/tests/ui/consts/const-eval/ub-enum.stderr index cfb7eaf537a..faec412b004 100644 --- a/tests/ui/consts/const-eval/ub-enum.stderr +++ b/tests/ui/consts/const-eval/ub-enum.stderr @@ -1,5 +1,5 @@ error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-enum.rs:27:1 + --> $DIR/ub-enum.rs:29:1 | LL | const BAD_ENUM: Enum = unsafe { mem::transmute(1usize) }; | ^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .: encountered 0x01, but expected a valid enum tag @@ -10,7 +10,7 @@ LL | const BAD_ENUM: Enum = unsafe { mem::transmute(1usize) }; } error[E0080]: evaluation of constant value failed - --> $DIR/ub-enum.rs:30:1 + --> $DIR/ub-enum.rs:32:1 | LL | const BAD_ENUM_PTR: Enum = unsafe { mem::transmute(&1) }; | ^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into integer @@ -19,7 +19,7 @@ LL | const BAD_ENUM_PTR: Enum = unsafe { mem::transmute(&1) }; = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported error[E0080]: evaluation of constant value failed - --> $DIR/ub-enum.rs:33:1 + --> $DIR/ub-enum.rs:35:1 | LL | const BAD_ENUM_WRAPPED: Wrap = unsafe { mem::transmute(&1) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into integer @@ -28,7 +28,7 @@ LL | const BAD_ENUM_WRAPPED: Wrap = unsafe { mem::transmute(&1) }; = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-enum.rs:45:1 + --> $DIR/ub-enum.rs:47:1 | LL | const BAD_ENUM2: Enum2 = unsafe { mem::transmute(0usize) }; | ^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .: encountered 0x0, but expected a valid enum tag @@ -39,7 +39,7 @@ LL | const BAD_ENUM2: Enum2 = unsafe { mem::transmute(0usize) }; } error[E0080]: evaluation of constant value failed - --> $DIR/ub-enum.rs:47:1 + --> $DIR/ub-enum.rs:49:1 | LL | const BAD_ENUM2_PTR: Enum2 = unsafe { mem::transmute(&0) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into integer @@ -48,7 +48,7 @@ LL | const BAD_ENUM2_PTR: Enum2 = unsafe { mem::transmute(&0) }; = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported error[E0080]: evaluation of constant value failed - --> $DIR/ub-enum.rs:50:1 + --> $DIR/ub-enum.rs:52:1 | LL | const BAD_ENUM2_WRAPPED: Wrap = unsafe { mem::transmute(&0) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into integer @@ -57,13 +57,13 @@ LL | const BAD_ENUM2_WRAPPED: Wrap = unsafe { mem::transmute(&0) }; = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported error[E0080]: evaluation of constant value failed - --> $DIR/ub-enum.rs:59:42 + --> $DIR/ub-enum.rs:61:42 | LL | const BAD_ENUM2_UNDEF : Enum2 = unsafe { MaybeUninit { uninit: () }.init }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory error[E0080]: evaluation of constant value failed - --> $DIR/ub-enum.rs:64:1 + --> $DIR/ub-enum.rs:66:1 | LL | const BAD_ENUM2_OPTION_PTR: Option = unsafe { mem::transmute(&0) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into integer @@ -72,7 +72,7 @@ LL | const BAD_ENUM2_OPTION_PTR: Option = unsafe { mem::transmute(&0) }; = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-enum.rs:81:1 + --> $DIR/ub-enum.rs:83:1 | LL | const BAD_UNINHABITED_VARIANT1: UninhDiscriminant = unsafe { mem::transmute(1u8) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .: encountered an uninhabited enum variant @@ -83,7 +83,7 @@ LL | const BAD_UNINHABITED_VARIANT1: UninhDiscriminant = unsafe { mem::transmute } error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-enum.rs:83:1 + --> $DIR/ub-enum.rs:85:1 | LL | const BAD_UNINHABITED_VARIANT2: UninhDiscriminant = unsafe { mem::transmute(3u8) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .: encountered an uninhabited enum variant @@ -94,7 +94,7 @@ LL | const BAD_UNINHABITED_VARIANT2: UninhDiscriminant = unsafe { mem::transmute } error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-enum.rs:91:1 + --> $DIR/ub-enum.rs:93:1 | LL | const BAD_OPTION_CHAR: Option<(char, char)> = Some(('x', unsafe { mem::transmute(!0u32) })); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at ..0.1: encountered 0xffffffff, but expected a valid unicode scalar value (in `0..=0x10FFFF` but not in `0xD800..=0xDFFF`) @@ -105,19 +105,19 @@ LL | const BAD_OPTION_CHAR: Option<(char, char)> = Some(('x', unsafe { mem::tran } error[E0080]: evaluation of constant value failed - --> $DIR/ub-enum.rs:96:77 + --> $DIR/ub-enum.rs:98:77 | LL | const BAD_UNINHABITED_WITH_DATA1: Result<(i32, Never), (i32, !)> = unsafe { mem::transmute(0u64) }; | ^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .: encountered an uninhabited enum variant error[E0080]: evaluation of constant value failed - --> $DIR/ub-enum.rs:98:77 + --> $DIR/ub-enum.rs:100:77 | LL | const BAD_UNINHABITED_WITH_DATA2: Result<(i32, !), (i32, Never)> = unsafe { mem::transmute(0u64) }; | ^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .: encountered an uninhabited enum variant error[E0080]: evaluation of constant value failed - --> $DIR/ub-enum.rs:103:14 + --> $DIR/ub-enum.rs:105:14 | LL | unsafe { std::mem::discriminant(&*(&() as *const () as *const Never)); }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ read discriminant of an uninhabited enum variant diff --git a/tests/ui/consts/const-eval/ub-incorrect-vtable.rs b/tests/ui/consts/const-eval/ub-incorrect-vtable.rs index 8058f7693a7..30c0ae3bb5a 100644 --- a/tests/ui/consts/const-eval/ub-incorrect-vtable.rs +++ b/tests/ui/consts/const-eval/ub-incorrect-vtable.rs @@ -11,19 +11,19 @@ // errors are emitted instead of ICEs. //@ stderr-per-bitwidth - +//@ dont-require-annotations: NOTE trait Trait {} const INVALID_VTABLE_ALIGNMENT: &dyn Trait = unsafe { std::mem::transmute((&92u8, &[0usize, 1usize, 1000usize])) }; //~^^ ERROR it is undefined behavior to use this value -//~| vtable +//~| NOTE vtable const INVALID_VTABLE_SIZE: &dyn Trait = unsafe { std::mem::transmute((&92u8, &[1usize, usize::MAX, 1usize])) }; //~^^ ERROR it is undefined behavior to use this value -//~| vtable +//~| NOTE vtable #[repr(transparent)] struct W(T); @@ -33,18 +33,18 @@ fn drop_me(_: *mut usize) {} const INVALID_VTABLE_ALIGNMENT_UB: W<&dyn Trait> = unsafe { std::mem::transmute((&92u8, &(drop_me as fn(*mut usize), 1usize, 1000usize))) }; //~^^ ERROR it is undefined behavior to use this value -//~| expected a vtable pointer +//~| NOTE expected a vtable pointer const INVALID_VTABLE_SIZE_UB: W<&dyn Trait> = unsafe { std::mem::transmute((&92u8, &(drop_me as fn(*mut usize), usize::MAX, 1usize))) }; //~^^ ERROR it is undefined behavior to use this value -//~| expected a vtable pointer +//~| NOTE expected a vtable pointer // Even if the vtable has a fn ptr and a reasonable size+align, it still does not work. const INVALID_VTABLE_UB: W<&dyn Trait> = unsafe { std::mem::transmute((&92u8, &(drop_me as fn(*mut usize), 1usize, 1usize))) }; //~^^ ERROR it is undefined behavior to use this value -//~| expected a vtable pointer +//~| NOTE expected a vtable pointer // Trying to access the data in a vtable does not work, either. @@ -90,7 +90,7 @@ union Transmute { const FOO: &dyn Bar = &Foo { foo: 128, bar: false }; const G: Wide = unsafe { Transmute { t: FOO }.u }; //~^ ERROR it is undefined behavior to use this value -//~| encountered a dangling reference +//~| NOTE encountered a dangling reference // (it is dangling because vtables do not contain memory that can be dereferenced) fn main() {} diff --git a/tests/ui/consts/const-eval/ub-int-array.rs b/tests/ui/consts/const-eval/ub-int-array.rs index cde0749dc5f..169ac7f1519 100644 --- a/tests/ui/consts/const-eval/ub-int-array.rs +++ b/tests/ui/consts/const-eval/ub-int-array.rs @@ -1,6 +1,8 @@ //! Test the "array of int" fast path in validity checking, and in particular whether it //! points at the right array element. +//@ dont-require-annotations: NOTE + use std::mem; #[repr(C)] @@ -17,7 +19,7 @@ impl MaybeUninit { const UNINIT_INT_0: [u32; 3] = unsafe { //~^ ERROR it is undefined behavior to use this value - //~| invalid value at [0] + //~| NOTE invalid value at [0] mem::transmute([ MaybeUninit { uninit: () }, // Constants chosen to achieve endianness-independent hex dump. @@ -27,7 +29,7 @@ const UNINIT_INT_0: [u32; 3] = unsafe { }; const UNINIT_INT_1: [u32; 3] = unsafe { //~^ ERROR it is undefined behavior to use this value - //~| invalid value at [1] + //~| NOTE invalid value at [1] mem::transmute([ MaybeUninit::new(0u8), MaybeUninit::new(0u8), @@ -45,7 +47,7 @@ const UNINIT_INT_1: [u32; 3] = unsafe { }; const UNINIT_INT_2: [u32; 3] = unsafe { //~^ ERROR it is undefined behavior to use this value - //~| invalid value at [2] + //~| NOTE invalid value at [2] mem::transmute([ MaybeUninit::new(0u8), MaybeUninit::new(0u8), diff --git a/tests/ui/consts/const-eval/ub-int-array.stderr b/tests/ui/consts/const-eval/ub-int-array.stderr index c8efd7e1bd3..d6ef9bcfeba 100644 --- a/tests/ui/consts/const-eval/ub-int-array.stderr +++ b/tests/ui/consts/const-eval/ub-int-array.stderr @@ -1,5 +1,5 @@ error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-int-array.rs:18:1 + --> $DIR/ub-int-array.rs:20:1 | LL | const UNINIT_INT_0: [u32; 3] = unsafe { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at [0]: encountered uninitialized memory, but expected an integer @@ -10,7 +10,7 @@ LL | const UNINIT_INT_0: [u32; 3] = unsafe { } error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-int-array.rs:28:1 + --> $DIR/ub-int-array.rs:30:1 | LL | const UNINIT_INT_1: [u32; 3] = unsafe { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at [1]: encountered uninitialized memory, but expected an integer @@ -21,7 +21,7 @@ LL | const UNINIT_INT_1: [u32; 3] = unsafe { } error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-int-array.rs:46:1 + --> $DIR/ub-int-array.rs:48:1 | LL | const UNINIT_INT_2: [u32; 3] = unsafe { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at [2]: encountered uninitialized memory, but expected an integer diff --git a/tests/ui/consts/const-eval/ub-nonnull.rs b/tests/ui/consts/const-eval/ub-nonnull.rs index b8e312759b4..8ae913db1e4 100644 --- a/tests/ui/consts/const-eval/ub-nonnull.rs +++ b/tests/ui/consts/const-eval/ub-nonnull.rs @@ -1,6 +1,8 @@ // Strip out raw byte dumps to make comparison platform-independent: //@ normalize-stderr: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" //@ normalize-stderr: "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?─*╼ )+ *│.*" -> "HEX_DUMP" +//@ dont-require-annotations: NOTE + #![allow(invalid_value)] // make sure we cannot allow away the errors tested here #![feature(rustc_attrs, ptr_metadata)] @@ -33,7 +35,7 @@ union MaybeUninit { } const UNINIT: NonZero = unsafe { MaybeUninit { uninit: () }.init }; //~^ ERROR evaluation of constant value failed -//~| uninitialized +//~| NOTE uninitialized // Also test other uses of rustc_layout_scalar_valid_range_start diff --git a/tests/ui/consts/const-eval/ub-nonnull.stderr b/tests/ui/consts/const-eval/ub-nonnull.stderr index 0e4926eb49e..c2cafbf60bc 100644 --- a/tests/ui/consts/const-eval/ub-nonnull.stderr +++ b/tests/ui/consts/const-eval/ub-nonnull.stderr @@ -1,5 +1,5 @@ error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-nonnull.rs:14:1 + --> $DIR/ub-nonnull.rs:16:1 | LL | const NULL_PTR: NonNull = unsafe { mem::transmute(0usize) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0, but expected something greater or equal to 1 @@ -10,13 +10,13 @@ LL | const NULL_PTR: NonNull = unsafe { mem::transmute(0usize) }; } error[E0080]: evaluation of constant value failed - --> $DIR/ub-nonnull.rs:20:29 + --> $DIR/ub-nonnull.rs:22:29 | LL | let out_of_bounds_ptr = &ptr[255]; | ^^^^^^^^^ out-of-bounds pointer arithmetic: expected a pointer to 255 bytes of memory, but got ALLOC1 which is only 1 byte from the end of the allocation error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-nonnull.rs:24:1 + --> $DIR/ub-nonnull.rs:26:1 | LL | const NULL_U8: NonZero = unsafe { mem::transmute(0u8) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered 0, but expected something greater or equal to 1 @@ -27,7 +27,7 @@ LL | const NULL_U8: NonZero = unsafe { mem::transmute(0u8) }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-nonnull.rs:26:1 + --> $DIR/ub-nonnull.rs:28:1 | LL | const NULL_USIZE: NonZero = unsafe { mem::transmute(0usize) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered 0, but expected something greater or equal to 1 @@ -38,13 +38,13 @@ LL | const NULL_USIZE: NonZero = unsafe { mem::transmute(0usize) }; } error[E0080]: evaluation of constant value failed - --> $DIR/ub-nonnull.rs:34:38 + --> $DIR/ub-nonnull.rs:36:38 | LL | const UNINIT: NonZero = unsafe { MaybeUninit { uninit: () }.init }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-nonnull.rs:43:1 + --> $DIR/ub-nonnull.rs:45:1 | LL | const BAD_RANGE1: RestrictedRange1 = unsafe { RestrictedRange1(42) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 42, but expected something in the range 10..=30 @@ -55,7 +55,7 @@ LL | const BAD_RANGE1: RestrictedRange1 = unsafe { RestrictedRange1(42) }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-nonnull.rs:49:1 + --> $DIR/ub-nonnull.rs:51:1 | LL | const BAD_RANGE2: RestrictedRange2 = unsafe { RestrictedRange2(20) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 20, but expected something less or equal to 10, or greater or equal to 30 @@ -66,7 +66,7 @@ LL | const BAD_RANGE2: RestrictedRange2 = unsafe { RestrictedRange2(20) }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-nonnull.rs:52:1 + --> $DIR/ub-nonnull.rs:54:1 | LL | const NULL_FAT_PTR: NonNull = unsafe { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0, but expected something greater or equal to 1 diff --git a/tests/ui/consts/const-eval/ub-ref-ptr.rs b/tests/ui/consts/const-eval/ub-ref-ptr.rs index 50e510a3d54..988e6c62e34 100644 --- a/tests/ui/consts/const-eval/ub-ref-ptr.rs +++ b/tests/ui/consts/const-eval/ub-ref-ptr.rs @@ -2,6 +2,8 @@ // Strip out raw byte dumps to make comparison platform-independent: //@ normalize-stderr: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" //@ normalize-stderr: "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" +//@ dont-require-annotations: NOTE + #![allow(invalid_value)] use std::mem; @@ -14,11 +16,11 @@ union MaybeUninit { const UNALIGNED: &u16 = unsafe { mem::transmute(&[0u8; 4]) }; //~^ ERROR it is undefined behavior to use this value -//~| constructing invalid value: encountered an unaligned reference (required 2 byte alignment but found 1) +//~| NOTE constructing invalid value: encountered an unaligned reference (required 2 byte alignment but found 1) const UNALIGNED_BOX: Box = unsafe { mem::transmute(&[0u8; 4]) }; //~^ ERROR it is undefined behavior to use this value -//~| constructing invalid value: encountered an unaligned box (required 2 byte alignment but found 1) +//~| NOTE constructing invalid value: encountered an unaligned box (required 2 byte alignment but found 1) const NULL: &u16 = unsafe { mem::transmute(0usize) }; //~^ ERROR it is undefined behavior to use this value @@ -47,13 +49,13 @@ const USIZE_AS_BOX: Box = unsafe { mem::transmute(1337usize) }; const UNINIT_PTR: *const i32 = unsafe { MaybeUninit { uninit: () }.init }; //~^ ERROR evaluation of constant value failed -//~| uninitialized +//~| NOTE uninitialized const NULL_FN_PTR: fn() = unsafe { mem::transmute(0usize) }; //~^ ERROR it is undefined behavior to use this value const UNINIT_FN_PTR: fn() = unsafe { MaybeUninit { uninit: () }.init }; //~^ ERROR evaluation of constant value failed -//~| uninitialized +//~| NOTE uninitialized const DANGLING_FN_PTR: fn() = unsafe { mem::transmute(13usize) }; //~^ ERROR it is undefined behavior to use this value const DATA_FN_PTR: fn() = unsafe { mem::transmute(&13) }; diff --git a/tests/ui/consts/const-eval/ub-ref-ptr.stderr b/tests/ui/consts/const-eval/ub-ref-ptr.stderr index 72a523282e6..de5e721c3f7 100644 --- a/tests/ui/consts/const-eval/ub-ref-ptr.stderr +++ b/tests/ui/consts/const-eval/ub-ref-ptr.stderr @@ -1,5 +1,5 @@ error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-ref-ptr.rs:15:1 + --> $DIR/ub-ref-ptr.rs:17:1 | LL | const UNALIGNED: &u16 = unsafe { mem::transmute(&[0u8; 4]) }; | ^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered an unaligned reference (required 2 byte alignment but found 1) @@ -10,7 +10,7 @@ LL | const UNALIGNED: &u16 = unsafe { mem::transmute(&[0u8; 4]) }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-ref-ptr.rs:19:1 + --> $DIR/ub-ref-ptr.rs:21:1 | LL | const UNALIGNED_BOX: Box = unsafe { mem::transmute(&[0u8; 4]) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered an unaligned box (required 2 byte alignment but found 1) @@ -21,7 +21,7 @@ LL | const UNALIGNED_BOX: Box = unsafe { mem::transmute(&[0u8; 4]) }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-ref-ptr.rs:23:1 + --> $DIR/ub-ref-ptr.rs:25:1 | LL | const NULL: &u16 = unsafe { mem::transmute(0usize) }; | ^^^^^^^^^^^^^^^^ constructing invalid value: encountered a null reference @@ -32,7 +32,7 @@ LL | const NULL: &u16 = unsafe { mem::transmute(0usize) }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-ref-ptr.rs:26:1 + --> $DIR/ub-ref-ptr.rs:28:1 | LL | const NULL_BOX: Box = unsafe { mem::transmute(0usize) }; | ^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a null box @@ -43,7 +43,7 @@ LL | const NULL_BOX: Box = unsafe { mem::transmute(0usize) }; } error[E0080]: evaluation of constant value failed - --> $DIR/ub-ref-ptr.rs:33:1 + --> $DIR/ub-ref-ptr.rs:35:1 | LL | const REF_AS_USIZE: usize = unsafe { mem::transmute(&0) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into integer @@ -52,7 +52,7 @@ LL | const REF_AS_USIZE: usize = unsafe { mem::transmute(&0) }; = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported error[E0080]: evaluation of constant value failed - --> $DIR/ub-ref-ptr.rs:36:39 + --> $DIR/ub-ref-ptr.rs:38:39 | LL | const REF_AS_USIZE_SLICE: &[usize] = &[unsafe { mem::transmute(&0) }]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into integer @@ -61,13 +61,13 @@ LL | const REF_AS_USIZE_SLICE: &[usize] = &[unsafe { mem::transmute(&0) }]; = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported note: erroneous constant encountered - --> $DIR/ub-ref-ptr.rs:36:38 + --> $DIR/ub-ref-ptr.rs:38:38 | LL | const REF_AS_USIZE_SLICE: &[usize] = &[unsafe { mem::transmute(&0) }]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0080]: evaluation of constant value failed - --> $DIR/ub-ref-ptr.rs:39:86 + --> $DIR/ub-ref-ptr.rs:41:86 | LL | const REF_AS_USIZE_BOX_SLICE: Box<[usize]> = unsafe { mem::transmute::<&[usize], _>(&[mem::transmute(&0)]) }; | ^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into integer @@ -76,13 +76,13 @@ LL | const REF_AS_USIZE_BOX_SLICE: Box<[usize]> = unsafe { mem::transmute::<&[us = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported note: erroneous constant encountered - --> $DIR/ub-ref-ptr.rs:39:85 + --> $DIR/ub-ref-ptr.rs:41:85 | LL | const REF_AS_USIZE_BOX_SLICE: Box<[usize]> = unsafe { mem::transmute::<&[usize], _>(&[mem::transmute(&0)]) }; | ^^^^^^^^^^^^^^^^^^^^^ error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-ref-ptr.rs:42:1 + --> $DIR/ub-ref-ptr.rs:44:1 | LL | const USIZE_AS_REF: &'static u8 = unsafe { mem::transmute(1337usize) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a dangling reference (0x539[noalloc] has no provenance) @@ -93,7 +93,7 @@ LL | const USIZE_AS_REF: &'static u8 = unsafe { mem::transmute(1337usize) }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-ref-ptr.rs:45:1 + --> $DIR/ub-ref-ptr.rs:47:1 | LL | const USIZE_AS_BOX: Box = unsafe { mem::transmute(1337usize) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a dangling box (0x539[noalloc] has no provenance) @@ -104,13 +104,13 @@ LL | const USIZE_AS_BOX: Box = unsafe { mem::transmute(1337usize) }; } error[E0080]: evaluation of constant value failed - --> $DIR/ub-ref-ptr.rs:48:41 + --> $DIR/ub-ref-ptr.rs:50:41 | LL | const UNINIT_PTR: *const i32 = unsafe { MaybeUninit { uninit: () }.init }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-ref-ptr.rs:52:1 + --> $DIR/ub-ref-ptr.rs:54:1 | LL | const NULL_FN_PTR: fn() = unsafe { mem::transmute(0usize) }; | ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered null pointer, but expected a function pointer @@ -121,13 +121,13 @@ LL | const NULL_FN_PTR: fn() = unsafe { mem::transmute(0usize) }; } error[E0080]: evaluation of constant value failed - --> $DIR/ub-ref-ptr.rs:54:38 + --> $DIR/ub-ref-ptr.rs:56:38 | LL | const UNINIT_FN_PTR: fn() = unsafe { MaybeUninit { uninit: () }.init }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-ref-ptr.rs:57:1 + --> $DIR/ub-ref-ptr.rs:59:1 | LL | const DANGLING_FN_PTR: fn() = unsafe { mem::transmute(13usize) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0xd[noalloc], but expected a function pointer @@ -138,7 +138,7 @@ LL | const DANGLING_FN_PTR: fn() = unsafe { mem::transmute(13usize) }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-ref-ptr.rs:59:1 + --> $DIR/ub-ref-ptr.rs:61:1 | LL | const DATA_FN_PTR: fn() = unsafe { mem::transmute(&13) }; | ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered ALLOC2, but expected a function pointer @@ -149,7 +149,7 @@ LL | const DATA_FN_PTR: fn() = unsafe { mem::transmute(&13) }; } error[E0080]: evaluation of constant value failed - --> $DIR/ub-ref-ptr.rs:66:5 + --> $DIR/ub-ref-ptr.rs:68:5 | LL | ptr.read(); | ^^^^^^^^^^ accessing memory based on pointer with alignment 1, but alignment 4 is required diff --git a/tests/ui/consts/const-eval/ub-uninhabit.rs b/tests/ui/consts/const-eval/ub-uninhabit.rs index d0515a4e6f0..3a5e291d5df 100644 --- a/tests/ui/consts/const-eval/ub-uninhabit.rs +++ b/tests/ui/consts/const-eval/ub-uninhabit.rs @@ -1,6 +1,8 @@ // Strip out raw byte dumps to make comparison platform-independent: //@ normalize-stderr: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" //@ normalize-stderr: "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" +//@ dont-require-annotations: NOTE + #![feature(core_intrinsics)] #![feature(never_type)] @@ -18,15 +20,15 @@ union MaybeUninit { const BAD_BAD_BAD: Bar = unsafe { MaybeUninit { uninit: () }.init }; //~^ ERROR evaluation of constant value failed -//~| constructing invalid value +//~| NOTE constructing invalid value const BAD_BAD_REF: &Bar = unsafe { mem::transmute(1usize) }; //~^ ERROR it is undefined behavior to use this value -//~| constructing invalid value +//~| NOTE constructing invalid value const BAD_BAD_ARRAY: [Bar; 1] = unsafe { MaybeUninit { uninit: () }.init }; //~^ ERROR evaluation of constant value failed -//~| constructing invalid value +//~| NOTE constructing invalid value const READ_NEVER: () = unsafe { @@ -34,7 +36,7 @@ const READ_NEVER: () = unsafe { let ptr = mem.as_ptr().cast::(); let _val = intrinsics::read_via_copy(ptr); //~^ ERROR evaluation of constant value failed - //~| constructing invalid value + //~| NOTE constructing invalid value }; diff --git a/tests/ui/consts/const-eval/ub-uninhabit.stderr b/tests/ui/consts/const-eval/ub-uninhabit.stderr index d26f4e03666..9d3f93279e5 100644 --- a/tests/ui/consts/const-eval/ub-uninhabit.stderr +++ b/tests/ui/consts/const-eval/ub-uninhabit.stderr @@ -1,11 +1,11 @@ error[E0080]: evaluation of constant value failed - --> $DIR/ub-uninhabit.rs:19:35 + --> $DIR/ub-uninhabit.rs:21:35 | LL | const BAD_BAD_BAD: Bar = unsafe { MaybeUninit { uninit: () }.init }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a value of uninhabited type `Bar` error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-uninhabit.rs:23:1 + --> $DIR/ub-uninhabit.rs:25:1 | LL | const BAD_BAD_REF: &Bar = unsafe { mem::transmute(1usize) }; | ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a reference pointing to uninhabited type Bar @@ -16,13 +16,13 @@ LL | const BAD_BAD_REF: &Bar = unsafe { mem::transmute(1usize) }; } error[E0080]: evaluation of constant value failed - --> $DIR/ub-uninhabit.rs:27:42 + --> $DIR/ub-uninhabit.rs:29:42 | LL | const BAD_BAD_ARRAY: [Bar; 1] = unsafe { MaybeUninit { uninit: () }.init }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at [0]: encountered a value of uninhabited type `Bar` error[E0080]: evaluation of constant value failed - --> $DIR/ub-uninhabit.rs:35:16 + --> $DIR/ub-uninhabit.rs:37:16 | LL | let _val = intrinsics::read_via_copy(ptr); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a value of the never type `!` diff --git a/tests/ui/consts/const-eval/ub-wide-ptr.rs b/tests/ui/consts/const-eval/ub-wide-ptr.rs index 4e2defc1a09..4b9bbb8066d 100644 --- a/tests/ui/consts/const-eval/ub-wide-ptr.rs +++ b/tests/ui/consts/const-eval/ub-wide-ptr.rs @@ -9,7 +9,7 @@ use std::{ptr, mem}; //@ normalize-stderr: "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" //@ normalize-stderr: "offset \d+" -> "offset N" //@ normalize-stderr: "size \d+" -> "size N" - +//@ dont-require-annotations: NOTE /// A newtype wrapper to prevent MIR generation from inserting reborrows that would affect the error /// message. @@ -62,7 +62,7 @@ const SLICE_VALID: &[u8] = unsafe { mem::transmute((&42u8, 1usize)) }; // bad slice: length uninit const SLICE_LENGTH_UNINIT: &[u8] = unsafe { //~^ ERROR evaluation of constant value failed -//~| uninitialized +//~| NOTE uninitialized let uninit_len = MaybeUninit:: { uninit: () }; mem::transmute((42, uninit_len)) }; @@ -85,18 +85,18 @@ const SLICE_LENGTH_PTR_BOX: Box<[u8]> = unsafe { mem::transmute((&42u8, &3)) }; // bad data *inside* the slice const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }]; //~^ ERROR it is undefined behavior to use this value -//~| constant +//~| NOTE constant // good MySliceBool const MYSLICE_GOOD: &MySliceBool = &MySlice(true, [false]); // bad: sized field is not okay const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3u8) }, [false]); //~^ ERROR it is undefined behavior to use this value -//~| constant +//~| NOTE constant // bad: unsized part is not okay const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::transmute(3u8) }]); //~^ ERROR it is undefined behavior to use this value -//~| constant +//~| NOTE constant // # raw slice const RAW_SLICE_VALID: *const [u8] = unsafe { mem::transmute((&42u8, 1usize)) }; // ok @@ -104,7 +104,7 @@ const RAW_SLICE_TOO_LONG: *const [u8] = unsafe { mem::transmute((&42u8, 999usize const RAW_SLICE_MUCH_TOO_LONG: *const [u8] = unsafe { mem::transmute((&42u8, usize::MAX)) }; // ok because raw const RAW_SLICE_LENGTH_UNINIT: *const [u8] = unsafe { //~^ ERROR evaluation of constant value failed -//~| uninitialized +//~| NOTE uninitialized let uninit_len = MaybeUninit:: { uninit: () }; mem::transmute((42, uninit_len)) }; @@ -113,40 +113,40 @@ const RAW_SLICE_LENGTH_UNINIT: *const [u8] = unsafe { // bad trait object const TRAIT_OBJ_SHORT_VTABLE_1: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, &3u8))) }; //~^ ERROR it is undefined behavior to use this value -//~| vtable +//~| NOTE vtable // bad trait object const TRAIT_OBJ_SHORT_VTABLE_2: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, &3u64))) }; //~^ ERROR it is undefined behavior to use this value -//~| vtable +//~| NOTE vtable // bad trait object const TRAIT_OBJ_INT_VTABLE: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, 4usize))) }; //~^ ERROR it is undefined behavior to use this value -//~| vtable +//~| NOTE vtable const TRAIT_OBJ_UNALIGNED_VTABLE: &dyn Trait = unsafe { mem::transmute((&92u8, &[0u8; 128])) }; //~^ ERROR it is undefined behavior to use this value -//~| vtable +//~| NOTE vtable const TRAIT_OBJ_BAD_DROP_FN_NULL: &dyn Trait = unsafe { mem::transmute((&92u8, &[0usize; 8])) }; //~^ ERROR it is undefined behavior to use this value -//~| vtable +//~| NOTE vtable const TRAIT_OBJ_BAD_DROP_FN_INT: &dyn Trait = unsafe { mem::transmute((&92u8, &[1usize; 8])) }; //~^ ERROR it is undefined behavior to use this value -//~| vtable +//~| NOTE vtable const TRAIT_OBJ_BAD_DROP_FN_NOT_FN_PTR: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, &[&42u8; 8]))) }; //~^ ERROR it is undefined behavior to use this value -//~| vtable +//~| NOTE vtable // bad data *inside* the trait object const TRAIT_OBJ_CONTENT_INVALID: &dyn Trait = unsafe { mem::transmute::<_, &bool>(&3u8) }; //~^ ERROR it is undefined behavior to use this value -//~| expected a boolean +//~| NOTE expected a boolean // # raw trait object const RAW_TRAIT_OBJ_VTABLE_NULL: *const dyn Trait = unsafe { mem::transmute((&92u8, 0usize)) }; //~^ ERROR it is undefined behavior to use this value -//~| null pointer +//~| NOTE null pointer const RAW_TRAIT_OBJ_VTABLE_INVALID: *const dyn Trait = unsafe { mem::transmute((&92u8, &3u64)) }; //~^ ERROR it is undefined behavior to use this value -//~| vtable +//~| NOTE vtable const RAW_TRAIT_OBJ_CONTENT_INVALID: *const dyn Trait = unsafe { mem::transmute::<_, &bool>(&3u8) } as *const dyn Trait; // ok because raw // Officially blessed way to get the vtable const DYN_METADATA: ptr::DynMetadata = ptr::metadata::(ptr::null::()); @@ -155,12 +155,12 @@ const DYN_METADATA: ptr::DynMetadata = ptr::metadata::(ptr:: static mut RAW_TRAIT_OBJ_VTABLE_NULL_THROUGH_REF: *const dyn Trait = unsafe { mem::transmute::<_, &dyn Trait>((&92u8, 0usize)) //~^^ ERROR it is undefined behavior to use this value - //~| null pointer + //~| NOTE null pointer }; static mut RAW_TRAIT_OBJ_VTABLE_INVALID_THROUGH_REF: *const dyn Trait = unsafe { mem::transmute::<_, &dyn Trait>((&92u8, &3u64)) //~^^ ERROR it is undefined behavior to use this value - //~| vtable + //~| NOTE vtable }; fn main() {} diff --git a/tests/ui/consts/const-eval/union-const-eval-field.rs b/tests/ui/consts/const-eval/union-const-eval-field.rs index c9799989ea8..55e9abe72e0 100644 --- a/tests/ui/consts/const-eval/union-const-eval-field.rs +++ b/tests/ui/consts/const-eval/union-const-eval-field.rs @@ -1,3 +1,5 @@ +//@ dont-require-annotations: NOTE + type Field1 = i32; type Field2 = f32; type Field3 = i64; @@ -25,7 +27,7 @@ const fn read_field2() -> Field2 { const fn read_field3() -> Field3 { const FIELD3: Field3 = unsafe { UNION.field3 }; //~^ ERROR evaluation of constant value failed - //~| uninitialized + //~| NOTE uninitialized FIELD3 } diff --git a/tests/ui/consts/const-eval/union-const-eval-field.stderr b/tests/ui/consts/const-eval/union-const-eval-field.stderr index b1de225ec58..4fd6b80381c 100644 --- a/tests/ui/consts/const-eval/union-const-eval-field.stderr +++ b/tests/ui/consts/const-eval/union-const-eval-field.stderr @@ -1,17 +1,17 @@ error[E0080]: evaluation of constant value failed - --> $DIR/union-const-eval-field.rs:26:37 + --> $DIR/union-const-eval-field.rs:28:37 | LL | const FIELD3: Field3 = unsafe { UNION.field3 }; | ^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory note: erroneous constant encountered - --> $DIR/union-const-eval-field.rs:29:5 + --> $DIR/union-const-eval-field.rs:31:5 | LL | FIELD3 | ^^^^^^ note: erroneous constant encountered - --> $DIR/union-const-eval-field.rs:29:5 + --> $DIR/union-const-eval-field.rs:31:5 | LL | FIELD3 | ^^^^^^ diff --git a/tests/ui/consts/const-eval/union-ub.32bit.stderr b/tests/ui/consts/const-eval/union-ub.32bit.stderr index e5c8f88be98..38ded4d65cf 100644 --- a/tests/ui/consts/const-eval/union-ub.32bit.stderr +++ b/tests/ui/consts/const-eval/union-ub.32bit.stderr @@ -1,5 +1,5 @@ error[E0080]: it is undefined behavior to use this value - --> $DIR/union-ub.rs:32:1 + --> $DIR/union-ub.rs:33:1 | LL | const BAD_BOOL: bool = unsafe { DummyUnion { u8: 42 }.bool}; | ^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0x2a, but expected a boolean @@ -10,7 +10,7 @@ LL | const BAD_BOOL: bool = unsafe { DummyUnion { u8: 42 }.bool}; } error[E0080]: evaluation of constant value failed - --> $DIR/union-ub.rs:34:36 + --> $DIR/union-ub.rs:35:36 | LL | const UNINIT_BOOL: bool = unsafe { DummyUnion { unit: () }.bool}; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory diff --git a/tests/ui/consts/const-eval/union-ub.64bit.stderr b/tests/ui/consts/const-eval/union-ub.64bit.stderr index e5c8f88be98..38ded4d65cf 100644 --- a/tests/ui/consts/const-eval/union-ub.64bit.stderr +++ b/tests/ui/consts/const-eval/union-ub.64bit.stderr @@ -1,5 +1,5 @@ error[E0080]: it is undefined behavior to use this value - --> $DIR/union-ub.rs:32:1 + --> $DIR/union-ub.rs:33:1 | LL | const BAD_BOOL: bool = unsafe { DummyUnion { u8: 42 }.bool}; | ^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0x2a, but expected a boolean @@ -10,7 +10,7 @@ LL | const BAD_BOOL: bool = unsafe { DummyUnion { u8: 42 }.bool}; } error[E0080]: evaluation of constant value failed - --> $DIR/union-ub.rs:34:36 + --> $DIR/union-ub.rs:35:36 | LL | const UNINIT_BOOL: bool = unsafe { DummyUnion { unit: () }.bool}; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory diff --git a/tests/ui/consts/const-eval/union-ub.rs b/tests/ui/consts/const-eval/union-ub.rs index 5eb4ad4b47f..7d8fd7446a0 100644 --- a/tests/ui/consts/const-eval/union-ub.rs +++ b/tests/ui/consts/const-eval/union-ub.rs @@ -1,4 +1,5 @@ //@ stderr-per-bitwidth +//@ dont-require-annotations: NOTE #[repr(C)] union DummyUnion { @@ -33,7 +34,7 @@ const BAD_BOOL: bool = unsafe { DummyUnion { u8: 42 }.bool}; //~^ ERROR it is undefined behavior to use this value const UNINIT_BOOL: bool = unsafe { DummyUnion { unit: () }.bool}; //~^ ERROR evaluation of constant value failed -//~| uninitialized +//~| NOTE uninitialized // The value is not valid for any union variant, but that's fine // unions are just a convenient way to transmute bits around diff --git a/tests/ui/consts/const-eval/unwind-abort.rs b/tests/ui/consts/const-eval/unwind-abort.rs index fee53f8528d..b239dba0239 100644 --- a/tests/ui/consts/const-eval/unwind-abort.rs +++ b/tests/ui/consts/const-eval/unwind-abort.rs @@ -1,5 +1,7 @@ +//@ dont-require-annotations: NOTE + const extern "C" fn foo() { - panic!() //~ inside `foo` + panic!() //~ NOTE inside `foo` } const _: () = foo(); //~ ERROR evaluation of constant value failed diff --git a/tests/ui/consts/const-eval/unwind-abort.stderr b/tests/ui/consts/const-eval/unwind-abort.stderr index 7d096c5d587..5ed7467e84b 100644 --- a/tests/ui/consts/const-eval/unwind-abort.stderr +++ b/tests/ui/consts/const-eval/unwind-abort.stderr @@ -1,11 +1,11 @@ error[E0080]: evaluation of constant value failed - --> $DIR/unwind-abort.rs:5:15 + --> $DIR/unwind-abort.rs:7:15 | LL | const _: () = foo(); | ^^^^^ evaluation panicked: explicit panic | note: inside `foo` - --> $DIR/unwind-abort.rs:2:5 + --> $DIR/unwind-abort.rs:4:5 | LL | panic!() | ^^^^^^^^ the failure occurred here diff --git a/tests/ui/consts/const-eval/validate_uninhabited_zsts.rs b/tests/ui/consts/const-eval/validate_uninhabited_zsts.rs index c4df93b6239..5f1d27b0de0 100644 --- a/tests/ui/consts/const-eval/validate_uninhabited_zsts.rs +++ b/tests/ui/consts/const-eval/validate_uninhabited_zsts.rs @@ -1,5 +1,7 @@ +//@ dont-require-annotations: NOTE + const fn foo() -> ! { - unsafe { std::mem::transmute(()) } //~ inside `foo` + unsafe { std::mem::transmute(()) } //~ NOTE inside `foo` } // Type defined in a submodule, so that it is not "visibly" diff --git a/tests/ui/consts/const-eval/validate_uninhabited_zsts.stderr b/tests/ui/consts/const-eval/validate_uninhabited_zsts.stderr index 29311fdb25a..0407ae5c323 100644 --- a/tests/ui/consts/const-eval/validate_uninhabited_zsts.stderr +++ b/tests/ui/consts/const-eval/validate_uninhabited_zsts.stderr @@ -1,17 +1,17 @@ error[E0080]: evaluation of constant value failed - --> $DIR/validate_uninhabited_zsts.rs:15:33 + --> $DIR/validate_uninhabited_zsts.rs:17:33 | LL | const FOO: [empty::Empty; 3] = [foo(); 3]; | ^^^^^ constructing invalid value: encountered a value of the never type `!` | note: inside `foo` - --> $DIR/validate_uninhabited_zsts.rs:2:14 + --> $DIR/validate_uninhabited_zsts.rs:4:14 | LL | unsafe { std::mem::transmute(()) } | ^^^^^^^^^^^^^^^^^^^^^^^ the failure occurred here error[E0080]: evaluation of constant value failed - --> $DIR/validate_uninhabited_zsts.rs:18:42 + --> $DIR/validate_uninhabited_zsts.rs:20:42 | LL | const BAR: [empty::Empty; 3] = [unsafe { std::mem::transmute(()) }; 3]; | ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered a value of uninhabited type `Void` diff --git a/tests/ui/consts/const-len-underflow-separate-spans.next.stderr b/tests/ui/consts/const-len-underflow-separate-spans.next.stderr index bd2a81f5148..aacd74635e9 100644 --- a/tests/ui/consts/const-len-underflow-separate-spans.next.stderr +++ b/tests/ui/consts/const-len-underflow-separate-spans.next.stderr @@ -5,7 +5,7 @@ LL | const LEN: usize = ONE - TWO; | ^^^^^^^^^ attempt to compute `1_usize - 2_usize`, which would overflow note: erroneous constant encountered - --> $DIR/const-len-underflow-separate-spans.rs:14:17 + --> $DIR/const-len-underflow-separate-spans.rs:15:17 | LL | let a: [i8; LEN] = unimplemented!(); | ^^^ diff --git a/tests/ui/consts/const-len-underflow-separate-spans.old.stderr b/tests/ui/consts/const-len-underflow-separate-spans.old.stderr index bd2a81f5148..aacd74635e9 100644 --- a/tests/ui/consts/const-len-underflow-separate-spans.old.stderr +++ b/tests/ui/consts/const-len-underflow-separate-spans.old.stderr @@ -5,7 +5,7 @@ LL | const LEN: usize = ONE - TWO; | ^^^^^^^^^ attempt to compute `1_usize - 2_usize`, which would overflow note: erroneous constant encountered - --> $DIR/const-len-underflow-separate-spans.rs:14:17 + --> $DIR/const-len-underflow-separate-spans.rs:15:17 | LL | let a: [i8; LEN] = unimplemented!(); | ^^^ diff --git a/tests/ui/consts/const-len-underflow-separate-spans.rs b/tests/ui/consts/const-len-underflow-separate-spans.rs index 42314eed7aa..14eb88b1427 100644 --- a/tests/ui/consts/const-len-underflow-separate-spans.rs +++ b/tests/ui/consts/const-len-underflow-separate-spans.rs @@ -9,8 +9,9 @@ const ONE: usize = 1; const TWO: usize = 2; const LEN: usize = ONE - TWO; //~^ ERROR constant +//~| NOTE attempt to compute `1_usize - 2_usize`, which would overflow fn main() { let a: [i8; LEN] = unimplemented!(); -//~^ constant +//~^ NOTE constant } diff --git a/tests/ui/consts/const-mut-refs/mut_ref_in_final.rs b/tests/ui/consts/const-mut-refs/mut_ref_in_final.rs index 283c1224e01..bc534be6832 100644 --- a/tests/ui/consts/const-mut-refs/mut_ref_in_final.rs +++ b/tests/ui/consts/const-mut-refs/mut_ref_in_final.rs @@ -1,6 +1,7 @@ //@ normalize-stderr: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" //@ normalize-stderr: "( 0x[0-9a-f][0-9a-f] │)? ([0-9a-f][0-9a-f] |__ |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> " HEX_DUMP" //@ normalize-stderr: "HEX_DUMP\s*\n\s*HEX_DUMP" -> "HEX_DUMP" +//@ dont-require-annotations: NOTE use std::cell::UnsafeCell; use std::mem; @@ -25,7 +26,7 @@ const B4: Option<&mut i32> = helper(&mut 42); //~ ERROR temporary value dropped // Not ok, since it points to read-only memory. const IMMUT_MUT_REF: &mut u16 = unsafe { mem::transmute(&13) }; //~^ ERROR undefined behavior to use this value -//~| pointing to read-only memory +//~| NOTE pointing to read-only memory // Ok, because no references to mutable data exist here, since the `{}` moves // its value and then takes a reference to that. diff --git a/tests/ui/consts/const-mut-refs/mut_ref_in_final.stderr b/tests/ui/consts/const-mut-refs/mut_ref_in_final.stderr index 4f50ae32312..1f49f08c401 100644 --- a/tests/ui/consts/const-mut-refs/mut_ref_in_final.stderr +++ b/tests/ui/consts/const-mut-refs/mut_ref_in_final.stderr @@ -1,11 +1,11 @@ error[E0764]: mutable references are not allowed in the final value of constants - --> $DIR/mut_ref_in_final.rs:14:21 + --> $DIR/mut_ref_in_final.rs:15:21 | LL | const B: *mut i32 = &mut 4; | ^^^^^^ error[E0716]: temporary value dropped while borrowed - --> $DIR/mut_ref_in_final.rs:20:40 + --> $DIR/mut_ref_in_final.rs:21:40 | LL | const B3: Option<&mut i32> = Some(&mut 42); | ----------^^- @@ -15,7 +15,7 @@ LL | const B3: Option<&mut i32> = Some(&mut 42); | using this value as a constant requires that borrow lasts for `'static` error[E0716]: temporary value dropped while borrowed - --> $DIR/mut_ref_in_final.rs:23:42 + --> $DIR/mut_ref_in_final.rs:24:42 | LL | const B4: Option<&mut i32> = helper(&mut 42); | ------------^^- @@ -25,7 +25,7 @@ LL | const B4: Option<&mut i32> = helper(&mut 42); | using this value as a constant requires that borrow lasts for `'static` error[E0080]: it is undefined behavior to use this value - --> $DIR/mut_ref_in_final.rs:26:1 + --> $DIR/mut_ref_in_final.rs:27:1 | LL | const IMMUT_MUT_REF: &mut u16 = unsafe { mem::transmute(&13) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered mutable reference or box pointing to read-only memory @@ -36,7 +36,7 @@ LL | const IMMUT_MUT_REF: &mut u16 = unsafe { mem::transmute(&13) }; } error[E0716]: temporary value dropped while borrowed - --> $DIR/mut_ref_in_final.rs:50:65 + --> $DIR/mut_ref_in_final.rs:51:65 | LL | const FOO: NotAMutex<&mut i32> = NotAMutex(UnsafeCell::new(&mut 42)); | -------------------------------^^-- @@ -46,7 +46,7 @@ LL | const FOO: NotAMutex<&mut i32> = NotAMutex(UnsafeCell::new(&mut 42)); | using this value as a constant requires that borrow lasts for `'static` error[E0716]: temporary value dropped while borrowed - --> $DIR/mut_ref_in_final.rs:53:67 + --> $DIR/mut_ref_in_final.rs:54:67 | LL | static FOO2: NotAMutex<&mut i32> = NotAMutex(UnsafeCell::new(&mut 42)); | -------------------------------^^-- @@ -56,7 +56,7 @@ LL | static FOO2: NotAMutex<&mut i32> = NotAMutex(UnsafeCell::new(&mut 42)); | using this value as a static requires that borrow lasts for `'static` error[E0716]: temporary value dropped while borrowed - --> $DIR/mut_ref_in_final.rs:56:71 + --> $DIR/mut_ref_in_final.rs:57:71 | LL | static mut FOO3: NotAMutex<&mut i32> = NotAMutex(UnsafeCell::new(&mut 42)); | -------------------------------^^-- @@ -66,25 +66,25 @@ LL | static mut FOO3: NotAMutex<&mut i32> = NotAMutex(UnsafeCell::new(&mut 42)); | using this value as a static requires that borrow lasts for `'static` error[E0764]: mutable references are not allowed in the final value of statics - --> $DIR/mut_ref_in_final.rs:69:53 + --> $DIR/mut_ref_in_final.rs:70:53 | LL | static RAW_MUT_CAST_S: SyncPtr = SyncPtr { x : &mut 42 as *mut _ as *const _ }; | ^^^^^^^ error[E0764]: mutable references are not allowed in the final value of statics - --> $DIR/mut_ref_in_final.rs:71:54 + --> $DIR/mut_ref_in_final.rs:72:54 | LL | static RAW_MUT_COERCE_S: SyncPtr = SyncPtr { x: &mut 0 }; | ^^^^^^ error[E0764]: mutable references are not allowed in the final value of constants - --> $DIR/mut_ref_in_final.rs:73:52 + --> $DIR/mut_ref_in_final.rs:74:52 | LL | const RAW_MUT_CAST_C: SyncPtr = SyncPtr { x : &mut 42 as *mut _ as *const _ }; | ^^^^^^^ error[E0764]: mutable references are not allowed in the final value of constants - --> $DIR/mut_ref_in_final.rs:75:53 + --> $DIR/mut_ref_in_final.rs:76:53 | LL | const RAW_MUT_COERCE_C: SyncPtr = SyncPtr { x: &mut 0 }; | ^^^^^^ diff --git a/tests/ui/consts/const-mut-refs/mut_ref_in_final_dynamic_check.rs b/tests/ui/consts/const-mut-refs/mut_ref_in_final_dynamic_check.rs index ac903fca20a..a58c4437e15 100644 --- a/tests/ui/consts/const-mut-refs/mut_ref_in_final_dynamic_check.rs +++ b/tests/ui/consts/const-mut-refs/mut_ref_in_final_dynamic_check.rs @@ -1,6 +1,7 @@ //@ normalize-stderr: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" //@ normalize-stderr: "( 0x[0-9a-f][0-9a-f] │)? ([0-9a-f][0-9a-f] |__ |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> " HEX_DUMP" //@ normalize-stderr: "HEX_DUMP\s*\n\s*HEX_DUMP" -> "HEX_DUMP" +//@ dont-require-annotations: NOTE use std::sync::Mutex; @@ -16,16 +17,16 @@ const fn helper() -> Option<&'static mut i32> { unsafe { Some(&mut *std::ptr::addr_of_mut!(BUFFER)) } } const MUT: Option<&mut i32> = helper(); //~ ERROR it is undefined behavior to use this value -//~^ encountered reference to mutable +//~^ NOTE encountered reference to mutable const fn helper_int2ptr() -> Option<&'static mut i32> { unsafe { // Undefined behaviour (integer as pointer), who doesn't love tests like this. Some(&mut *(42 as *mut i32)) } } const INT2PTR: Option<&mut i32> = helper_int2ptr(); //~ ERROR it is undefined behavior to use this value -//~^ encountered a dangling reference +//~^ NOTE encountered a dangling reference static INT2PTR_STATIC: Option<&mut i32> = helper_int2ptr(); //~ ERROR it is undefined behavior to use this value -//~^ encountered a dangling reference +//~^ NOTE encountered a dangling reference const fn helper_dangling() -> Option<&'static mut i32> { unsafe { // Undefined behaviour (dangling pointer), who doesn't love tests like this. diff --git a/tests/ui/consts/const-mut-refs/mut_ref_in_final_dynamic_check.stderr b/tests/ui/consts/const-mut-refs/mut_ref_in_final_dynamic_check.stderr index aebac56f8c5..4ea6fa62475 100644 --- a/tests/ui/consts/const-mut-refs/mut_ref_in_final_dynamic_check.stderr +++ b/tests/ui/consts/const-mut-refs/mut_ref_in_final_dynamic_check.stderr @@ -1,5 +1,5 @@ error[E0080]: it is undefined behavior to use this value - --> $DIR/mut_ref_in_final_dynamic_check.rs:18:1 + --> $DIR/mut_ref_in_final_dynamic_check.rs:19:1 | LL | const MUT: Option<&mut i32> = helper(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at ..0: encountered reference to mutable memory in `const` @@ -10,7 +10,7 @@ LL | const MUT: Option<&mut i32> = helper(); } error[E0080]: it is undefined behavior to use this value - --> $DIR/mut_ref_in_final_dynamic_check.rs:25:1 + --> $DIR/mut_ref_in_final_dynamic_check.rs:26:1 | LL | const INT2PTR: Option<&mut i32> = helper_int2ptr(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at ..0: encountered a dangling reference (0x2a[noalloc] has no provenance) @@ -21,7 +21,7 @@ LL | const INT2PTR: Option<&mut i32> = helper_int2ptr(); } error[E0080]: it is undefined behavior to use this value - --> $DIR/mut_ref_in_final_dynamic_check.rs:27:1 + --> $DIR/mut_ref_in_final_dynamic_check.rs:28:1 | LL | static INT2PTR_STATIC: Option<&mut i32> = helper_int2ptr(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at ..0: encountered a dangling reference (0x2a[noalloc] has no provenance) @@ -32,7 +32,7 @@ LL | static INT2PTR_STATIC: Option<&mut i32> = helper_int2ptr(); } error[E0080]: it is undefined behavior to use this value - --> $DIR/mut_ref_in_final_dynamic_check.rs:34:1 + --> $DIR/mut_ref_in_final_dynamic_check.rs:35:1 | LL | const DANGLING: Option<&mut i32> = helper_dangling(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at ..0: encountered a dangling reference (use-after-free) @@ -43,7 +43,7 @@ LL | const DANGLING: Option<&mut i32> = helper_dangling(); } error[E0080]: it is undefined behavior to use this value - --> $DIR/mut_ref_in_final_dynamic_check.rs:35:1 + --> $DIR/mut_ref_in_final_dynamic_check.rs:36:1 | LL | static DANGLING_STATIC: Option<&mut i32> = helper_dangling(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at ..0: encountered a dangling reference (use-after-free) diff --git a/tests/ui/consts/const-pattern-irrefutable.rs b/tests/ui/consts/const-pattern-irrefutable.rs index 759d2e8b2ed..e131fd27d53 100644 --- a/tests/ui/consts/const-pattern-irrefutable.rs +++ b/tests/ui/consts/const-pattern-irrefutable.rs @@ -1,15 +1,17 @@ +//@ dont-require-annotations: NOTE + mod foo { pub const b: u8 = 2; - //~^ missing patterns are not covered because `b` is interpreted as a constant pattern, not a new variable + //~^ NOTE missing patterns are not covered because `b` is interpreted as a constant pattern, not a new variable pub const d: (u8, u8) = (2, 1); - //~^ missing patterns are not covered because `d` is interpreted as a constant pattern, not a new variable + //~^ NOTE missing patterns are not covered because `d` is interpreted as a constant pattern, not a new variable } use foo::b as c; use foo::d; const a: u8 = 2; -//~^ missing patterns are not covered because `a` is interpreted as a constant pattern, not a new variable +//~^ NOTE missing patterns are not covered because `a` is interpreted as a constant pattern, not a new variable #[derive(PartialEq)] struct S { @@ -23,19 +25,19 @@ const e: S = S { fn main() { let a = 4; //~^ ERROR refutable pattern in local binding - //~| patterns `0_u8..=1_u8` and `3_u8..=u8::MAX` not covered + //~| NOTE patterns `0_u8..=1_u8` and `3_u8..=u8::MAX` not covered //~| HELP introduce a variable instead let c = 4; //~^ ERROR refutable pattern in local binding - //~| patterns `0_u8..=1_u8` and `3_u8..=u8::MAX` not covered + //~| NOTE patterns `0_u8..=1_u8` and `3_u8..=u8::MAX` not covered //~| HELP introduce a variable instead let d = (4, 4); //~^ ERROR refutable pattern in local binding - //~| patterns `(0_u8..=1_u8, _)` and `(3_u8..=u8::MAX, _)` not covered + //~| NOTE patterns `(0_u8..=1_u8, _)` and `(3_u8..=u8::MAX, _)` not covered //~| HELP introduce a variable instead let e = S { //~^ ERROR refutable pattern in local binding - //~| pattern `S { foo: 1_u8..=u8::MAX }` not covered + //~| NOTE pattern `S { foo: 1_u8..=u8::MAX }` not covered //~| HELP introduce a variable instead foo: 1, }; diff --git a/tests/ui/consts/const-pattern-irrefutable.stderr b/tests/ui/consts/const-pattern-irrefutable.stderr index 06bd01bff79..f52ebc31333 100644 --- a/tests/ui/consts/const-pattern-irrefutable.stderr +++ b/tests/ui/consts/const-pattern-irrefutable.stderr @@ -1,5 +1,5 @@ error[E0005]: refutable pattern in local binding - --> $DIR/const-pattern-irrefutable.rs:24:9 + --> $DIR/const-pattern-irrefutable.rs:26:9 | LL | const a: u8 = 2; | ----------- missing patterns are not covered because `a` is interpreted as a constant pattern, not a new variable @@ -16,7 +16,7 @@ LL | let a_var = 4; | ++++ error[E0005]: refutable pattern in local binding - --> $DIR/const-pattern-irrefutable.rs:28:9 + --> $DIR/const-pattern-irrefutable.rs:30:9 | LL | pub const b: u8 = 2; | --------------- missing patterns are not covered because `b` is interpreted as a constant pattern, not a new variable @@ -34,7 +34,7 @@ LL + let b_var = 4; | error[E0005]: refutable pattern in local binding - --> $DIR/const-pattern-irrefutable.rs:32:9 + --> $DIR/const-pattern-irrefutable.rs:34:9 | LL | pub const d: (u8, u8) = (2, 1); | --------------------- missing patterns are not covered because `d` is interpreted as a constant pattern, not a new variable @@ -51,7 +51,7 @@ LL | let d_var = (4, 4); | ++++ error[E0005]: refutable pattern in local binding - --> $DIR/const-pattern-irrefutable.rs:36:9 + --> $DIR/const-pattern-irrefutable.rs:38:9 | LL | const e: S = S { | ---------- missing patterns are not covered because `e` is interpreted as a constant pattern, not a new variable @@ -62,7 +62,7 @@ LL | let e = S { = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html note: `S` defined here - --> $DIR/const-pattern-irrefutable.rs:15:8 + --> $DIR/const-pattern-irrefutable.rs:17:8 | LL | struct S { | ^ diff --git a/tests/ui/consts/const-tup-index-span.rs b/tests/ui/consts/const-tup-index-span.rs index e77d392e694..4cb7143b435 100644 --- a/tests/ui/consts/const-tup-index-span.rs +++ b/tests/ui/consts/const-tup-index-span.rs @@ -2,7 +2,8 @@ const TUP: (usize,) = 5usize << 64; //~^ ERROR mismatched types -//~| expected `(usize,)`, found `usize` +//~| NOTE expected `(usize,)`, found `usize` +//~| NOTE expected tuple `(usize,)` const ARR: [i32; TUP.0] = []; fn main() { diff --git a/tests/ui/consts/const_refs_to_static_fail.rs b/tests/ui/consts/const_refs_to_static_fail.rs index 596ed50af38..e1f2262ba29 100644 --- a/tests/ui/consts/const_refs_to_static_fail.rs +++ b/tests/ui/consts/const_refs_to_static_fail.rs @@ -1,5 +1,6 @@ //@ normalize-stderr: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" //@ normalize-stderr: "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" +//@ dont-require-annotations: NOTE #![feature(sync_unsafe_cell)] @@ -9,14 +10,14 @@ static S: SyncUnsafeCell = SyncUnsafeCell::new(0); static mut S_MUT: i32 = 0; const C1: &SyncUnsafeCell = &S; //~ERROR undefined behavior -//~| encountered reference to mutable memory +//~| NOTE encountered reference to mutable memory const C1_READ: () = unsafe { assert!(*C1.get() == 0); }; const C2: *const i32 = unsafe { std::ptr::addr_of!(S_MUT) }; const C2_READ: () = unsafe { assert!(*C2 == 0); //~ERROR evaluation of constant value failed - //~^ constant accesses mutable global memory + //~^ NOTE constant accesses mutable global memory }; fn main() { diff --git a/tests/ui/consts/const_refs_to_static_fail.stderr b/tests/ui/consts/const_refs_to_static_fail.stderr index 297561dbcf1..245806da5c6 100644 --- a/tests/ui/consts/const_refs_to_static_fail.stderr +++ b/tests/ui/consts/const_refs_to_static_fail.stderr @@ -1,5 +1,5 @@ error[E0080]: it is undefined behavior to use this value - --> $DIR/const_refs_to_static_fail.rs:11:1 + --> $DIR/const_refs_to_static_fail.rs:12:1 | LL | const C1: &SyncUnsafeCell = &S; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered reference to mutable memory in `const` @@ -10,13 +10,13 @@ LL | const C1: &SyncUnsafeCell = &S; } note: erroneous constant encountered - --> $DIR/const_refs_to_static_fail.rs:14:14 + --> $DIR/const_refs_to_static_fail.rs:15:14 | LL | assert!(*C1.get() == 0); | ^^ error[E0080]: evaluation of constant value failed - --> $DIR/const_refs_to_static_fail.rs:18:13 + --> $DIR/const_refs_to_static_fail.rs:19:13 | LL | assert!(*C2 == 0); | ^^^ constant accesses mutable global memory diff --git a/tests/ui/consts/const_refs_to_static_fail_invalid.rs b/tests/ui/consts/const_refs_to_static_fail_invalid.rs index 3383a208345..f6ccfbfc52f 100644 --- a/tests/ui/consts/const_refs_to_static_fail_invalid.rs +++ b/tests/ui/consts/const_refs_to_static_fail_invalid.rs @@ -1,5 +1,7 @@ //@ normalize-stderr: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" //@ normalize-stderr: "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" +//@ dont-require-annotations: NOTE + #![allow(static_mut_refs)] fn invalid() { @@ -7,7 +9,7 @@ fn invalid() { const C: &bool = unsafe { std::mem::transmute(&S) }; //~^ERROR: undefined behavior - //~| expected a boolean + //~| NOTE expected a boolean // This must be rejected here (or earlier), since it's not a valid `&bool`. match &true { @@ -23,7 +25,7 @@ fn extern_() { const C: &i8 = unsafe { &S }; //~^ERROR: undefined behavior - //~| `extern` static + //~| NOTE `extern` static // This must be rejected here (or earlier), since the pattern cannot be read. match &0 { @@ -37,7 +39,7 @@ fn mutable() { const C: &i32 = unsafe { &S_MUT }; //~^ERROR: undefined behavior - //~| encountered reference to mutable memory + //~| NOTE encountered reference to mutable memory // This *must not build*, the constant we are matching against // could change its value! diff --git a/tests/ui/consts/const_refs_to_static_fail_invalid.stderr b/tests/ui/consts/const_refs_to_static_fail_invalid.stderr index c9d5cb60bf7..e0086e07af7 100644 --- a/tests/ui/consts/const_refs_to_static_fail_invalid.stderr +++ b/tests/ui/consts/const_refs_to_static_fail_invalid.stderr @@ -1,5 +1,5 @@ error[E0080]: it is undefined behavior to use this value - --> $DIR/const_refs_to_static_fail_invalid.rs:8:5 + --> $DIR/const_refs_to_static_fail_invalid.rs:10:5 | LL | const C: &bool = unsafe { std::mem::transmute(&S) }; | ^^^^^^^^^^^^^^ constructing invalid value at .: encountered 0x0a, but expected a boolean @@ -10,7 +10,7 @@ LL | const C: &bool = unsafe { std::mem::transmute(&S) }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/const_refs_to_static_fail_invalid.rs:24:5 + --> $DIR/const_refs_to_static_fail_invalid.rs:26:5 | LL | const C: &i8 = unsafe { &S }; | ^^^^^^^^^^^^ constructing invalid value: encountered reference to `extern` static in `const` @@ -21,7 +21,7 @@ LL | const C: &i8 = unsafe { &S }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/const_refs_to_static_fail_invalid.rs:38:5 + --> $DIR/const_refs_to_static_fail_invalid.rs:40:5 | LL | const C: &i32 = unsafe { &S_MUT }; | ^^^^^^^^^^^^^ constructing invalid value: encountered reference to mutable memory in `const` diff --git a/tests/ui/consts/issue-17718-const-bad-values.rs b/tests/ui/consts/issue-17718-const-bad-values.rs index c4de7b61f07..286972365d5 100644 --- a/tests/ui/consts/issue-17718-const-bad-values.rs +++ b/tests/ui/consts/issue-17718-const-bad-values.rs @@ -1,5 +1,6 @@ //@ normalize-stderr: "\(size: \d+, align: \d+\)" -> "(size: $$PTR, align: $$PTR)" //@ normalize-stderr: "([0-9a-f][0-9a-f] |╾─*A(LLOC)?[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" +//@ dont-require-annotations: NOTE #![allow(static_mut_refs)] @@ -9,6 +10,6 @@ const C1: &'static mut [usize] = &mut []; static mut S: i32 = 3; const C2: &'static mut i32 = unsafe { &mut S }; //~^ ERROR: it is undefined behavior to use this value -//~| reference to mutable memory +//~| NOTE reference to mutable memory fn main() {} diff --git a/tests/ui/consts/issue-17718-const-bad-values.stderr b/tests/ui/consts/issue-17718-const-bad-values.stderr index 364fa7be5aa..102491e90ba 100644 --- a/tests/ui/consts/issue-17718-const-bad-values.stderr +++ b/tests/ui/consts/issue-17718-const-bad-values.stderr @@ -1,11 +1,11 @@ error[E0764]: mutable references are not allowed in the final value of constants - --> $DIR/issue-17718-const-bad-values.rs:6:34 + --> $DIR/issue-17718-const-bad-values.rs:7:34 | LL | const C1: &'static mut [usize] = &mut []; | ^^^^^^^ error[E0080]: it is undefined behavior to use this value - --> $DIR/issue-17718-const-bad-values.rs:10:1 + --> $DIR/issue-17718-const-bad-values.rs:11:1 | LL | const C2: &'static mut i32 = unsafe { &mut S }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered reference to mutable memory in `const` diff --git a/tests/ui/consts/issue-39974.rs b/tests/ui/consts/issue-39974.rs index 9cb180014b8..adc65d9be0d 100644 --- a/tests/ui/consts/issue-39974.rs +++ b/tests/ui/consts/issue-39974.rs @@ -1,10 +1,11 @@ const LENGTH: f64 = 2; //~^ ERROR mismatched types +//~| NOTE expected `f64`, found integer struct Thing { f: [[f64; 2]; LENGTH], //~^ ERROR mismatched types - //~| expected `usize`, found `f64` + //~| NOTE expected `usize`, found `f64` } fn main() { diff --git a/tests/ui/consts/issue-39974.stderr b/tests/ui/consts/issue-39974.stderr index d03f709b0ea..1c15debb119 100644 --- a/tests/ui/consts/issue-39974.stderr +++ b/tests/ui/consts/issue-39974.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/issue-39974.rs:5:19 + --> $DIR/issue-39974.rs:6:19 | LL | f: [[f64; 2]; LENGTH], | ^^^^^^ expected `usize`, found `f64` diff --git a/tests/ui/consts/miri_unleashed/assoc_const_2.rs b/tests/ui/consts/miri_unleashed/assoc_const_2.rs index 5490c096391..1d8ed2065a4 100644 --- a/tests/ui/consts/miri_unleashed/assoc_const_2.rs +++ b/tests/ui/consts/miri_unleashed/assoc_const_2.rs @@ -1,4 +1,5 @@ //@ build-fail +//@ dont-require-annotations: NOTE // a test demonstrating that const qualification cannot prevent monomorphization time errors @@ -24,5 +25,5 @@ impl Bar for String {} fn main() { let x = <() as Bar<()>>::F; // this test only causes errors due to the line below, so post-monomorphization - let y = >::F; //~ constant + let y = >::F; //~ NOTE constant } diff --git a/tests/ui/consts/miri_unleashed/assoc_const_2.stderr b/tests/ui/consts/miri_unleashed/assoc_const_2.stderr index e923d95b755..5503f8e56f0 100644 --- a/tests/ui/consts/miri_unleashed/assoc_const_2.stderr +++ b/tests/ui/consts/miri_unleashed/assoc_const_2.stderr @@ -1,17 +1,17 @@ error[E0080]: evaluation of `>::F` failed - --> $DIR/assoc_const_2.rs:10:20 + --> $DIR/assoc_const_2.rs:11:20 | LL | const F: u32 = 100 / U::X; | ^^^^^^^^^^ attempt to divide `100_u32` by zero note: erroneous constant encountered - --> $DIR/assoc_const_2.rs:27:13 + --> $DIR/assoc_const_2.rs:28:13 | LL | let y = >::F; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ note: erroneous constant encountered - --> $DIR/assoc_const_2.rs:27:13 + --> $DIR/assoc_const_2.rs:28:13 | LL | let y = >::F; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/consts/miri_unleashed/const_refers_to_static.rs b/tests/ui/consts/miri_unleashed/const_refers_to_static.rs index fdccc17ab49..c66aaec8c56 100644 --- a/tests/ui/consts/miri_unleashed/const_refers_to_static.rs +++ b/tests/ui/consts/miri_unleashed/const_refers_to_static.rs @@ -1,6 +1,7 @@ //@ compile-flags: -Zunleash-the-miri-inside-of-you //@ normalize-stderr: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" //@ normalize-stderr: "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" +//@ dont-require-annotations: NOTE use std::sync::atomic::AtomicUsize; use std::sync::atomic::Ordering; @@ -20,7 +21,7 @@ const READ_MUT: u32 = unsafe { MUTABLE }; //~ERROR evaluation of constant value // Evaluating this does not read anything mutable, but validation does, so this should error. const REF_INTERIOR_MUT: &usize = { //~ ERROR undefined behavior - //~| encountered reference to mutable memory + //~| NOTE encountered reference to mutable memory static FOO: AtomicUsize = AtomicUsize::new(0); unsafe { &*(&FOO as *const _ as *const usize) } }; diff --git a/tests/ui/consts/miri_unleashed/const_refers_to_static.stderr b/tests/ui/consts/miri_unleashed/const_refers_to_static.stderr index f8e0606fbd7..f647107094d 100644 --- a/tests/ui/consts/miri_unleashed/const_refers_to_static.stderr +++ b/tests/ui/consts/miri_unleashed/const_refers_to_static.stderr @@ -1,23 +1,23 @@ error[E0080]: evaluation of constant value failed - --> $DIR/const_refers_to_static.rs:10:5 + --> $DIR/const_refers_to_static.rs:11:5 | LL | FOO.fetch_add(1, Ordering::Relaxed) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ calling non-const function `AtomicUsize::fetch_add` error[E0080]: evaluation of constant value failed - --> $DIR/const_refers_to_static.rs:15:14 + --> $DIR/const_refers_to_static.rs:16:14 | LL | unsafe { *(&FOO as *const _ as *const usize) } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constant accesses mutable global memory error[E0080]: evaluation of constant value failed - --> $DIR/const_refers_to_static.rs:19:32 + --> $DIR/const_refers_to_static.rs:20:32 | LL | const READ_MUT: u32 = unsafe { MUTABLE }; | ^^^^^^^ constant accesses mutable global memory error[E0080]: it is undefined behavior to use this value - --> $DIR/const_refers_to_static.rs:22:1 + --> $DIR/const_refers_to_static.rs:23:1 | LL | const REF_INTERIOR_MUT: &usize = { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered reference to mutable memory in `const` @@ -30,7 +30,7 @@ LL | const REF_INTERIOR_MUT: &usize = { warning: skipping const checks | help: skipping check that does not even have a feature gate - --> $DIR/const_refers_to_static.rs:10:5 + --> $DIR/const_refers_to_static.rs:11:5 | LL | FOO.fetch_add(1, Ordering::Relaxed) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.rs b/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.rs index b33ebfb06be..86d23d44bff 100644 --- a/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.rs +++ b/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.rs @@ -2,6 +2,8 @@ //@ aux-build:static_cross_crate.rs //@ normalize-stderr: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" //@ normalize-stderr: "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" +//@ dont-require-annotations: NOTE + #![feature(half_open_range_patterns_in_slices)] #![allow(static_mut_refs)] @@ -10,25 +12,25 @@ extern crate static_cross_crate; // Sneaky: reference to a mutable static. // Allowing this would be a disaster for pattern matching, we could violate exhaustiveness checking! const SLICE_MUT: &[u8; 1] = { //~ ERROR undefined behavior - //~| encountered reference to mutable memory + //~| NOTE encountered reference to mutable memory unsafe { &static_cross_crate::ZERO } }; const U8_MUT: &u8 = { //~ ERROR undefined behavior - //~| encountered reference to mutable memory + //~| NOTE encountered reference to mutable memory unsafe { &static_cross_crate::ZERO[0] } }; // Also test indirection that reads from other static. const U8_MUT2: &u8 = { //~ ERROR undefined behavior - //~| encountered reference to mutable memory + //~| NOTE encountered reference to mutable memory unsafe { &(*static_cross_crate::ZERO_REF)[0] } }; const U8_MUT3: &u8 = { unsafe { match static_cross_crate::OPT_ZERO { //~^ ERROR evaluation of constant value failed - //~| constant accesses mutable global memory + //~| NOTE constant accesses mutable global memory Some(ref u) => u, None => panic!(), } diff --git a/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.stderr b/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.stderr index 8f8271cce38..4e5052ed470 100644 --- a/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.stderr +++ b/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.stderr @@ -1,5 +1,5 @@ error[E0080]: it is undefined behavior to use this value - --> $DIR/const_refers_to_static_cross_crate.rs:12:1 + --> $DIR/const_refers_to_static_cross_crate.rs:14:1 | LL | const SLICE_MUT: &[u8; 1] = { | ^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered reference to mutable memory in `const` @@ -10,7 +10,7 @@ LL | const SLICE_MUT: &[u8; 1] = { } error[E0080]: it is undefined behavior to use this value - --> $DIR/const_refers_to_static_cross_crate.rs:17:1 + --> $DIR/const_refers_to_static_cross_crate.rs:19:1 | LL | const U8_MUT: &u8 = { | ^^^^^^^^^^^^^^^^^ constructing invalid value: encountered reference to mutable memory in `const` @@ -21,7 +21,7 @@ LL | const U8_MUT: &u8 = { } error[E0080]: it is undefined behavior to use this value - --> $DIR/const_refers_to_static_cross_crate.rs:23:1 + --> $DIR/const_refers_to_static_cross_crate.rs:25:1 | LL | const U8_MUT2: &u8 = { | ^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered reference to mutable memory in `const` @@ -32,7 +32,7 @@ LL | const U8_MUT2: &u8 = { } error[E0080]: evaluation of constant value failed - --> $DIR/const_refers_to_static_cross_crate.rs:29:15 + --> $DIR/const_refers_to_static_cross_crate.rs:31:15 | LL | match static_cross_crate::OPT_ZERO { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constant accesses mutable global memory diff --git a/tests/ui/consts/miri_unleashed/mutable_references.rs b/tests/ui/consts/miri_unleashed/mutable_references.rs index e7fc5699236..02a35487e8a 100644 --- a/tests/ui/consts/miri_unleashed/mutable_references.rs +++ b/tests/ui/consts/miri_unleashed/mutable_references.rs @@ -1,6 +1,7 @@ //@ compile-flags: -Zunleash-the-miri-inside-of-you //@ normalize-stderr: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" //@ normalize-stderr: "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" +//@ dont-require-annotations: NOTE #![allow(static_mut_refs)] use std::cell::UnsafeCell; @@ -11,10 +12,10 @@ use std::sync::atomic::*; // This requires walking nested statics. static FOO: &&mut u32 = &&mut 42; //~^ ERROR it is undefined behavior to use this value -//~| pointing to read-only memory +//~| NOTE pointing to read-only memory static OH_YES: &mut i32 = &mut 42; //~^ ERROR it is undefined behavior to use this value -//~| pointing to read-only memory +//~| NOTE pointing to read-only memory static BAR: &mut () = &mut (); //~^ ERROR encountered mutable pointer in final value of static @@ -25,11 +26,11 @@ static BOO: &mut Foo<()> = &mut Foo(()); const BLUNT: &mut i32 = &mut 42; //~^ ERROR: it is undefined behavior to use this value -//~| pointing to read-only memory +//~| NOTE pointing to read-only memory const SUBTLE: &mut i32 = unsafe { //~^ ERROR: it is undefined behavior to use this value - //~| constructing invalid value: encountered reference to mutable memory in `const` + //~| NOTE constructing invalid value: encountered reference to mutable memory in `const` static mut STATIC: i32 = 0; &mut STATIC }; @@ -42,13 +43,13 @@ struct Meh { unsafe impl Sync for Meh {} static MEH: Meh = Meh { x: &UnsafeCell::new(42) }; //~^ ERROR it is undefined behavior to use this value -//~| `UnsafeCell` in read-only memory +//~| NOTE `UnsafeCell` in read-only memory // Same with a const: // the following will never be ok! no interior mut behind consts, because // all allocs interned here will be marked immutable. const MUH: Meh = Meh { //~^ ERROR it is undefined behavior to use this value - //~| `UnsafeCell` in read-only memory + //~| NOTE `UnsafeCell` in read-only memory x: &UnsafeCell::new(42), }; @@ -60,30 +61,30 @@ unsafe impl Sync for Synced {} // Make sure we also catch this behind a type-erased `dyn Trait` reference. const SNEAKY: &dyn Sync = &Synced { x: UnsafeCell::new(42) }; //~^ ERROR: it is undefined behavior to use this value -//~| `UnsafeCell` in read-only memory +//~| NOTE `UnsafeCell` in read-only memory // # Check for mutable references to read-only memory static READONLY: i32 = 0; static mut MUT_TO_READONLY: &mut i32 = unsafe { &mut *(&READONLY as *const _ as *mut _) }; //~^ ERROR: it is undefined behavior to use this value -//~| pointing to read-only memory +//~| NOTE pointing to read-only memory // # Check for consts pointing to mutable memory static mut MUTABLE: i32 = 42; -const POINTS_TO_MUTABLE: &i32 = unsafe { &MUTABLE }; //~ERROR: undefined behavior -//~| encountered reference to mutable memory +const POINTS_TO_MUTABLE: &i32 = unsafe { &MUTABLE }; //~ ERROR undefined behavior +//~| NOTE encountered reference to mutable memory static mut MUTABLE_REF: &mut i32 = &mut 42; const POINTS_TO_MUTABLE2: &i32 = unsafe { &*MUTABLE_REF }; -//~^ ERROR: evaluation of constant value failed -//~| accesses mutable global memory +//~^ ERROR evaluation of constant value failed +//~| NOTE accesses mutable global memory const POINTS_TO_MUTABLE_INNER: *const i32 = &mut 42 as *mut _ as *const _; -//~^ ERROR: mutable pointer in final value +//~^ ERROR mutable pointer in final value const POINTS_TO_MUTABLE_INNER2: *const i32 = &mut 42 as *const _; -//~^ ERROR: mutable pointer in final value +//~^ ERROR mutable pointer in final value // This does *not* error since it uses a shared reference, and we have to ignore // those. See . diff --git a/tests/ui/consts/miri_unleashed/mutable_references.stderr b/tests/ui/consts/miri_unleashed/mutable_references.stderr index ce5cedac8bc..3049be80adc 100644 --- a/tests/ui/consts/miri_unleashed/mutable_references.stderr +++ b/tests/ui/consts/miri_unleashed/mutable_references.stderr @@ -1,5 +1,5 @@ error[E0080]: it is undefined behavior to use this value - --> $DIR/mutable_references.rs:12:1 + --> $DIR/mutable_references.rs:13:1 | LL | static FOO: &&mut u32 = &&mut 42; | ^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .: encountered mutable reference or box pointing to read-only memory @@ -10,7 +10,7 @@ LL | static FOO: &&mut u32 = &&mut 42; } error[E0080]: it is undefined behavior to use this value - --> $DIR/mutable_references.rs:15:1 + --> $DIR/mutable_references.rs:16:1 | LL | static OH_YES: &mut i32 = &mut 42; | ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered mutable reference or box pointing to read-only memory @@ -21,19 +21,19 @@ LL | static OH_YES: &mut i32 = &mut 42; } error: encountered mutable pointer in final value of static - --> $DIR/mutable_references.rs:18:1 + --> $DIR/mutable_references.rs:19:1 | LL | static BAR: &mut () = &mut (); | ^^^^^^^^^^^^^^^^^^^ error: encountered mutable pointer in final value of static - --> $DIR/mutable_references.rs:23:1 + --> $DIR/mutable_references.rs:24:1 | LL | static BOO: &mut Foo<()> = &mut Foo(()); | ^^^^^^^^^^^^^^^^^^^^^^^^ error[E0080]: it is undefined behavior to use this value - --> $DIR/mutable_references.rs:26:1 + --> $DIR/mutable_references.rs:27:1 | LL | const BLUNT: &mut i32 = &mut 42; | ^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered mutable reference or box pointing to read-only memory @@ -44,7 +44,7 @@ LL | const BLUNT: &mut i32 = &mut 42; } error[E0080]: it is undefined behavior to use this value - --> $DIR/mutable_references.rs:30:1 + --> $DIR/mutable_references.rs:31:1 | LL | const SUBTLE: &mut i32 = unsafe { | ^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered reference to mutable memory in `const` @@ -55,7 +55,7 @@ LL | const SUBTLE: &mut i32 = unsafe { } error[E0080]: it is undefined behavior to use this value - --> $DIR/mutable_references.rs:43:1 + --> $DIR/mutable_references.rs:44:1 | LL | static MEH: Meh = Meh { x: &UnsafeCell::new(42) }; | ^^^^^^^^^^^^^^^ constructing invalid value at .x.: encountered `UnsafeCell` in read-only memory @@ -66,7 +66,7 @@ LL | static MEH: Meh = Meh { x: &UnsafeCell::new(42) }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/mutable_references.rs:49:1 + --> $DIR/mutable_references.rs:50:1 | LL | const MUH: Meh = Meh { | ^^^^^^^^^^^^^^ constructing invalid value at .x.: encountered `UnsafeCell` in read-only memory @@ -77,7 +77,7 @@ LL | const MUH: Meh = Meh { } error[E0080]: it is undefined behavior to use this value - --> $DIR/mutable_references.rs:61:1 + --> $DIR/mutable_references.rs:62:1 | LL | const SNEAKY: &dyn Sync = &Synced { x: UnsafeCell::new(42) }; | ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at ...x: encountered `UnsafeCell` in read-only memory @@ -88,7 +88,7 @@ LL | const SNEAKY: &dyn Sync = &Synced { x: UnsafeCell::new(42) }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/mutable_references.rs:68:1 + --> $DIR/mutable_references.rs:69:1 | LL | static mut MUT_TO_READONLY: &mut i32 = unsafe { &mut *(&READONLY as *const _ as *mut _) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered mutable reference or box pointing to read-only memory @@ -99,7 +99,7 @@ LL | static mut MUT_TO_READONLY: &mut i32 = unsafe { &mut *(&READONLY as *const } error[E0080]: it is undefined behavior to use this value - --> $DIR/mutable_references.rs:75:1 + --> $DIR/mutable_references.rs:76:1 | LL | const POINTS_TO_MUTABLE: &i32 = unsafe { &MUTABLE }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered reference to mutable memory in `const` @@ -110,37 +110,37 @@ LL | const POINTS_TO_MUTABLE: &i32 = unsafe { &MUTABLE }; } error[E0080]: evaluation of constant value failed - --> $DIR/mutable_references.rs:78:43 + --> $DIR/mutable_references.rs:79:43 | LL | const POINTS_TO_MUTABLE2: &i32 = unsafe { &*MUTABLE_REF }; | ^^^^^^^^^^^^^ constant accesses mutable global memory error: encountered mutable pointer in final value of constant - --> $DIR/mutable_references.rs:82:1 + --> $DIR/mutable_references.rs:83:1 | LL | const POINTS_TO_MUTABLE_INNER: *const i32 = &mut 42 as *mut _ as *const _; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: encountered mutable pointer in final value of constant - --> $DIR/mutable_references.rs:85:1 + --> $DIR/mutable_references.rs:86:1 | LL | const POINTS_TO_MUTABLE_INNER2: *const i32 = &mut 42 as *const _; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: encountered mutable pointer in final value of constant - --> $DIR/mutable_references.rs:105:1 + --> $DIR/mutable_references.rs:106:1 | LL | const RAW_MUT_CAST: SyncPtr = SyncPtr { x: &mut 42 as *mut _ as *const _ }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: encountered mutable pointer in final value of constant - --> $DIR/mutable_references.rs:108:1 + --> $DIR/mutable_references.rs:109:1 | LL | const RAW_MUT_COERCE: SyncPtr = SyncPtr { x: &mut 0 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0594]: cannot assign to `*OH_YES`, as `OH_YES` is an immutable static item - --> $DIR/mutable_references.rs:115:5 + --> $DIR/mutable_references.rs:116:5 | LL | *OH_YES = 99; | ^^^^^^^^^^^^ cannot assign @@ -148,72 +148,72 @@ LL | *OH_YES = 99; warning: skipping const checks | help: skipping check that does not even have a feature gate - --> $DIR/mutable_references.rs:12:26 + --> $DIR/mutable_references.rs:13:26 | LL | static FOO: &&mut u32 = &&mut 42; | ^^^^^^^ help: skipping check that does not even have a feature gate - --> $DIR/mutable_references.rs:15:27 + --> $DIR/mutable_references.rs:16:27 | LL | static OH_YES: &mut i32 = &mut 42; | ^^^^^^^ help: skipping check that does not even have a feature gate - --> $DIR/mutable_references.rs:18:23 + --> $DIR/mutable_references.rs:19:23 | LL | static BAR: &mut () = &mut (); | ^^^^^^^ help: skipping check that does not even have a feature gate - --> $DIR/mutable_references.rs:23:28 + --> $DIR/mutable_references.rs:24:28 | LL | static BOO: &mut Foo<()> = &mut Foo(()); | ^^^^^^^^^^^^ help: skipping check that does not even have a feature gate - --> $DIR/mutable_references.rs:26:25 + --> $DIR/mutable_references.rs:27:25 | LL | const BLUNT: &mut i32 = &mut 42; | ^^^^^^^ help: skipping check that does not even have a feature gate - --> $DIR/mutable_references.rs:43:28 + --> $DIR/mutable_references.rs:44:28 | LL | static MEH: Meh = Meh { x: &UnsafeCell::new(42) }; | ^^^^^^^^^^^^^^^^^^^^ help: skipping check that does not even have a feature gate - --> $DIR/mutable_references.rs:52:8 + --> $DIR/mutable_references.rs:53:8 | LL | x: &UnsafeCell::new(42), | ^^^^^^^^^^^^^^^^^^^^ help: skipping check that does not even have a feature gate - --> $DIR/mutable_references.rs:61:27 + --> $DIR/mutable_references.rs:62:27 | LL | const SNEAKY: &dyn Sync = &Synced { x: UnsafeCell::new(42) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: skipping check that does not even have a feature gate - --> $DIR/mutable_references.rs:82:45 + --> $DIR/mutable_references.rs:83:45 | LL | const POINTS_TO_MUTABLE_INNER: *const i32 = &mut 42 as *mut _ as *const _; | ^^^^^^^ help: skipping check that does not even have a feature gate - --> $DIR/mutable_references.rs:85:46 + --> $DIR/mutable_references.rs:86:46 | LL | const POINTS_TO_MUTABLE_INNER2: *const i32 = &mut 42 as *const _; | ^^^^^^^ help: skipping check that does not even have a feature gate - --> $DIR/mutable_references.rs:90:47 + --> $DIR/mutable_references.rs:91:47 | LL | const INTERIOR_MUTABLE_BEHIND_RAW: *mut i32 = &UnsafeCell::new(42) as *const _ as *mut _; | ^^^^^^^^^^^^^^^^^^^^ help: skipping check that does not even have a feature gate - --> $DIR/mutable_references.rs:102:51 + --> $DIR/mutable_references.rs:103:51 | LL | const RAW_SYNC: SyncPtr = SyncPtr { x: &AtomicI32::new(42) }; | ^^^^^^^^^^^^^^^^^^^ help: skipping check that does not even have a feature gate - --> $DIR/mutable_references.rs:105:49 + --> $DIR/mutable_references.rs:106:49 | LL | const RAW_MUT_CAST: SyncPtr = SyncPtr { x: &mut 42 as *mut _ as *const _ }; | ^^^^^^^ help: skipping check that does not even have a feature gate - --> $DIR/mutable_references.rs:108:51 + --> $DIR/mutable_references.rs:109:51 | LL | const RAW_MUT_COERCE: SyncPtr = SyncPtr { x: &mut 0 }; | ^^^^^^ diff --git a/tests/ui/consts/offset_from_ub.rs b/tests/ui/consts/offset_from_ub.rs index 53d9c7a39da..47511c0343d 100644 --- a/tests/ui/consts/offset_from_ub.rs +++ b/tests/ui/consts/offset_from_ub.rs @@ -1,4 +1,6 @@ //@ normalize-stderr: "\d+ bytes" -> "$$BYTES bytes" +//@ dont-require-annotations: NOTE + #![feature(core_intrinsics)] use std::intrinsics::{ptr_offset_from, ptr_offset_from_unsigned}; @@ -16,7 +18,7 @@ pub const DIFFERENT_ALLOC: usize = { let uninit2 = std::mem::MaybeUninit::::uninit(); let field_ptr: *const Struct = &uninit2 as *const _ as *const Struct; let offset = unsafe { ptr_offset_from(field_ptr, base_ptr) }; //~ERROR evaluation of constant value failed - //~| not both derived from the same allocation + //~| NOTE not both derived from the same allocation offset as usize }; @@ -29,14 +31,14 @@ pub const NOT_MULTIPLE_OF_SIZE: isize = { let base_ptr = data.as_ptr(); let field_ptr = &data[1] as *const u8 as *const u16; unsafe { ptr_offset_from(field_ptr, base_ptr as *const u16) } //~ERROR evaluation of constant value failed - //~| 1_isize cannot be divided by 2_isize without remainder + //~| NOTE 1_isize cannot be divided by 2_isize without remainder }; pub const DIFFERENT_INT: isize = { // offset_from with two different integers: like DIFFERENT_ALLOC let ptr1 = 8 as *const u8; let ptr2 = 16 as *const u8; unsafe { ptr_offset_from(ptr2, ptr1) } //~ERROR evaluation of constant value failed - //~| not both derived from the same allocation + //~| NOTE not both derived from the same allocation }; const OUT_OF_BOUNDS_1: isize = { @@ -45,7 +47,7 @@ const OUT_OF_BOUNDS_1: isize = { let end_ptr = (start_ptr).wrapping_add(length); // First ptr is out of bounds unsafe { ptr_offset_from(end_ptr, start_ptr) } //~ERROR evaluation of constant value failed - //~| the memory range between them is not in-bounds of an allocation + //~| NOTE the memory range between them is not in-bounds of an allocation }; const OUT_OF_BOUNDS_2: isize = { @@ -54,7 +56,7 @@ const OUT_OF_BOUNDS_2: isize = { let end_ptr = (start_ptr).wrapping_add(length); // Second ptr is out of bounds unsafe { ptr_offset_from(start_ptr, end_ptr) } //~ERROR evaluation of constant value failed - //~| the memory range between them is not in-bounds of an allocation + //~| NOTE the memory range between them is not in-bounds of an allocation }; pub const DIFFERENT_ALLOC_UNSIGNED: usize = { @@ -63,20 +65,20 @@ pub const DIFFERENT_ALLOC_UNSIGNED: usize = { let uninit2 = std::mem::MaybeUninit::::uninit(); let field_ptr: *const Struct = &uninit2 as *const _ as *const Struct; unsafe { ptr_offset_from_unsigned(field_ptr, base_ptr) } //~ERROR evaluation of constant value failed - //~| not both derived from the same allocation + //~| NOTE not both derived from the same allocation }; pub const TOO_FAR_APART1: isize = { let ptr1 = &0u8 as *const u8; let ptr2 = ptr1.wrapping_add(isize::MAX as usize + 42); unsafe { ptr_offset_from(ptr2, ptr1) } //~ERROR evaluation of constant value failed - //~| too far ahead + //~| NOTE too far ahead }; pub const TOO_FAR_APART2: isize = { let ptr1 = &0u8 as *const u8; let ptr2 = ptr1.wrapping_add(isize::MAX as usize + 42); unsafe { ptr_offset_from(ptr1, ptr2) } //~ERROR evaluation of constant value failed - //~| too far before + //~| NOTE too far before }; pub const TOO_FAR_APART3: isize = { let ptr1 = &0u8 as *const u8; @@ -84,21 +86,21 @@ pub const TOO_FAR_APART3: isize = { // The result of this would be `isize::MIN`, which *does* fit in an `isize`, but its // absolute value does not. (Also anyway there cannot be an allocation of that size.) unsafe { ptr_offset_from(ptr1, ptr2) } //~ERROR evaluation of constant value failed - //~| too far before + //~| NOTE too far before }; const WRONG_ORDER_UNSIGNED: usize = { let a = ['a', 'b', 'c']; let p = a.as_ptr(); unsafe { ptr_offset_from_unsigned(p, p.add(2) ) } //~ERROR evaluation of constant value failed - //~| first pointer has smaller offset than second: 0 < 8 + //~| NOTE first pointer has smaller offset than second: 0 < 8 }; pub const TOO_FAR_APART_UNSIGNED: usize = { let ptr1 = &0u8 as *const u8; let ptr2 = ptr1.wrapping_add(isize::MAX as usize + 42); // This would fit into a `usize` but we still don't allow it. unsafe { ptr_offset_from_unsigned(ptr2, ptr1) } //~ERROR evaluation of constant value failed - //~| too far ahead + //~| NOTE too far ahead }; // These do NOT complain that pointers are too far apart; they pass that check (to then fail the diff --git a/tests/ui/consts/offset_from_ub.stderr b/tests/ui/consts/offset_from_ub.stderr index 08e42c9f30b..5bfb9a1170c 100644 --- a/tests/ui/consts/offset_from_ub.stderr +++ b/tests/ui/consts/offset_from_ub.stderr @@ -1,11 +1,11 @@ error[E0080]: evaluation of constant value failed - --> $DIR/offset_from_ub.rs:18:27 + --> $DIR/offset_from_ub.rs:20:27 | LL | let offset = unsafe { ptr_offset_from(field_ptr, base_ptr) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `ptr_offset_from` called on two different pointers that are not both derived from the same allocation error[E0080]: evaluation of constant value failed - --> $DIR/offset_from_ub.rs:24:14 + --> $DIR/offset_from_ub.rs:26:14 | LL | unsafe { (42 as *const u8).offset_from(&5u8) as usize } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `ptr_offset_from` called on two different pointers that are not both derived from the same allocation @@ -14,67 +14,67 @@ note: inside `std::ptr::const_ptr::::offset_from` --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL error[E0080]: evaluation of constant value failed - --> $DIR/offset_from_ub.rs:31:14 + --> $DIR/offset_from_ub.rs:33:14 | LL | unsafe { ptr_offset_from(field_ptr, base_ptr as *const u16) } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ exact_div: 1_isize cannot be divided by 2_isize without remainder error[E0080]: evaluation of constant value failed - --> $DIR/offset_from_ub.rs:38:14 + --> $DIR/offset_from_ub.rs:40:14 | LL | unsafe { ptr_offset_from(ptr2, ptr1) } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `ptr_offset_from` called on two different pointers that are not both derived from the same allocation error[E0080]: evaluation of constant value failed - --> $DIR/offset_from_ub.rs:47:14 + --> $DIR/offset_from_ub.rs:49:14 | LL | unsafe { ptr_offset_from(end_ptr, start_ptr) } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `ptr_offset_from` called on two different pointers where the memory range between them is not in-bounds of an allocation error[E0080]: evaluation of constant value failed - --> $DIR/offset_from_ub.rs:56:14 + --> $DIR/offset_from_ub.rs:58:14 | LL | unsafe { ptr_offset_from(start_ptr, end_ptr) } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `ptr_offset_from` called on two different pointers where the memory range between them is not in-bounds of an allocation error[E0080]: evaluation of constant value failed - --> $DIR/offset_from_ub.rs:65:14 + --> $DIR/offset_from_ub.rs:67:14 | LL | unsafe { ptr_offset_from_unsigned(field_ptr, base_ptr) } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `ptr_offset_from_unsigned` called on two different pointers that are not both derived from the same allocation error[E0080]: evaluation of constant value failed - --> $DIR/offset_from_ub.rs:72:14 + --> $DIR/offset_from_ub.rs:74:14 | LL | unsafe { ptr_offset_from(ptr2, ptr1) } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `ptr_offset_from` called when first pointer is too far ahead of second error[E0080]: evaluation of constant value failed - --> $DIR/offset_from_ub.rs:78:14 + --> $DIR/offset_from_ub.rs:80:14 | LL | unsafe { ptr_offset_from(ptr1, ptr2) } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `ptr_offset_from` called when first pointer is too far before second error[E0080]: evaluation of constant value failed - --> $DIR/offset_from_ub.rs:86:14 + --> $DIR/offset_from_ub.rs:88:14 | LL | unsafe { ptr_offset_from(ptr1, ptr2) } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `ptr_offset_from` called when first pointer is too far before second error[E0080]: evaluation of constant value failed - --> $DIR/offset_from_ub.rs:93:14 + --> $DIR/offset_from_ub.rs:95:14 | LL | unsafe { ptr_offset_from_unsigned(p, p.add(2) ) } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `ptr_offset_from_unsigned` called when first pointer has smaller offset than second: 0 < 8 error[E0080]: evaluation of constant value failed - --> $DIR/offset_from_ub.rs:100:14 + --> $DIR/offset_from_ub.rs:102:14 | LL | unsafe { ptr_offset_from_unsigned(ptr2, ptr1) } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `ptr_offset_from_unsigned` called when first pointer is too far ahead of second error[E0080]: evaluation of constant value failed - --> $DIR/offset_from_ub.rs:109:14 + --> $DIR/offset_from_ub.rs:111:14 | LL | unsafe { ptr2.offset_from(ptr1) } | ^^^^^^^^^^^^^^^^^^^^^^ `ptr_offset_from` called on two different pointers that are not both derived from the same allocation @@ -83,7 +83,7 @@ note: inside `std::ptr::const_ptr::::offset_from` --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL error[E0080]: evaluation of constant value failed - --> $DIR/offset_from_ub.rs:115:14 + --> $DIR/offset_from_ub.rs:117:14 | LL | unsafe { ptr1.offset_from(ptr2.wrapping_offset(1)) } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `ptr_offset_from` called when first pointer is too far before second diff --git a/tests/ui/consts/required-consts/interpret-in-const-called-fn.noopt.stderr b/tests/ui/consts/required-consts/interpret-in-const-called-fn.noopt.stderr index 9184df472c4..f98e2c17202 100644 --- a/tests/ui/consts/required-consts/interpret-in-const-called-fn.noopt.stderr +++ b/tests/ui/consts/required-consts/interpret-in-const-called-fn.noopt.stderr @@ -5,7 +5,7 @@ LL | const C: () = panic!(); | ^^^^^^^^ evaluation panicked: explicit panic note: erroneous constant encountered - --> $DIR/interpret-in-const-called-fn.rs:17:9 + --> $DIR/interpret-in-const-called-fn.rs:18:9 | LL | Fail::::C; | ^^^^^^^^^^^^ diff --git a/tests/ui/consts/required-consts/interpret-in-const-called-fn.opt.stderr b/tests/ui/consts/required-consts/interpret-in-const-called-fn.opt.stderr index 9184df472c4..f98e2c17202 100644 --- a/tests/ui/consts/required-consts/interpret-in-const-called-fn.opt.stderr +++ b/tests/ui/consts/required-consts/interpret-in-const-called-fn.opt.stderr @@ -5,7 +5,7 @@ LL | const C: () = panic!(); | ^^^^^^^^ evaluation panicked: explicit panic note: erroneous constant encountered - --> $DIR/interpret-in-const-called-fn.rs:17:9 + --> $DIR/interpret-in-const-called-fn.rs:18:9 | LL | Fail::::C; | ^^^^^^^^^^^^ diff --git a/tests/ui/consts/required-consts/interpret-in-const-called-fn.rs b/tests/ui/consts/required-consts/interpret-in-const-called-fn.rs index f2e83f56f37..1ed6853f0a4 100644 --- a/tests/ui/consts/required-consts/interpret-in-const-called-fn.rs +++ b/tests/ui/consts/required-consts/interpret-in-const-called-fn.rs @@ -6,6 +6,7 @@ struct Fail(T); impl Fail { const C: () = panic!(); //~ERROR evaluation of `Fail::::C` failed + //~| NOTE in this expansion of panic! } #[inline(never)] @@ -14,7 +15,7 @@ const fn no_codegen() { // This bad constant is only used in dead code in a no-codegen function... and yet we still // must make sure that the build fails. // This relies on const-eval evaluating all `required_consts` of `const fn`. - Fail::::C; //~ constant + Fail::::C; //~ NOTE constant } } diff --git a/tests/ui/consts/required-consts/interpret-in-promoted.noopt.stderr b/tests/ui/consts/required-consts/interpret-in-promoted.noopt.stderr index 2bd0b92d4c2..f70e262ac4c 100644 --- a/tests/ui/consts/required-consts/interpret-in-promoted.noopt.stderr +++ b/tests/ui/consts/required-consts/interpret-in-promoted.noopt.stderr @@ -1,11 +1,11 @@ error[E0080]: evaluation of constant value failed - --> $DIR/interpret-in-promoted.rs:13:28 + --> $DIR/interpret-in-promoted.rs:15:28 | LL | let _x: &'static () = &ub(); | ^^^^ entering unreachable code | note: inside `ub` - --> $DIR/interpret-in-promoted.rs:7:5 + --> $DIR/interpret-in-promoted.rs:9:5 | LL | std::hint::unreachable_unchecked(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -13,7 +13,7 @@ note: inside `unreachable_unchecked` --> $SRC_DIR/core/src/hint.rs:LL:COL note: erroneous constant encountered - --> $DIR/interpret-in-promoted.rs:13:27 + --> $DIR/interpret-in-promoted.rs:15:27 | LL | let _x: &'static () = &ub(); | ^^^^^ diff --git a/tests/ui/consts/required-consts/interpret-in-promoted.opt.stderr b/tests/ui/consts/required-consts/interpret-in-promoted.opt.stderr index 2bd0b92d4c2..f70e262ac4c 100644 --- a/tests/ui/consts/required-consts/interpret-in-promoted.opt.stderr +++ b/tests/ui/consts/required-consts/interpret-in-promoted.opt.stderr @@ -1,11 +1,11 @@ error[E0080]: evaluation of constant value failed - --> $DIR/interpret-in-promoted.rs:13:28 + --> $DIR/interpret-in-promoted.rs:15:28 | LL | let _x: &'static () = &ub(); | ^^^^ entering unreachable code | note: inside `ub` - --> $DIR/interpret-in-promoted.rs:7:5 + --> $DIR/interpret-in-promoted.rs:9:5 | LL | std::hint::unreachable_unchecked(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -13,7 +13,7 @@ note: inside `unreachable_unchecked` --> $SRC_DIR/core/src/hint.rs:LL:COL note: erroneous constant encountered - --> $DIR/interpret-in-promoted.rs:13:27 + --> $DIR/interpret-in-promoted.rs:15:27 | LL | let _x: &'static () = &ub(); | ^^^^^ diff --git a/tests/ui/consts/required-consts/interpret-in-promoted.rs b/tests/ui/consts/required-consts/interpret-in-promoted.rs index 2c7b3375054..85d2ea3418c 100644 --- a/tests/ui/consts/required-consts/interpret-in-promoted.rs +++ b/tests/ui/consts/required-consts/interpret-in-promoted.rs @@ -1,10 +1,12 @@ //@revisions: noopt opt //@[noopt] compile-flags: -Copt-level=0 //@[opt] compile-flags: -O +//@ dont-require-annotations: NOTE + //! Make sure we evaluate const fn calls even if they get promoted and their result ignored. const unsafe fn ub() { - std::hint::unreachable_unchecked(); //~ inside `ub` + std::hint::unreachable_unchecked(); //~ NOTE inside `ub` } pub const FOO: () = unsafe { diff --git a/tests/ui/consts/required-consts/interpret-in-static.noopt.stderr b/tests/ui/consts/required-consts/interpret-in-static.noopt.stderr index aa778deb542..28daf265af4 100644 --- a/tests/ui/consts/required-consts/interpret-in-static.noopt.stderr +++ b/tests/ui/consts/required-consts/interpret-in-static.noopt.stderr @@ -5,7 +5,7 @@ LL | const C: () = panic!(); | ^^^^^^^^ evaluation panicked: explicit panic note: erroneous constant encountered - --> $DIR/interpret-in-static.rs:16:9 + --> $DIR/interpret-in-static.rs:17:9 | LL | Fail::::C; | ^^^^^^^^^^^^^^ diff --git a/tests/ui/consts/required-consts/interpret-in-static.opt.stderr b/tests/ui/consts/required-consts/interpret-in-static.opt.stderr index aa778deb542..28daf265af4 100644 --- a/tests/ui/consts/required-consts/interpret-in-static.opt.stderr +++ b/tests/ui/consts/required-consts/interpret-in-static.opt.stderr @@ -5,7 +5,7 @@ LL | const C: () = panic!(); | ^^^^^^^^ evaluation panicked: explicit panic note: erroneous constant encountered - --> $DIR/interpret-in-static.rs:16:9 + --> $DIR/interpret-in-static.rs:17:9 | LL | Fail::::C; | ^^^^^^^^^^^^^^ diff --git a/tests/ui/consts/required-consts/interpret-in-static.rs b/tests/ui/consts/required-consts/interpret-in-static.rs index 8bacd030440..7ddf15f9121 100644 --- a/tests/ui/consts/required-consts/interpret-in-static.rs +++ b/tests/ui/consts/required-consts/interpret-in-static.rs @@ -6,6 +6,7 @@ struct Fail(T); impl Fail { const C: () = panic!(); //~ERROR evaluation of `Fail::::C` failed + //~| NOTE in this expansion of panic! } pub static FOO: () = { @@ -13,7 +14,7 @@ pub static FOO: () = { // This bad constant is only used in dead code in a static initializer... and yet we still // must make sure that the build fails. // This relies on const-eval evaluating all `required_consts` of the `static` MIR body. - Fail::::C; //~ constant + Fail::::C; //~ NOTE constant } }; diff --git a/tests/ui/consts/uninhabited-const-issue-61744.rs b/tests/ui/consts/uninhabited-const-issue-61744.rs index 743aaf58ef5..802d422888b 100644 --- a/tests/ui/consts/uninhabited-const-issue-61744.rs +++ b/tests/ui/consts/uninhabited-const-issue-61744.rs @@ -1,11 +1,12 @@ //@ build-fail +//@ dont-require-annotations: NOTE pub const unsafe fn fake_type() -> T { - hint_unreachable() //~ inside + hint_unreachable() //~ NOTE inside } pub const unsafe fn hint_unreachable() -> ! { - fake_type() //~ inside + fake_type() //~ NOTE inside } trait Const { diff --git a/tests/ui/consts/uninhabited-const-issue-61744.stderr b/tests/ui/consts/uninhabited-const-issue-61744.stderr index dd175b92593..d0e90f9a423 100644 --- a/tests/ui/consts/uninhabited-const-issue-61744.stderr +++ b/tests/ui/consts/uninhabited-const-issue-61744.stderr @@ -1,641 +1,641 @@ error[E0080]: evaluation of `fake_type::` failed - --> $DIR/uninhabited-const-issue-61744.rs:12:36 + --> $DIR/uninhabited-const-issue-61744.rs:13:36 | LL | const CONSTANT: i32 = unsafe { fake_type() }; | ^^^^^^^^^^^ reached the configured maximum number of stack frames | note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 + --> $DIR/uninhabited-const-issue-61744.rs:5:5 | LL | hint_unreachable() | ^^^^^^^^^^^^^^^^^^ note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 + --> $DIR/uninhabited-const-issue-61744.rs:9:5 | LL | fake_type() | ^^^^^^^^^^^ note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 + --> $DIR/uninhabited-const-issue-61744.rs:5:5 | LL | hint_unreachable() | ^^^^^^^^^^^^^^^^^^ note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 + --> $DIR/uninhabited-const-issue-61744.rs:9:5 | LL | fake_type() | ^^^^^^^^^^^ note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 + --> $DIR/uninhabited-const-issue-61744.rs:5:5 | LL | hint_unreachable() | ^^^^^^^^^^^^^^^^^^ note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 + --> $DIR/uninhabited-const-issue-61744.rs:9:5 | LL | fake_type() | ^^^^^^^^^^^ note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 + --> $DIR/uninhabited-const-issue-61744.rs:5:5 | LL | hint_unreachable() | ^^^^^^^^^^^^^^^^^^ note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 + --> $DIR/uninhabited-const-issue-61744.rs:9:5 | LL | fake_type() | ^^^^^^^^^^^ note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 + --> $DIR/uninhabited-const-issue-61744.rs:5:5 | LL | hint_unreachable() | ^^^^^^^^^^^^^^^^^^ note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 + --> $DIR/uninhabited-const-issue-61744.rs:9:5 | LL | fake_type() | ^^^^^^^^^^^ note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 + --> $DIR/uninhabited-const-issue-61744.rs:5:5 | LL | hint_unreachable() | ^^^^^^^^^^^^^^^^^^ note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 + --> $DIR/uninhabited-const-issue-61744.rs:9:5 | LL | fake_type() | ^^^^^^^^^^^ note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 + --> $DIR/uninhabited-const-issue-61744.rs:5:5 | LL | hint_unreachable() | ^^^^^^^^^^^^^^^^^^ note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 + --> $DIR/uninhabited-const-issue-61744.rs:9:5 | LL | fake_type() | ^^^^^^^^^^^ note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 + --> $DIR/uninhabited-const-issue-61744.rs:5:5 | LL | hint_unreachable() | ^^^^^^^^^^^^^^^^^^ note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 + --> $DIR/uninhabited-const-issue-61744.rs:9:5 | LL | fake_type() | ^^^^^^^^^^^ note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 + --> $DIR/uninhabited-const-issue-61744.rs:5:5 | LL | hint_unreachable() | ^^^^^^^^^^^^^^^^^^ note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 + --> $DIR/uninhabited-const-issue-61744.rs:9:5 | LL | fake_type() | ^^^^^^^^^^^ note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 + --> $DIR/uninhabited-const-issue-61744.rs:5:5 | LL | hint_unreachable() | ^^^^^^^^^^^^^^^^^^ note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 + --> $DIR/uninhabited-const-issue-61744.rs:9:5 | LL | fake_type() | ^^^^^^^^^^^ note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 + --> $DIR/uninhabited-const-issue-61744.rs:5:5 | LL | hint_unreachable() | ^^^^^^^^^^^^^^^^^^ note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 + --> $DIR/uninhabited-const-issue-61744.rs:9:5 | LL | fake_type() | ^^^^^^^^^^^ note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 + --> $DIR/uninhabited-const-issue-61744.rs:5:5 | LL | hint_unreachable() | ^^^^^^^^^^^^^^^^^^ note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 + --> $DIR/uninhabited-const-issue-61744.rs:9:5 | LL | fake_type() | ^^^^^^^^^^^ note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 + --> $DIR/uninhabited-const-issue-61744.rs:5:5 | LL | hint_unreachable() | ^^^^^^^^^^^^^^^^^^ note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 + --> $DIR/uninhabited-const-issue-61744.rs:9:5 | LL | fake_type() | ^^^^^^^^^^^ note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 + --> $DIR/uninhabited-const-issue-61744.rs:5:5 | LL | hint_unreachable() | ^^^^^^^^^^^^^^^^^^ note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 + --> $DIR/uninhabited-const-issue-61744.rs:9:5 | LL | fake_type() | ^^^^^^^^^^^ note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 + --> $DIR/uninhabited-const-issue-61744.rs:5:5 | LL | hint_unreachable() | ^^^^^^^^^^^^^^^^^^ note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 + --> $DIR/uninhabited-const-issue-61744.rs:9:5 | LL | fake_type() | ^^^^^^^^^^^ note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 + --> $DIR/uninhabited-const-issue-61744.rs:5:5 | LL | hint_unreachable() | ^^^^^^^^^^^^^^^^^^ note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 + --> $DIR/uninhabited-const-issue-61744.rs:9:5 | LL | fake_type() | ^^^^^^^^^^^ note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 + --> $DIR/uninhabited-const-issue-61744.rs:5:5 | LL | hint_unreachable() | ^^^^^^^^^^^^^^^^^^ note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 + --> $DIR/uninhabited-const-issue-61744.rs:9:5 | LL | fake_type() | ^^^^^^^^^^^ note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 + --> $DIR/uninhabited-const-issue-61744.rs:5:5 | LL | hint_unreachable() | ^^^^^^^^^^^^^^^^^^ note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 + --> $DIR/uninhabited-const-issue-61744.rs:9:5 | LL | fake_type() | ^^^^^^^^^^^ note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 + --> $DIR/uninhabited-const-issue-61744.rs:5:5 | LL | hint_unreachable() | ^^^^^^^^^^^^^^^^^^ note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 + --> $DIR/uninhabited-const-issue-61744.rs:9:5 | LL | fake_type() | ^^^^^^^^^^^ note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 + --> $DIR/uninhabited-const-issue-61744.rs:5:5 | LL | hint_unreachable() | ^^^^^^^^^^^^^^^^^^ note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 + --> $DIR/uninhabited-const-issue-61744.rs:9:5 | LL | fake_type() | ^^^^^^^^^^^ note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 + --> $DIR/uninhabited-const-issue-61744.rs:5:5 | LL | hint_unreachable() | ^^^^^^^^^^^^^^^^^^ note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 + --> $DIR/uninhabited-const-issue-61744.rs:9:5 | LL | fake_type() | ^^^^^^^^^^^ note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 + --> $DIR/uninhabited-const-issue-61744.rs:5:5 | LL | hint_unreachable() | ^^^^^^^^^^^^^^^^^^ note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 + --> $DIR/uninhabited-const-issue-61744.rs:9:5 | LL | fake_type() | ^^^^^^^^^^^ note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 + --> $DIR/uninhabited-const-issue-61744.rs:5:5 | LL | hint_unreachable() | ^^^^^^^^^^^^^^^^^^ note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 + --> $DIR/uninhabited-const-issue-61744.rs:9:5 | LL | fake_type() | ^^^^^^^^^^^ note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 + --> $DIR/uninhabited-const-issue-61744.rs:5:5 | LL | hint_unreachable() | ^^^^^^^^^^^^^^^^^^ note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 + --> $DIR/uninhabited-const-issue-61744.rs:9:5 | LL | fake_type() | ^^^^^^^^^^^ note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 + --> $DIR/uninhabited-const-issue-61744.rs:5:5 | LL | hint_unreachable() | ^^^^^^^^^^^^^^^^^^ note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 + --> $DIR/uninhabited-const-issue-61744.rs:9:5 | LL | fake_type() | ^^^^^^^^^^^ note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 + --> $DIR/uninhabited-const-issue-61744.rs:5:5 | LL | hint_unreachable() | ^^^^^^^^^^^^^^^^^^ note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 + --> $DIR/uninhabited-const-issue-61744.rs:9:5 | LL | fake_type() | ^^^^^^^^^^^ note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 + --> $DIR/uninhabited-const-issue-61744.rs:5:5 | LL | hint_unreachable() | ^^^^^^^^^^^^^^^^^^ note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 + --> $DIR/uninhabited-const-issue-61744.rs:9:5 | LL | fake_type() | ^^^^^^^^^^^ note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 + --> $DIR/uninhabited-const-issue-61744.rs:5:5 | LL | hint_unreachable() | ^^^^^^^^^^^^^^^^^^ note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 + --> $DIR/uninhabited-const-issue-61744.rs:9:5 | LL | fake_type() | ^^^^^^^^^^^ note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 + --> $DIR/uninhabited-const-issue-61744.rs:5:5 | LL | hint_unreachable() | ^^^^^^^^^^^^^^^^^^ note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 + --> $DIR/uninhabited-const-issue-61744.rs:9:5 | LL | fake_type() | ^^^^^^^^^^^ note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 + --> $DIR/uninhabited-const-issue-61744.rs:5:5 | LL | hint_unreachable() | ^^^^^^^^^^^^^^^^^^ note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 + --> $DIR/uninhabited-const-issue-61744.rs:9:5 | LL | fake_type() | ^^^^^^^^^^^ note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 + --> $DIR/uninhabited-const-issue-61744.rs:5:5 | LL | hint_unreachable() | ^^^^^^^^^^^^^^^^^^ note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 + --> $DIR/uninhabited-const-issue-61744.rs:9:5 | LL | fake_type() | ^^^^^^^^^^^ note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 + --> $DIR/uninhabited-const-issue-61744.rs:5:5 | LL | hint_unreachable() | ^^^^^^^^^^^^^^^^^^ note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 + --> $DIR/uninhabited-const-issue-61744.rs:9:5 | LL | fake_type() | ^^^^^^^^^^^ note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 + --> $DIR/uninhabited-const-issue-61744.rs:5:5 | LL | hint_unreachable() | ^^^^^^^^^^^^^^^^^^ note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 + --> $DIR/uninhabited-const-issue-61744.rs:9:5 | LL | fake_type() | ^^^^^^^^^^^ note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 + --> $DIR/uninhabited-const-issue-61744.rs:5:5 | LL | hint_unreachable() | ^^^^^^^^^^^^^^^^^^ note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 + --> $DIR/uninhabited-const-issue-61744.rs:9:5 | LL | fake_type() | ^^^^^^^^^^^ note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 + --> $DIR/uninhabited-const-issue-61744.rs:5:5 | LL | hint_unreachable() | ^^^^^^^^^^^^^^^^^^ note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 + --> $DIR/uninhabited-const-issue-61744.rs:9:5 | LL | fake_type() | ^^^^^^^^^^^ note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 + --> $DIR/uninhabited-const-issue-61744.rs:5:5 | LL | hint_unreachable() | ^^^^^^^^^^^^^^^^^^ note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 + --> $DIR/uninhabited-const-issue-61744.rs:9:5 | LL | fake_type() | ^^^^^^^^^^^ note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 + --> $DIR/uninhabited-const-issue-61744.rs:5:5 | LL | hint_unreachable() | ^^^^^^^^^^^^^^^^^^ note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 + --> $DIR/uninhabited-const-issue-61744.rs:9:5 | LL | fake_type() | ^^^^^^^^^^^ note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 + --> $DIR/uninhabited-const-issue-61744.rs:5:5 | LL | hint_unreachable() | ^^^^^^^^^^^^^^^^^^ note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 + --> $DIR/uninhabited-const-issue-61744.rs:9:5 | LL | fake_type() | ^^^^^^^^^^^ note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 + --> $DIR/uninhabited-const-issue-61744.rs:5:5 | LL | hint_unreachable() | ^^^^^^^^^^^^^^^^^^ note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 + --> $DIR/uninhabited-const-issue-61744.rs:9:5 | LL | fake_type() | ^^^^^^^^^^^ note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 + --> $DIR/uninhabited-const-issue-61744.rs:5:5 | LL | hint_unreachable() | ^^^^^^^^^^^^^^^^^^ note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 + --> $DIR/uninhabited-const-issue-61744.rs:9:5 | LL | fake_type() | ^^^^^^^^^^^ note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 + --> $DIR/uninhabited-const-issue-61744.rs:5:5 | LL | hint_unreachable() | ^^^^^^^^^^^^^^^^^^ note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 + --> $DIR/uninhabited-const-issue-61744.rs:9:5 | LL | fake_type() | ^^^^^^^^^^^ note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 + --> $DIR/uninhabited-const-issue-61744.rs:5:5 | LL | hint_unreachable() | ^^^^^^^^^^^^^^^^^^ note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 + --> $DIR/uninhabited-const-issue-61744.rs:9:5 | LL | fake_type() | ^^^^^^^^^^^ note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 + --> $DIR/uninhabited-const-issue-61744.rs:5:5 | LL | hint_unreachable() | ^^^^^^^^^^^^^^^^^^ note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 + --> $DIR/uninhabited-const-issue-61744.rs:9:5 | LL | fake_type() | ^^^^^^^^^^^ note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 + --> $DIR/uninhabited-const-issue-61744.rs:5:5 | LL | hint_unreachable() | ^^^^^^^^^^^^^^^^^^ note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 + --> $DIR/uninhabited-const-issue-61744.rs:9:5 | LL | fake_type() | ^^^^^^^^^^^ note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 + --> $DIR/uninhabited-const-issue-61744.rs:5:5 | LL | hint_unreachable() | ^^^^^^^^^^^^^^^^^^ note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 + --> $DIR/uninhabited-const-issue-61744.rs:9:5 | LL | fake_type() | ^^^^^^^^^^^ note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 + --> $DIR/uninhabited-const-issue-61744.rs:5:5 | LL | hint_unreachable() | ^^^^^^^^^^^^^^^^^^ note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 + --> $DIR/uninhabited-const-issue-61744.rs:9:5 | LL | fake_type() | ^^^^^^^^^^^ note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 + --> $DIR/uninhabited-const-issue-61744.rs:5:5 | LL | hint_unreachable() | ^^^^^^^^^^^^^^^^^^ note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 + --> $DIR/uninhabited-const-issue-61744.rs:9:5 | LL | fake_type() | ^^^^^^^^^^^ note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 + --> $DIR/uninhabited-const-issue-61744.rs:5:5 | LL | hint_unreachable() | ^^^^^^^^^^^^^^^^^^ note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 + --> $DIR/uninhabited-const-issue-61744.rs:9:5 | LL | fake_type() | ^^^^^^^^^^^ note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 + --> $DIR/uninhabited-const-issue-61744.rs:5:5 | LL | hint_unreachable() | ^^^^^^^^^^^^^^^^^^ note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 + --> $DIR/uninhabited-const-issue-61744.rs:9:5 | LL | fake_type() | ^^^^^^^^^^^ note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 + --> $DIR/uninhabited-const-issue-61744.rs:5:5 | LL | hint_unreachable() | ^^^^^^^^^^^^^^^^^^ note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 + --> $DIR/uninhabited-const-issue-61744.rs:9:5 | LL | fake_type() | ^^^^^^^^^^^ note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 + --> $DIR/uninhabited-const-issue-61744.rs:5:5 | LL | hint_unreachable() | ^^^^^^^^^^^^^^^^^^ note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 + --> $DIR/uninhabited-const-issue-61744.rs:9:5 | LL | fake_type() | ^^^^^^^^^^^ note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 + --> $DIR/uninhabited-const-issue-61744.rs:5:5 | LL | hint_unreachable() | ^^^^^^^^^^^^^^^^^^ note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 + --> $DIR/uninhabited-const-issue-61744.rs:9:5 | LL | fake_type() | ^^^^^^^^^^^ note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 + --> $DIR/uninhabited-const-issue-61744.rs:5:5 | LL | hint_unreachable() | ^^^^^^^^^^^^^^^^^^ note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 + --> $DIR/uninhabited-const-issue-61744.rs:9:5 | LL | fake_type() | ^^^^^^^^^^^ note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 + --> $DIR/uninhabited-const-issue-61744.rs:5:5 | LL | hint_unreachable() | ^^^^^^^^^^^^^^^^^^ note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 + --> $DIR/uninhabited-const-issue-61744.rs:9:5 | LL | fake_type() | ^^^^^^^^^^^ note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 + --> $DIR/uninhabited-const-issue-61744.rs:5:5 | LL | hint_unreachable() | ^^^^^^^^^^^^^^^^^^ note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 + --> $DIR/uninhabited-const-issue-61744.rs:9:5 | LL | fake_type() | ^^^^^^^^^^^ note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 + --> $DIR/uninhabited-const-issue-61744.rs:5:5 | LL | hint_unreachable() | ^^^^^^^^^^^^^^^^^^ note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 + --> $DIR/uninhabited-const-issue-61744.rs:9:5 | LL | fake_type() | ^^^^^^^^^^^ note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 + --> $DIR/uninhabited-const-issue-61744.rs:5:5 | LL | hint_unreachable() | ^^^^^^^^^^^^^^^^^^ note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 + --> $DIR/uninhabited-const-issue-61744.rs:9:5 | LL | fake_type() | ^^^^^^^^^^^ note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 + --> $DIR/uninhabited-const-issue-61744.rs:5:5 | LL | hint_unreachable() | ^^^^^^^^^^^^^^^^^^ note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 + --> $DIR/uninhabited-const-issue-61744.rs:9:5 | LL | fake_type() | ^^^^^^^^^^^ note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 + --> $DIR/uninhabited-const-issue-61744.rs:5:5 | LL | hint_unreachable() | ^^^^^^^^^^^^^^^^^^ note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 + --> $DIR/uninhabited-const-issue-61744.rs:9:5 | LL | fake_type() | ^^^^^^^^^^^ note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 + --> $DIR/uninhabited-const-issue-61744.rs:5:5 | LL | hint_unreachable() | ^^^^^^^^^^^^^^^^^^ note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 + --> $DIR/uninhabited-const-issue-61744.rs:9:5 | LL | fake_type() | ^^^^^^^^^^^ note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 + --> $DIR/uninhabited-const-issue-61744.rs:5:5 | LL | hint_unreachable() | ^^^^^^^^^^^^^^^^^^ note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 + --> $DIR/uninhabited-const-issue-61744.rs:9:5 | LL | fake_type() | ^^^^^^^^^^^ note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 + --> $DIR/uninhabited-const-issue-61744.rs:5:5 | LL | hint_unreachable() | ^^^^^^^^^^^^^^^^^^ note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 + --> $DIR/uninhabited-const-issue-61744.rs:9:5 | LL | fake_type() | ^^^^^^^^^^^ note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 + --> $DIR/uninhabited-const-issue-61744.rs:5:5 | LL | hint_unreachable() | ^^^^^^^^^^^^^^^^^^ note: inside `hint_unreachable` - --> $DIR/uninhabited-const-issue-61744.rs:8:5 + --> $DIR/uninhabited-const-issue-61744.rs:9:5 | LL | fake_type() | ^^^^^^^^^^^ note: inside `fake_type::` - --> $DIR/uninhabited-const-issue-61744.rs:4:5 + --> $DIR/uninhabited-const-issue-61744.rs:5:5 | LL | hint_unreachable() | ^^^^^^^^^^^^^^^^^^ the failure occurred here diff --git a/tests/ui/coroutine/drop-tracking-parent-expression.rs b/tests/ui/coroutine/drop-tracking-parent-expression.rs index 0f4d99c8936..702cbc88ae4 100644 --- a/tests/ui/coroutine/drop-tracking-parent-expression.rs +++ b/tests/ui/coroutine/drop-tracking-parent-expression.rs @@ -1,3 +1,5 @@ +//@ dont-require-annotations: NOTE + #![feature(coroutines, negative_impls, rustc_attrs, stmt_expr_attributes)] macro_rules! type_combinations { @@ -15,9 +17,9 @@ macro_rules! type_combinations { // dropped *after* the yield. { let g = #[coroutine] move || match drop($name::Client { ..$name::Client::default() }) { - //~^ `significant_drop::Client` which is not `Send` - //~| `insignificant_dtor::Client` which is not `Send` - //~| `derived_drop::Client` which is not `Send` + //~^ NOTE `significant_drop::Client` which is not `Send` + //~| NOTE `insignificant_dtor::Client` which is not `Send` + //~| NOTE `derived_drop::Client` which is not `Send` _ => yield, }; assert_send(g); diff --git a/tests/ui/coroutine/drop-tracking-parent-expression.stderr b/tests/ui/coroutine/drop-tracking-parent-expression.stderr index dc2f9768d23..2f5fe882f6e 100644 --- a/tests/ui/coroutine/drop-tracking-parent-expression.stderr +++ b/tests/ui/coroutine/drop-tracking-parent-expression.stderr @@ -1,5 +1,5 @@ error: coroutine cannot be sent between threads safely - --> $DIR/drop-tracking-parent-expression.rs:23:13 + --> $DIR/drop-tracking-parent-expression.rs:25:13 | LL | assert_send(g); | ^^^^^^^^^^^^^^ coroutine is not `Send` @@ -12,9 +12,9 @@ LL | | }; LL | | ); | |_____- in this macro invocation | - = help: within `{coroutine@$DIR/drop-tracking-parent-expression.rs:17:34: 17:41}`, the trait `Send` is not implemented for `derived_drop::Client` + = help: within `{coroutine@$DIR/drop-tracking-parent-expression.rs:19:34: 19:41}`, the trait `Send` is not implemented for `derived_drop::Client` note: coroutine is not `Send` as this value is used across a yield - --> $DIR/drop-tracking-parent-expression.rs:21:22 + --> $DIR/drop-tracking-parent-expression.rs:23:22 | LL | let g = #[coroutine] move || match drop($name::Client { ..$name::Client::default() }) { | ------------------------ has type `derived_drop::Client` which is not `Send` @@ -30,14 +30,14 @@ LL | | }; LL | | ); | |_____- in this macro invocation note: required by a bound in `assert_send` - --> $DIR/drop-tracking-parent-expression.rs:40:19 + --> $DIR/drop-tracking-parent-expression.rs:42:19 | LL | fn assert_send(_thing: T) {} | ^^^^ required by this bound in `assert_send` = note: this error originates in the macro `type_combinations` (in Nightly builds, run with -Z macro-backtrace for more info) error: coroutine cannot be sent between threads safely - --> $DIR/drop-tracking-parent-expression.rs:23:13 + --> $DIR/drop-tracking-parent-expression.rs:25:13 | LL | assert_send(g); | ^^^^^^^^^^^^^^ coroutine is not `Send` @@ -50,9 +50,9 @@ LL | | }; LL | | ); | |_____- in this macro invocation | - = help: within `{coroutine@$DIR/drop-tracking-parent-expression.rs:17:34: 17:41}`, the trait `Send` is not implemented for `significant_drop::Client` + = help: within `{coroutine@$DIR/drop-tracking-parent-expression.rs:19:34: 19:41}`, the trait `Send` is not implemented for `significant_drop::Client` note: coroutine is not `Send` as this value is used across a yield - --> $DIR/drop-tracking-parent-expression.rs:21:22 + --> $DIR/drop-tracking-parent-expression.rs:23:22 | LL | let g = #[coroutine] move || match drop($name::Client { ..$name::Client::default() }) { | ------------------------ has type `significant_drop::Client` which is not `Send` @@ -68,14 +68,14 @@ LL | | }; LL | | ); | |_____- in this macro invocation note: required by a bound in `assert_send` - --> $DIR/drop-tracking-parent-expression.rs:40:19 + --> $DIR/drop-tracking-parent-expression.rs:42:19 | LL | fn assert_send(_thing: T) {} | ^^^^ required by this bound in `assert_send` = note: this error originates in the macro `type_combinations` (in Nightly builds, run with -Z macro-backtrace for more info) error: coroutine cannot be sent between threads safely - --> $DIR/drop-tracking-parent-expression.rs:23:13 + --> $DIR/drop-tracking-parent-expression.rs:25:13 | LL | assert_send(g); | ^^^^^^^^^^^^^^ coroutine is not `Send` @@ -88,9 +88,9 @@ LL | | }; LL | | ); | |_____- in this macro invocation | - = help: within `{coroutine@$DIR/drop-tracking-parent-expression.rs:17:34: 17:41}`, the trait `Send` is not implemented for `insignificant_dtor::Client` + = help: within `{coroutine@$DIR/drop-tracking-parent-expression.rs:19:34: 19:41}`, the trait `Send` is not implemented for `insignificant_dtor::Client` note: coroutine is not `Send` as this value is used across a yield - --> $DIR/drop-tracking-parent-expression.rs:21:22 + --> $DIR/drop-tracking-parent-expression.rs:23:22 | LL | let g = #[coroutine] move || match drop($name::Client { ..$name::Client::default() }) { | ------------------------ has type `insignificant_dtor::Client` which is not `Send` @@ -106,7 +106,7 @@ LL | | }; LL | | ); | |_____- in this macro invocation note: required by a bound in `assert_send` - --> $DIR/drop-tracking-parent-expression.rs:40:19 + --> $DIR/drop-tracking-parent-expression.rs:42:19 | LL | fn assert_send(_thing: T) {} | ^^^^ required by this bound in `assert_send` diff --git a/tests/ui/coroutine/parent-expression.rs b/tests/ui/coroutine/parent-expression.rs index 0f4d99c8936..702cbc88ae4 100644 --- a/tests/ui/coroutine/parent-expression.rs +++ b/tests/ui/coroutine/parent-expression.rs @@ -1,3 +1,5 @@ +//@ dont-require-annotations: NOTE + #![feature(coroutines, negative_impls, rustc_attrs, stmt_expr_attributes)] macro_rules! type_combinations { @@ -15,9 +17,9 @@ macro_rules! type_combinations { // dropped *after* the yield. { let g = #[coroutine] move || match drop($name::Client { ..$name::Client::default() }) { - //~^ `significant_drop::Client` which is not `Send` - //~| `insignificant_dtor::Client` which is not `Send` - //~| `derived_drop::Client` which is not `Send` + //~^ NOTE `significant_drop::Client` which is not `Send` + //~| NOTE `insignificant_dtor::Client` which is not `Send` + //~| NOTE `derived_drop::Client` which is not `Send` _ => yield, }; assert_send(g); diff --git a/tests/ui/coroutine/parent-expression.stderr b/tests/ui/coroutine/parent-expression.stderr index a9125772b5a..f14bf05ed09 100644 --- a/tests/ui/coroutine/parent-expression.stderr +++ b/tests/ui/coroutine/parent-expression.stderr @@ -1,5 +1,5 @@ error: coroutine cannot be sent between threads safely - --> $DIR/parent-expression.rs:23:13 + --> $DIR/parent-expression.rs:25:13 | LL | assert_send(g); | ^^^^^^^^^^^^^^ coroutine is not `Send` @@ -12,9 +12,9 @@ LL | | }; LL | | ); | |_____- in this macro invocation | - = help: within `{coroutine@$DIR/parent-expression.rs:17:34: 17:41}`, the trait `Send` is not implemented for `derived_drop::Client` + = help: within `{coroutine@$DIR/parent-expression.rs:19:34: 19:41}`, the trait `Send` is not implemented for `derived_drop::Client` note: coroutine is not `Send` as this value is used across a yield - --> $DIR/parent-expression.rs:21:22 + --> $DIR/parent-expression.rs:23:22 | LL | let g = #[coroutine] move || match drop($name::Client { ..$name::Client::default() }) { | ------------------------ has type `derived_drop::Client` which is not `Send` @@ -30,14 +30,14 @@ LL | | }; LL | | ); | |_____- in this macro invocation note: required by a bound in `assert_send` - --> $DIR/parent-expression.rs:40:19 + --> $DIR/parent-expression.rs:42:19 | LL | fn assert_send(_thing: T) {} | ^^^^ required by this bound in `assert_send` = note: this error originates in the macro `type_combinations` (in Nightly builds, run with -Z macro-backtrace for more info) error: coroutine cannot be sent between threads safely - --> $DIR/parent-expression.rs:23:13 + --> $DIR/parent-expression.rs:25:13 | LL | assert_send(g); | ^^^^^^^^^^^^^^ coroutine is not `Send` @@ -50,9 +50,9 @@ LL | | }; LL | | ); | |_____- in this macro invocation | - = help: within `{coroutine@$DIR/parent-expression.rs:17:34: 17:41}`, the trait `Send` is not implemented for `significant_drop::Client` + = help: within `{coroutine@$DIR/parent-expression.rs:19:34: 19:41}`, the trait `Send` is not implemented for `significant_drop::Client` note: coroutine is not `Send` as this value is used across a yield - --> $DIR/parent-expression.rs:21:22 + --> $DIR/parent-expression.rs:23:22 | LL | let g = #[coroutine] move || match drop($name::Client { ..$name::Client::default() }) { | ------------------------ has type `significant_drop::Client` which is not `Send` @@ -68,14 +68,14 @@ LL | | }; LL | | ); | |_____- in this macro invocation note: required by a bound in `assert_send` - --> $DIR/parent-expression.rs:40:19 + --> $DIR/parent-expression.rs:42:19 | LL | fn assert_send(_thing: T) {} | ^^^^ required by this bound in `assert_send` = note: this error originates in the macro `type_combinations` (in Nightly builds, run with -Z macro-backtrace for more info) error: coroutine cannot be sent between threads safely - --> $DIR/parent-expression.rs:23:13 + --> $DIR/parent-expression.rs:25:13 | LL | assert_send(g); | ^^^^^^^^^^^^^^ coroutine is not `Send` @@ -88,9 +88,9 @@ LL | | }; LL | | ); | |_____- in this macro invocation | - = help: within `{coroutine@$DIR/parent-expression.rs:17:34: 17:41}`, the trait `Send` is not implemented for `insignificant_dtor::Client` + = help: within `{coroutine@$DIR/parent-expression.rs:19:34: 19:41}`, the trait `Send` is not implemented for `insignificant_dtor::Client` note: coroutine is not `Send` as this value is used across a yield - --> $DIR/parent-expression.rs:21:22 + --> $DIR/parent-expression.rs:23:22 | LL | let g = #[coroutine] move || match drop($name::Client { ..$name::Client::default() }) { | ------------------------ has type `insignificant_dtor::Client` which is not `Send` @@ -106,7 +106,7 @@ LL | | }; LL | | ); | |_____- in this macro invocation note: required by a bound in `assert_send` - --> $DIR/parent-expression.rs:40:19 + --> $DIR/parent-expression.rs:42:19 | LL | fn assert_send(_thing: T) {} | ^^^^ required by this bound in `assert_send` diff --git a/tests/ui/coverage-attr/bad-attr-ice.rs b/tests/ui/coverage-attr/bad-attr-ice.rs index 8d57bbbf49a..aeb44075bb6 100644 --- a/tests/ui/coverage-attr/bad-attr-ice.rs +++ b/tests/ui/coverage-attr/bad-attr-ice.rs @@ -10,7 +10,7 @@ #[coverage] //~^ ERROR malformed `coverage` attribute input -//[nofeat]~| the `#[coverage]` attribute is an experimental feature +//[nofeat]~| ERROR the `#[coverage]` attribute is an experimental feature fn main() {} // FIXME(#130766): When the `#[coverage(..)]` attribute is stabilized, diff --git a/tests/ui/cross/cross-borrow-trait.rs b/tests/ui/cross/cross-borrow-trait.rs index 180a75e3dfc..88ea78e44b3 100644 --- a/tests/ui/cross/cross-borrow-trait.rs +++ b/tests/ui/cross/cross-borrow-trait.rs @@ -1,6 +1,8 @@ // Test that cross-borrowing (implicitly converting from `Box` to `&T`) is // forbidden when `T` is a trait. +//@ dont-require-annotations: NOTE + struct Foo; trait Trait { fn foo(&self) {} } impl Trait for Foo {} @@ -8,6 +10,6 @@ impl Trait for Foo {} pub fn main() { let x: Box = Box::new(Foo); let _y: &dyn Trait = x; //~ ERROR E0308 - //~| expected reference `&dyn Trait` - //~| found struct `Box` + //~| NOTE expected reference `&dyn Trait` + //~| NOTE found struct `Box` } diff --git a/tests/ui/cross/cross-borrow-trait.stderr b/tests/ui/cross/cross-borrow-trait.stderr index b670de39f6d..5fe80b5a3ee 100644 --- a/tests/ui/cross/cross-borrow-trait.stderr +++ b/tests/ui/cross/cross-borrow-trait.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/cross-borrow-trait.rs:10:26 + --> $DIR/cross-borrow-trait.rs:12:26 | LL | let _y: &dyn Trait = x; | ---------- ^ expected `&dyn Trait`, found `Box` diff --git a/tests/ui/destructure-trait-ref.rs b/tests/ui/destructure-trait-ref.rs index 50b64aeebf0..daa0ca30d68 100644 --- a/tests/ui/destructure-trait-ref.rs +++ b/tests/ui/destructure-trait-ref.rs @@ -1,6 +1,8 @@ // The regression test for #15031 to make sure destructuring trait // reference work properly. +//@ dont-require-annotations: NOTE + #![feature(box_patterns)] trait T { fn foo(&self) {} } @@ -31,14 +33,14 @@ fn main() { // n > m let &&x = &1isize as &dyn T; //~^ ERROR mismatched types - //~| expected trait object `dyn T` - //~| found reference `&_` + //~| NOTE expected trait object `dyn T` + //~| NOTE found reference `&_` let &&&x = &(&1isize as &dyn T); //~^ ERROR mismatched types - //~| expected trait object `dyn T` - //~| found reference `&_` + //~| NOTE expected trait object `dyn T` + //~| NOTE found reference `&_` let box box x = Box::new(1isize) as Box; //~^ ERROR mismatched types - //~| expected trait object `dyn T` - //~| found struct `Box<_>` + //~| NOTE expected trait object `dyn T` + //~| NOTE found struct `Box<_>` } diff --git a/tests/ui/destructure-trait-ref.stderr b/tests/ui/destructure-trait-ref.stderr index 38d20188827..0b5ea551a57 100644 --- a/tests/ui/destructure-trait-ref.stderr +++ b/tests/ui/destructure-trait-ref.stderr @@ -1,23 +1,23 @@ error[E0033]: type `&dyn T` cannot be dereferenced - --> $DIR/destructure-trait-ref.rs:26:9 + --> $DIR/destructure-trait-ref.rs:28:9 | LL | let &x = &1isize as &dyn T; | ^^ type `&dyn T` cannot be dereferenced error[E0033]: type `&dyn T` cannot be dereferenced - --> $DIR/destructure-trait-ref.rs:27:10 + --> $DIR/destructure-trait-ref.rs:29:10 | LL | let &&x = &(&1isize as &dyn T); | ^^ type `&dyn T` cannot be dereferenced error[E0033]: type `Box` cannot be dereferenced - --> $DIR/destructure-trait-ref.rs:28:9 + --> $DIR/destructure-trait-ref.rs:30:9 | LL | let box x = Box::new(1isize) as Box; | ^^^^^ type `Box` cannot be dereferenced error[E0308]: mismatched types - --> $DIR/destructure-trait-ref.rs:32:10 + --> $DIR/destructure-trait-ref.rs:34:10 | LL | let &&x = &1isize as &dyn T; | ^^ ----------------- this expression has type `&dyn T` @@ -33,7 +33,7 @@ LL + let &x = &1isize as &dyn T; | error[E0308]: mismatched types - --> $DIR/destructure-trait-ref.rs:36:11 + --> $DIR/destructure-trait-ref.rs:38:11 | LL | let &&&x = &(&1isize as &dyn T); | ^^ -------------------- this expression has type `&&dyn T` @@ -49,7 +49,7 @@ LL + let &&x = &(&1isize as &dyn T); | error[E0308]: mismatched types - --> $DIR/destructure-trait-ref.rs:40:13 + --> $DIR/destructure-trait-ref.rs:42:13 | LL | let box box x = Box::new(1isize) as Box; | ^^^^^ ------------------------------ this expression has type `Box` diff --git a/tests/ui/diagnostic-width/long-E0529.rs b/tests/ui/diagnostic-width/long-E0529.rs index 759a902da7e..4146d3be40f 100644 --- a/tests/ui/diagnostic-width/long-E0529.rs +++ b/tests/ui/diagnostic-width/long-E0529.rs @@ -1,4 +1,5 @@ //@ compile-flags: --diagnostic-width=60 -Zwrite-long-types-to-disk=yes +//@ dont-require-annotations: NOTE type A = (i32, i32, i32, i32); type B = (A, A, A, A); @@ -7,7 +8,7 @@ type D = (C, C, C, C); fn foo(x: D) { let [] = x; //~ ERROR expected an array or slice, found `(... - //~^ pattern cannot match with input type `(... + //~^ NOTE pattern cannot match with input type `(... } fn main() {} diff --git a/tests/ui/diagnostic-width/long-E0529.stderr b/tests/ui/diagnostic-width/long-E0529.stderr index bf3144cc9b6..e5b82b59271 100644 --- a/tests/ui/diagnostic-width/long-E0529.stderr +++ b/tests/ui/diagnostic-width/long-E0529.stderr @@ -1,5 +1,5 @@ error[E0529]: expected an array or slice, found `(..., ..., ..., ...)` - --> $DIR/long-E0529.rs:9:9 + --> $DIR/long-E0529.rs:10:9 | LL | let [] = x; | ^^ pattern cannot match with input type `(..., ..., ..., ...)` diff --git a/tests/ui/diagnostic-width/long-E0618.rs b/tests/ui/diagnostic-width/long-E0618.rs index b499bedc394..247061d17f8 100644 --- a/tests/ui/diagnostic-width/long-E0618.rs +++ b/tests/ui/diagnostic-width/long-E0618.rs @@ -1,11 +1,12 @@ //@ compile-flags: --diagnostic-width=60 -Zwrite-long-types-to-disk=yes +//@ dont-require-annotations: NOTE type A = (i32, i32, i32, i32); type B = (A, A, A, A); type C = (B, B, B, B); type D = (C, C, C, C); -fn foo(x: D) { //~ `x` has type `(... +fn foo(x: D) { //~ NOTE `x` has type `(... x(); //~ ERROR expected function, found `(... } diff --git a/tests/ui/diagnostic-width/long-E0618.stderr b/tests/ui/diagnostic-width/long-E0618.stderr index 05bf999c142..7d92b94faf8 100644 --- a/tests/ui/diagnostic-width/long-E0618.stderr +++ b/tests/ui/diagnostic-width/long-E0618.stderr @@ -1,5 +1,5 @@ error[E0618]: expected function, found `(..., ..., ..., ...)` - --> $DIR/long-E0618.rs:9:5 + --> $DIR/long-E0618.rs:10:5 | LL | fn foo(x: D) { | - `x` has type `(..., ..., ..., ...)` diff --git a/tests/ui/diagnostic_namespace/on_unimplemented/custom-on-unimplemented-diagnostic.rs b/tests/ui/diagnostic_namespace/on_unimplemented/custom-on-unimplemented-diagnostic.rs index 3bb0939b5f9..44a84f40d44 100644 --- a/tests/ui/diagnostic_namespace/on_unimplemented/custom-on-unimplemented-diagnostic.rs +++ b/tests/ui/diagnostic_namespace/on_unimplemented/custom-on-unimplemented-diagnostic.rs @@ -1,5 +1,7 @@ //@ reference: attributes.diagnostic.on_unimplemented.intro //@ reference: attributes.diagnostic.on_unimplemented.keys +//@ dont-require-annotations: NOTE + #[diagnostic::on_unimplemented(message = "my message", label = "my label", note = "my note")] pub trait ProviderLt {} @@ -16,6 +18,6 @@ struct B; fn main() { B.request(); //~^ ERROR my message [E0599] - //~| my label - //~| my note + //~| NOTE my label + //~| NOTE my note } diff --git a/tests/ui/diagnostic_namespace/on_unimplemented/custom-on-unimplemented-diagnostic.stderr b/tests/ui/diagnostic_namespace/on_unimplemented/custom-on-unimplemented-diagnostic.stderr index 4c1838620b3..1ba2c2e222d 100644 --- a/tests/ui/diagnostic_namespace/on_unimplemented/custom-on-unimplemented-diagnostic.stderr +++ b/tests/ui/diagnostic_namespace/on_unimplemented/custom-on-unimplemented-diagnostic.stderr @@ -1,5 +1,5 @@ error[E0599]: my message - --> $DIR/custom-on-unimplemented-diagnostic.rs:17:7 + --> $DIR/custom-on-unimplemented-diagnostic.rs:19:7 | LL | struct B; | -------- method `request` not found for this struct because it doesn't satisfy `B: ProviderExt` or `B: ProviderLt` @@ -8,7 +8,7 @@ LL | B.request(); | ^^^^^^^ my label | note: trait bound `B: ProviderLt` was not satisfied - --> $DIR/custom-on-unimplemented-diagnostic.rs:12:18 + --> $DIR/custom-on-unimplemented-diagnostic.rs:14:18 | LL | impl ProviderExt for T {} | ^^^^^^^^^^ ----------- - @@ -16,13 +16,13 @@ LL | impl ProviderExt for T {} | unsatisfied trait bound introduced here = note: my note note: the trait `ProviderLt` must be implemented - --> $DIR/custom-on-unimplemented-diagnostic.rs:4:1 + --> $DIR/custom-on-unimplemented-diagnostic.rs:6:1 | LL | pub trait ProviderLt {} | ^^^^^^^^^^^^^^^^^^^^ = help: items from traits can only be used if the trait is implemented and in scope note: `ProviderExt` defines an item `request`, perhaps you need to implement it - --> $DIR/custom-on-unimplemented-diagnostic.rs:6:1 + --> $DIR/custom-on-unimplemented-diagnostic.rs:8:1 | LL | pub trait ProviderExt { | ^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/dst/dst-bad-assign-3.rs b/tests/ui/dst/dst-bad-assign-3.rs index f96ecf7762c..e9e69134a62 100644 --- a/tests/ui/dst/dst-bad-assign-3.rs +++ b/tests/ui/dst/dst-bad-assign-3.rs @@ -1,5 +1,7 @@ // Forbid assignment into a dynamically sized type. +//@ dont-require-annotations: NOTE + struct Fat(isize, &'static str, T); #[derive(PartialEq,Eq)] @@ -30,8 +32,8 @@ pub fn main() { let z: Box = Box::new(Bar1 {f: 36}); f5.2 = Bar1 {f: 36}; //~^ ERROR mismatched types - //~| expected `dyn ToBar`, found `Bar1` - //~| expected trait object `dyn ToBar` - //~| found struct `Bar1` + //~| NOTE expected `dyn ToBar`, found `Bar1` + //~| NOTE expected trait object `dyn ToBar` + //~| NOTE found struct `Bar1` //~| ERROR the size for values of type } diff --git a/tests/ui/dst/dst-bad-assign-3.stderr b/tests/ui/dst/dst-bad-assign-3.stderr index 4aa1677e751..007f6b898be 100644 --- a/tests/ui/dst/dst-bad-assign-3.stderr +++ b/tests/ui/dst/dst-bad-assign-3.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/dst-bad-assign-3.rs:31:12 + --> $DIR/dst-bad-assign-3.rs:33:12 | LL | f5.2 = Bar1 {f: 36}; | ---- ^^^^^^^^^^^^ expected `dyn ToBar`, found `Bar1` @@ -11,7 +11,7 @@ LL | f5.2 = Bar1 {f: 36}; = help: `Bar1` implements `ToBar` so you could box the found value and coerce it to the trait object `Box`, you will have to change the expected type as well error[E0277]: the size for values of type `dyn ToBar` cannot be known at compilation time - --> $DIR/dst-bad-assign-3.rs:31:5 + --> $DIR/dst-bad-assign-3.rs:33:5 | LL | f5.2 = Bar1 {f: 36}; | ^^^^ doesn't have a size known at compile-time diff --git a/tests/ui/dst/dst-bad-assign.rs b/tests/ui/dst/dst-bad-assign.rs index c55fb2c3e57..79a3f5c44d3 100644 --- a/tests/ui/dst/dst-bad-assign.rs +++ b/tests/ui/dst/dst-bad-assign.rs @@ -1,5 +1,7 @@ // Forbid assignment into a dynamically sized type. +//@ dont-require-annotations: NOTE + struct Fat { f1: isize, f2: &'static str, @@ -34,8 +36,8 @@ pub fn main() { let z: Box = Box::new(Bar1 {f: 36}); f5.ptr = Bar1 {f: 36}; //~^ ERROR mismatched types - //~| expected `dyn ToBar`, found `Bar1` - //~| expected trait object `dyn ToBar` - //~| found struct `Bar1` + //~| NOTE expected `dyn ToBar`, found `Bar1` + //~| NOTE expected trait object `dyn ToBar` + //~| NOTE found struct `Bar1` //~| ERROR the size for values of type } diff --git a/tests/ui/dst/dst-bad-assign.stderr b/tests/ui/dst/dst-bad-assign.stderr index f935d27e96e..fc73069bee0 100644 --- a/tests/ui/dst/dst-bad-assign.stderr +++ b/tests/ui/dst/dst-bad-assign.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/dst-bad-assign.rs:35:14 + --> $DIR/dst-bad-assign.rs:37:14 | LL | f5.ptr = Bar1 {f: 36}; | ------ ^^^^^^^^^^^^ expected `dyn ToBar`, found `Bar1` @@ -11,7 +11,7 @@ LL | f5.ptr = Bar1 {f: 36}; = help: `Bar1` implements `ToBar` so you could box the found value and coerce it to the trait object `Box`, you will have to change the expected type as well error[E0277]: the size for values of type `dyn ToBar` cannot be known at compilation time - --> $DIR/dst-bad-assign.rs:35:5 + --> $DIR/dst-bad-assign.rs:37:5 | LL | f5.ptr = Bar1 {f: 36}; | ^^^^^^ doesn't have a size known at compile-time diff --git a/tests/ui/dst/dst-bad-coerce4.rs b/tests/ui/dst/dst-bad-coerce4.rs index 25410aa4fac..b5288d5d3e1 100644 --- a/tests/ui/dst/dst-bad-coerce4.rs +++ b/tests/ui/dst/dst-bad-coerce4.rs @@ -9,7 +9,8 @@ pub fn main() { let f1: &Fat<[isize]> = &Fat { ptr: [1, 2, 3] }; let f2: &Fat<[isize; 3]> = f1; //~^ ERROR mismatched types - //~| expected `&Fat<[isize; 3]>`, found `&Fat<[isize]>` - //~| expected reference `&Fat<[isize; 3]>` - //~| found reference `&Fat<[isize]>` + //~| NOTE expected `&Fat<[isize; 3]>`, found `&Fat<[isize]>` + //~| NOTE expected reference `&Fat<[isize; 3]>` + //~| NOTE found reference `&Fat<[isize]>` + //~| NOTE expected due to this } diff --git a/tests/ui/empty/empty-never-array.rs b/tests/ui/empty/empty-never-array.rs index fd93346101d..c84d9bd85a3 100644 --- a/tests/ui/empty/empty-never-array.rs +++ b/tests/ui/empty/empty-never-array.rs @@ -1,3 +1,5 @@ +//@ dont-require-annotations: NOTE + #![feature(never_type)] enum Helper { @@ -9,7 +11,7 @@ enum Helper { fn transmute(t: T) -> U { let Helper::U(u) = Helper::T(t, []); //~^ ERROR refutable pattern in local binding - //~| `Helper::T(_, _)` not covered + //~| NOTE `Helper::T(_, _)` not covered u } diff --git a/tests/ui/empty/empty-never-array.stderr b/tests/ui/empty/empty-never-array.stderr index f9f39a6371e..ee04ff162a4 100644 --- a/tests/ui/empty/empty-never-array.stderr +++ b/tests/ui/empty/empty-never-array.stderr @@ -1,5 +1,5 @@ error[E0005]: refutable pattern in local binding - --> $DIR/empty-never-array.rs:10:9 + --> $DIR/empty-never-array.rs:12:9 | LL | let Helper::U(u) = Helper::T(t, []); | ^^^^^^^^^^^^ pattern `Helper::T(_, _)` not covered @@ -7,7 +7,7 @@ LL | let Helper::U(u) = Helper::T(t, []); = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html note: `Helper` defined here - --> $DIR/empty-never-array.rs:3:6 + --> $DIR/empty-never-array.rs:5:6 | LL | enum Helper { | ^^^^^^ diff --git a/tests/ui/enum-discriminant/discriminant-overflow.rs b/tests/ui/enum-discriminant/discriminant-overflow.rs index 774ced93c17..aa3f4c13c4e 100644 --- a/tests/ui/enum-discriminant/discriminant-overflow.rs +++ b/tests/ui/enum-discriminant/discriminant-overflow.rs @@ -1,8 +1,9 @@ // Issue 23030: Detect overflowing discriminant - // See also run-pass/discrim-explicit-23030.rs where the suggested // workaround is tested. +//@ dont-require-annotations: NOTE + fn f_i8() { #[repr(i8)] enum A { @@ -42,7 +43,7 @@ fn f_u16() { Ok = u16::MAX - 1, Ok2, OhNo, //~ ERROR enum discriminant overflowed [E0370] - //~| overflowed on value after 65535 + //~| NOTE overflowed on value after 65535 } let x = A::Ok; @@ -54,7 +55,7 @@ fn f_i32() { Ok = i32::MAX - 1, Ok2, OhNo, //~ ERROR enum discriminant overflowed [E0370] - //~| overflowed on value after 2147483647 + //~| NOTE overflowed on value after 2147483647 } let x = A::Ok; @@ -66,7 +67,7 @@ fn f_u32() { Ok = u32::MAX - 1, Ok2, OhNo, //~ ERROR enum discriminant overflowed [E0370] - //~| overflowed on value after 4294967295 + //~| NOTE overflowed on value after 4294967295 } let x = A::Ok; @@ -78,7 +79,7 @@ fn f_i64() { Ok = i64::MAX - 1, Ok2, OhNo, //~ ERROR enum discriminant overflowed [E0370] - //~| overflowed on value after 9223372036854775807 + //~| NOTE overflowed on value after 9223372036854775807 } let x = A::Ok; @@ -90,7 +91,7 @@ fn f_u64() { Ok = u64::MAX - 1, Ok2, OhNo, //~ ERROR enum discriminant overflowed [E0370] - //~| overflowed on value after 18446744073709551615 + //~| NOTE overflowed on value after 18446744073709551615 } let x = A::Ok; diff --git a/tests/ui/enum-discriminant/discriminant-overflow.stderr b/tests/ui/enum-discriminant/discriminant-overflow.stderr index 2ecc1839f57..2662ddb2b93 100644 --- a/tests/ui/enum-discriminant/discriminant-overflow.stderr +++ b/tests/ui/enum-discriminant/discriminant-overflow.stderr @@ -1,5 +1,5 @@ error[E0370]: enum discriminant overflowed - --> $DIR/discriminant-overflow.rs:11:9 + --> $DIR/discriminant-overflow.rs:12:9 | LL | OhNo, | ^^^^ overflowed on value after 127 @@ -7,7 +7,7 @@ LL | OhNo, = note: explicitly set `OhNo = -128` if that is desired outcome error[E0370]: enum discriminant overflowed - --> $DIR/discriminant-overflow.rs:22:9 + --> $DIR/discriminant-overflow.rs:23:9 | LL | OhNo, | ^^^^ overflowed on value after 255 @@ -15,7 +15,7 @@ LL | OhNo, = note: explicitly set `OhNo = 0` if that is desired outcome error[E0370]: enum discriminant overflowed - --> $DIR/discriminant-overflow.rs:33:9 + --> $DIR/discriminant-overflow.rs:34:9 | LL | OhNo, | ^^^^ overflowed on value after 32767 @@ -23,7 +23,7 @@ LL | OhNo, = note: explicitly set `OhNo = -32768` if that is desired outcome error[E0370]: enum discriminant overflowed - --> $DIR/discriminant-overflow.rs:44:9 + --> $DIR/discriminant-overflow.rs:45:9 | LL | OhNo, | ^^^^ overflowed on value after 65535 @@ -31,7 +31,7 @@ LL | OhNo, = note: explicitly set `OhNo = 0` if that is desired outcome error[E0370]: enum discriminant overflowed - --> $DIR/discriminant-overflow.rs:56:9 + --> $DIR/discriminant-overflow.rs:57:9 | LL | OhNo, | ^^^^ overflowed on value after 2147483647 @@ -39,7 +39,7 @@ LL | OhNo, = note: explicitly set `OhNo = -2147483648` if that is desired outcome error[E0370]: enum discriminant overflowed - --> $DIR/discriminant-overflow.rs:68:9 + --> $DIR/discriminant-overflow.rs:69:9 | LL | OhNo, | ^^^^ overflowed on value after 4294967295 @@ -47,7 +47,7 @@ LL | OhNo, = note: explicitly set `OhNo = 0` if that is desired outcome error[E0370]: enum discriminant overflowed - --> $DIR/discriminant-overflow.rs:80:9 + --> $DIR/discriminant-overflow.rs:81:9 | LL | OhNo, | ^^^^ overflowed on value after 9223372036854775807 @@ -55,7 +55,7 @@ LL | OhNo, = note: explicitly set `OhNo = -9223372036854775808` if that is desired outcome error[E0370]: enum discriminant overflowed - --> $DIR/discriminant-overflow.rs:92:9 + --> $DIR/discriminant-overflow.rs:93:9 | LL | OhNo, | ^^^^ overflowed on value after 18446744073709551615 diff --git a/tests/ui/error-codes/E0080.rs b/tests/ui/error-codes/E0080.rs index ea3264b61b3..55f45055f01 100644 --- a/tests/ui/error-codes/E0080.rs +++ b/tests/ui/error-codes/E0080.rs @@ -1,7 +1,8 @@ enum Enum { X = (1 << 500), //~ ERROR E0080 - //~| attempt to shift left by `500_i32`, which would overflow + //~| NOTE attempt to shift left by `500_i32`, which would overflow Y = (1 / 0) //~ ERROR E0080 + //~| NOTE attempt to divide `1_isize` by zero } fn main() { diff --git a/tests/ui/error-codes/E0106.rs b/tests/ui/error-codes/E0106.rs index cc3438727a8..c8030495628 100644 --- a/tests/ui/error-codes/E0106.rs +++ b/tests/ui/error-codes/E0106.rs @@ -1,3 +1,5 @@ +//@ dont-require-annotations: NOTE + struct Foo { x: &bool, //~^ ERROR E0106 @@ -16,10 +18,10 @@ struct Buzz<'a, 'b>(&'a str, &'b str); struct Quux { baz: Baz, //~^ ERROR E0106 - //~| expected named lifetime parameter + //~| NOTE expected named lifetime parameter buzz: Buzz, //~^ ERROR E0106 - //~| expected 2 lifetime parameters + //~| NOTE expected 2 lifetime parameters } fn main() { diff --git a/tests/ui/error-codes/E0106.stderr b/tests/ui/error-codes/E0106.stderr index d11a24f7768..97ae1df9873 100644 --- a/tests/ui/error-codes/E0106.stderr +++ b/tests/ui/error-codes/E0106.stderr @@ -1,5 +1,5 @@ error[E0106]: missing lifetime specifier - --> $DIR/E0106.rs:2:8 + --> $DIR/E0106.rs:4:8 | LL | x: &bool, | ^ expected named lifetime parameter @@ -11,7 +11,7 @@ LL ~ x: &'a bool, | error[E0106]: missing lifetime specifier - --> $DIR/E0106.rs:7:7 + --> $DIR/E0106.rs:9:7 | LL | B(&bool), | ^ expected named lifetime parameter @@ -24,7 +24,7 @@ LL ~ B(&'a bool), | error[E0106]: missing lifetime specifier - --> $DIR/E0106.rs:10:14 + --> $DIR/E0106.rs:12:14 | LL | type MyStr = &str; | ^ expected named lifetime parameter @@ -35,7 +35,7 @@ LL | type MyStr<'a> = &'a str; | ++++ ++ error[E0106]: missing lifetime specifier - --> $DIR/E0106.rs:17:10 + --> $DIR/E0106.rs:19:10 | LL | baz: Baz, | ^^^ expected named lifetime parameter @@ -47,7 +47,7 @@ LL ~ baz: Baz<'a>, | error[E0106]: missing lifetime specifiers - --> $DIR/E0106.rs:20:11 + --> $DIR/E0106.rs:22:11 | LL | buzz: Buzz, | ^^^^ expected 2 lifetime parameters diff --git a/tests/ui/error-codes/E0428.rs b/tests/ui/error-codes/E0428.rs index eb9594fb8b6..08393b009d5 100644 --- a/tests/ui/error-codes/E0428.rs +++ b/tests/ui/error-codes/E0428.rs @@ -1,4 +1,6 @@ -struct Bar; //~ previous definition of the type `Bar` here +//@ dont-require-annotations: NOTE + +struct Bar; //~ NOTE previous definition of the type `Bar` here struct Bar; //~ ERROR E0428 fn main () { diff --git a/tests/ui/error-codes/E0428.stderr b/tests/ui/error-codes/E0428.stderr index b5bb84e2e68..78f57066e26 100644 --- a/tests/ui/error-codes/E0428.stderr +++ b/tests/ui/error-codes/E0428.stderr @@ -1,5 +1,5 @@ error[E0428]: the name `Bar` is defined multiple times - --> $DIR/E0428.rs:2:1 + --> $DIR/E0428.rs:4:1 | LL | struct Bar; | ----------- previous definition of the type `Bar` here diff --git a/tests/ui/explicit/explicit-self-lifetime-mismatch.rs b/tests/ui/explicit/explicit-self-lifetime-mismatch.rs index a9a6f50fb8e..aa5e352b6eb 100644 --- a/tests/ui/explicit/explicit-self-lifetime-mismatch.rs +++ b/tests/ui/explicit/explicit-self-lifetime-mismatch.rs @@ -1,3 +1,5 @@ +//@ dont-require-annotations: NOTE + struct Foo<'a,'b> { x: &'a isize, y: &'b isize, @@ -7,13 +9,13 @@ impl<'a,'b> Foo<'a,'b> { fn bar(self: Foo<'b,'a> //~^ ERROR mismatched `self` parameter type - //~| expected struct `Foo<'a, 'b>` - //~| found struct `Foo<'b, 'a>` - //~| lifetime mismatch + //~| NOTE expected struct `Foo<'a, 'b>` + //~| NOTE found struct `Foo<'b, 'a>` + //~| NOTE lifetime mismatch //~| ERROR mismatched `self` parameter type - //~| expected struct `Foo<'a, 'b>` - //~| found struct `Foo<'b, 'a>` - //~| lifetime mismatch + //~| NOTE expected struct `Foo<'a, 'b>` + //~| NOTE found struct `Foo<'b, 'a>` + //~| NOTE lifetime mismatch ) {} } diff --git a/tests/ui/explicit/explicit-self-lifetime-mismatch.stderr b/tests/ui/explicit/explicit-self-lifetime-mismatch.stderr index d5ffa8f1b2f..a20901e8c74 100644 --- a/tests/ui/explicit/explicit-self-lifetime-mismatch.stderr +++ b/tests/ui/explicit/explicit-self-lifetime-mismatch.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched `self` parameter type - --> $DIR/explicit-self-lifetime-mismatch.rs:8:12 + --> $DIR/explicit-self-lifetime-mismatch.rs:10:12 | LL | Foo<'b,'a> | ^^^^^^^^^^ lifetime mismatch @@ -7,18 +7,18 @@ LL | Foo<'b,'a> = note: expected struct `Foo<'a, 'b>` found struct `Foo<'b, 'a>` note: the lifetime `'b` as defined here... - --> $DIR/explicit-self-lifetime-mismatch.rs:6:9 + --> $DIR/explicit-self-lifetime-mismatch.rs:8:9 | LL | impl<'a,'b> Foo<'a,'b> { | ^^ note: ...does not necessarily outlive the lifetime `'a` as defined here - --> $DIR/explicit-self-lifetime-mismatch.rs:6:6 + --> $DIR/explicit-self-lifetime-mismatch.rs:8:6 | LL | impl<'a,'b> Foo<'a,'b> { | ^^ error[E0308]: mismatched `self` parameter type - --> $DIR/explicit-self-lifetime-mismatch.rs:8:12 + --> $DIR/explicit-self-lifetime-mismatch.rs:10:12 | LL | Foo<'b,'a> | ^^^^^^^^^^ lifetime mismatch @@ -26,12 +26,12 @@ LL | Foo<'b,'a> = note: expected struct `Foo<'a, 'b>` found struct `Foo<'b, 'a>` note: the lifetime `'a` as defined here... - --> $DIR/explicit-self-lifetime-mismatch.rs:6:6 + --> $DIR/explicit-self-lifetime-mismatch.rs:8:6 | LL | impl<'a,'b> Foo<'a,'b> { | ^^ note: ...does not necessarily outlive the lifetime `'b` as defined here - --> $DIR/explicit-self-lifetime-mismatch.rs:6:9 + --> $DIR/explicit-self-lifetime-mismatch.rs:8:9 | LL | impl<'a,'b> Foo<'a,'b> { | ^^ diff --git a/tests/ui/expr/if/if-branch-types.rs b/tests/ui/expr/if/if-branch-types.rs index c125ba30606..d6da3ee7193 100644 --- a/tests/ui/expr/if/if-branch-types.rs +++ b/tests/ui/expr/if/if-branch-types.rs @@ -1,5 +1,6 @@ fn main() { let x = if true { 10i32 } else { 10u32 }; //~^ ERROR `if` and `else` have incompatible types - //~| expected `i32`, found `u32` + //~| NOTE expected `i32`, found `u32` + //~| NOTE expected because of this } diff --git a/tests/ui/expr/if/if-without-else-result.rs b/tests/ui/expr/if/if-without-else-result.rs index 95604758a6b..29aa3d3f626 100644 --- a/tests/ui/expr/if/if-without-else-result.rs +++ b/tests/ui/expr/if/if-without-else-result.rs @@ -1,6 +1,8 @@ +//@ dont-require-annotations: NOTE + fn main() { let a = if true { true }; //~^ ERROR `if` may be missing an `else` clause [E0317] - //~| expected `bool`, found `()` + //~| NOTE expected `bool`, found `()` println!("{}", a); } diff --git a/tests/ui/expr/if/if-without-else-result.stderr b/tests/ui/expr/if/if-without-else-result.stderr index 4eaa0393496..d0a0981e2bd 100644 --- a/tests/ui/expr/if/if-without-else-result.stderr +++ b/tests/ui/expr/if/if-without-else-result.stderr @@ -1,5 +1,5 @@ error[E0317]: `if` may be missing an `else` clause - --> $DIR/if-without-else-result.rs:2:13 + --> $DIR/if-without-else-result.rs:4:13 | LL | let a = if true { true }; | ^^^^^^^^^^----^^ diff --git a/tests/ui/expr/if/issue-4201.rs b/tests/ui/expr/if/issue-4201.rs index 59c465b9e14..b456673b3c8 100644 --- a/tests/ui/expr/if/issue-4201.rs +++ b/tests/ui/expr/if/issue-4201.rs @@ -1,9 +1,11 @@ +//@ dont-require-annotations: NOTE + fn main() { let a = if true { 0 } else if false { //~^ ERROR `if` may be missing an `else` clause -//~| expected integer, found `()` +//~| NOTE expected integer, found `()` 1 }; } diff --git a/tests/ui/expr/if/issue-4201.stderr b/tests/ui/expr/if/issue-4201.stderr index c761d0b8553..4f5462c0372 100644 --- a/tests/ui/expr/if/issue-4201.stderr +++ b/tests/ui/expr/if/issue-4201.stderr @@ -1,5 +1,5 @@ error[E0317]: `if` may be missing an `else` clause - --> $DIR/issue-4201.rs:4:12 + --> $DIR/issue-4201.rs:6:12 | LL | } else if false { | ____________^ diff --git a/tests/ui/feature-gates/feature-gate-cfg-target-thread-local.rs b/tests/ui/feature-gates/feature-gate-cfg-target-thread-local.rs index 131a10ea03b..a9d4f6fe04f 100644 --- a/tests/ui/feature-gates/feature-gate-cfg-target-thread-local.rs +++ b/tests/ui/feature-gates/feature-gate-cfg-target-thread-local.rs @@ -7,7 +7,7 @@ extern crate cfg_target_thread_local; extern "C" { #[cfg_attr(target_thread_local, thread_local)] - //~^ `cfg(target_thread_local)` is experimental and subject to change + //~^ ERROR `cfg(target_thread_local)` is experimental and subject to change static FOO: u32; } diff --git a/tests/ui/fn/fn-item-type.rs b/tests/ui/fn/fn-item-type.rs index c094a34b207..c4c090bfda7 100644 --- a/tests/ui/fn/fn-item-type.rs +++ b/tests/ui/fn/fn-item-type.rs @@ -1,6 +1,8 @@ // Test that the types of distinct fn items are not compatible by // default. See also `run-pass/fn-item-type-*.rs`. +//@ dont-require-annotations: NOTE + fn foo(x: isize) -> isize { x * 2 } @@ -21,31 +23,31 @@ impl Foo for T { fn main() { eq(foo::, bar::); //~^ ERROR mismatched types - //~| expected fn item `fn(_) -> _ {foo::}` - //~| found fn item `fn(_) -> _ {bar::}` - //~| expected fn item, found a different fn item - //~| different fn items have unique types, even if their signatures are the same + //~| NOTE expected fn item `fn(_) -> _ {foo::}` + //~| NOTE found fn item `fn(_) -> _ {bar::}` + //~| NOTE expected fn item, found a different fn item + //~| NOTE different fn items have unique types, even if their signatures are the same eq(foo::, foo::); //~^ ERROR mismatched types - //~| expected `u8`, found `i8` - //~| different fn items have unique types, even if their signatures are the same + //~| NOTE expected `u8`, found `i8` + //~| NOTE different fn items have unique types, even if their signatures are the same eq(bar::, bar::>); //~^ ERROR mismatched types - //~| found fn item `fn(_) -> _ {bar::>}` - //~| expected `String`, found `Vec` + //~| NOTE found fn item `fn(_) -> _ {bar::>}` + //~| NOTE expected `String`, found `Vec` // Make sure we distinguish between trait methods correctly. eq(::foo, ::foo); //~^ ERROR mismatched types - //~| expected `u8`, found `u16` - //~| different fn items have unique types, even if their signatures are the same + //~| NOTE expected `u8`, found `u16` + //~| NOTE different fn items have unique types, even if their signatures are the same eq(foo::, bar:: as fn(isize) -> isize); //~^ ERROR mismatched types - //~| found fn pointer `fn(_) -> _` - //~| expected fn item, found fn pointer + //~| NOTE found fn pointer `fn(_) -> _` + //~| NOTE expected fn item, found fn pointer eq(foo:: as fn(isize) -> isize, bar::); // ok! } diff --git a/tests/ui/fn/fn-item-type.stderr b/tests/ui/fn/fn-item-type.stderr index 5cc529543d2..ea202f96a8e 100644 --- a/tests/ui/fn/fn-item-type.stderr +++ b/tests/ui/fn/fn-item-type.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/fn-item-type.rs:22:19 + --> $DIR/fn-item-type.rs:24:19 | LL | eq(foo::, bar::); | -- --------- ^^^^^^^^^ expected fn item, found a different fn item @@ -11,7 +11,7 @@ LL | eq(foo::, bar::); found fn item `fn(_) -> _ {bar::}` = note: different fn items have unique types, even if their signatures are the same note: function defined here - --> $DIR/fn-item-type.rs:11:4 + --> $DIR/fn-item-type.rs:13:4 | LL | fn eq(x: T, y: T) {} | ^^ - ---- ---- this parameter needs to match the fn item type of `x` @@ -21,7 +21,7 @@ LL | fn eq(x: T, y: T) {} = help: consider casting both fn items to fn pointers using `as fn(isize) -> isize` error[E0308]: mismatched types - --> $DIR/fn-item-type.rs:29:19 + --> $DIR/fn-item-type.rs:31:19 | LL | eq(foo::, foo::); | -- --------- ^^^^^^^^^ expected `u8`, found `i8` @@ -33,7 +33,7 @@ LL | eq(foo::, foo::); found fn item `fn(_) -> _ {foo::}` = note: different fn items have unique types, even if their signatures are the same note: function defined here - --> $DIR/fn-item-type.rs:11:4 + --> $DIR/fn-item-type.rs:13:4 | LL | fn eq(x: T, y: T) {} | ^^ - ---- ---- this parameter needs to match the fn item type of `x` @@ -43,7 +43,7 @@ LL | fn eq(x: T, y: T) {} = help: consider casting both fn items to fn pointers using `as fn(isize) -> isize` error[E0308]: mismatched types - --> $DIR/fn-item-type.rs:34:23 + --> $DIR/fn-item-type.rs:36:23 | LL | eq(bar::, bar::>); | -- ------------- ^^^^^^^^^^^^^^ expected `String`, found `Vec` @@ -55,7 +55,7 @@ LL | eq(bar::, bar::>); found fn item `fn(_) -> _ {bar::>}` = note: different fn items have unique types, even if their signatures are the same note: function defined here - --> $DIR/fn-item-type.rs:11:4 + --> $DIR/fn-item-type.rs:13:4 | LL | fn eq(x: T, y: T) {} | ^^ - ---- ---- this parameter needs to match the fn item type of `x` @@ -65,7 +65,7 @@ LL | fn eq(x: T, y: T) {} = help: consider casting both fn items to fn pointers using `as fn(isize) -> isize` error[E0308]: mismatched types - --> $DIR/fn-item-type.rs:40:26 + --> $DIR/fn-item-type.rs:42:26 | LL | eq(::foo, ::foo); | -- ---------------- ^^^^^^^^^^^^^^^^^ expected `u8`, found `u16` @@ -77,7 +77,7 @@ LL | eq(::foo, ::foo); found fn item `fn() {::foo}` = note: different fn items have unique types, even if their signatures are the same note: function defined here - --> $DIR/fn-item-type.rs:11:4 + --> $DIR/fn-item-type.rs:13:4 | LL | fn eq(x: T, y: T) {} | ^^ - ---- ---- this parameter needs to match the fn item type of `x` @@ -87,7 +87,7 @@ LL | fn eq(x: T, y: T) {} = help: consider casting both fn items to fn pointers using `as fn()` error[E0308]: mismatched types - --> $DIR/fn-item-type.rs:45:19 + --> $DIR/fn-item-type.rs:47:19 | LL | eq(foo::, bar:: as fn(isize) -> isize); | -- --------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected fn item, found fn pointer @@ -99,7 +99,7 @@ LL | eq(foo::, bar:: as fn(isize) -> isize); found fn pointer `fn(_) -> _` = help: consider casting the fn item to a fn pointer: `foo:: as fn(isize) -> isize` note: function defined here - --> $DIR/fn-item-type.rs:11:4 + --> $DIR/fn-item-type.rs:13:4 | LL | fn eq(x: T, y: T) {} | ^^ - ---- ---- this parameter needs to match the fn item type of `x` diff --git a/tests/ui/fn/fn-pointer-mismatch.rs b/tests/ui/fn/fn-pointer-mismatch.rs index 1c50d8b0f8b..3854c8eab68 100644 --- a/tests/ui/fn/fn-pointer-mismatch.rs +++ b/tests/ui/fn/fn-pointer-mismatch.rs @@ -1,3 +1,5 @@ +//@ dont-require-annotations: NOTE + fn foo(x: u32) -> u32 { x * 2 } @@ -10,7 +12,7 @@ fn bar(x: u32) -> u32 { fn foobar(n: u32) -> u32 { let g = if n % 2 == 0 { &foo } else { &bar }; //~^ ERROR `if` and `else` have incompatible types - //~| different fn items have unique types, even if their signatures are the same + //~| NOTE different fn items have unique types, even if their signatures are the same g(n) } @@ -22,33 +24,33 @@ fn main() { let mut a = foo; a = bar; //~^ ERROR mismatched types - //~| expected fn item `fn(_) -> _ {foo}` - //~| found fn item `fn(_) -> _ {bar}` - //~| different fn items have unique types, even if their signatures are the same + //~| NOTE expected fn item `fn(_) -> _ {foo}` + //~| NOTE found fn item `fn(_) -> _ {bar}` + //~| NOTE different fn items have unique types, even if their signatures are the same // display note even when boxed let mut b = Box::new(foo); b = Box::new(bar); //~^ ERROR mismatched types - //~| different fn items have unique types, even if their signatures are the same + //~| NOTE different fn items have unique types, even if their signatures are the same // suggest removing reference let c: fn(u32) -> u32 = &foo; //~^ ERROR mismatched types - //~| expected fn pointer `fn(_) -> _` - //~| found reference `&fn(_) -> _ {foo}` + //~| NOTE expected fn pointer `fn(_) -> _` + //~| NOTE found reference `&fn(_) -> _ {foo}` // suggest using reference let d: &fn(u32) -> u32 = foo; //~^ ERROR mismatched types - //~| expected reference `&fn(_) -> _` - //~| found fn item `fn(_) -> _ {foo}` + //~| NOTE expected reference `&fn(_) -> _` + //~| NOTE found fn item `fn(_) -> _ {foo}` // suggest casting with reference let e: &fn(u32) -> u32 = &foo; //~^ ERROR mismatched types - //~| expected reference `&fn(_) -> _` - //~| found reference `&fn(_) -> _ {foo}` + //~| NOTE expected reference `&fn(_) -> _` + //~| NOTE found reference `&fn(_) -> _ {foo}` // OK let mut z: fn(u32) -> u32 = foo as fn(u32) -> u32; diff --git a/tests/ui/fn/fn-pointer-mismatch.stderr b/tests/ui/fn/fn-pointer-mismatch.stderr index 051eb945467..87a2e39913d 100644 --- a/tests/ui/fn/fn-pointer-mismatch.stderr +++ b/tests/ui/fn/fn-pointer-mismatch.stderr @@ -1,5 +1,5 @@ error[E0308]: `if` and `else` have incompatible types - --> $DIR/fn-pointer-mismatch.rs:11:43 + --> $DIR/fn-pointer-mismatch.rs:13:43 | LL | let g = if n % 2 == 0 { &foo } else { &bar }; | ---- ^^^^ expected `&fn(u32) -> u32 {foo}`, found `&fn(u32) -> u32 {bar}` @@ -12,7 +12,7 @@ LL | let g = if n % 2 == 0 { &foo } else { &bar }; = help: consider casting both fn items to fn pointers using `as fn(u32) -> u32` error[E0308]: mismatched types - --> $DIR/fn-pointer-mismatch.rs:23:9 + --> $DIR/fn-pointer-mismatch.rs:25:9 | LL | let mut a = foo; | --- expected due to this value @@ -25,7 +25,7 @@ LL | a = bar; = help: consider casting both fn items to fn pointers using `as fn(u32) -> u32` error[E0308]: mismatched types - --> $DIR/fn-pointer-mismatch.rs:31:18 + --> $DIR/fn-pointer-mismatch.rs:33:18 | LL | b = Box::new(bar); | -------- ^^^ expected fn item, found a different fn item @@ -40,7 +40,7 @@ note: associated function defined here = help: consider casting both fn items to fn pointers using `as fn(u32) -> u32` error[E0308]: mismatched types - --> $DIR/fn-pointer-mismatch.rs:36:29 + --> $DIR/fn-pointer-mismatch.rs:38:29 | LL | let c: fn(u32) -> u32 = &foo; | -------------- ^^^^ expected fn pointer, found `&fn(u32) -> u32 {foo}` @@ -56,7 +56,7 @@ LL + let c: fn(u32) -> u32 = foo; | error[E0308]: mismatched types - --> $DIR/fn-pointer-mismatch.rs:42:30 + --> $DIR/fn-pointer-mismatch.rs:44:30 | LL | let d: &fn(u32) -> u32 = foo; | --------------- ^^^ expected `&fn(u32) -> u32`, found fn item @@ -71,7 +71,7 @@ LL | let d: &fn(u32) -> u32 = &foo; | + error[E0308]: mismatched types - --> $DIR/fn-pointer-mismatch.rs:48:30 + --> $DIR/fn-pointer-mismatch.rs:50:30 | LL | let e: &fn(u32) -> u32 = &foo; | --------------- ^^^^ expected `&fn(u32) -> u32`, found `&fn(u32) -> u32 {foo}` diff --git a/tests/ui/fn/fn-trait-formatting.rs b/tests/ui/fn/fn-trait-formatting.rs index 61a8791ab1f..be74d1ca9be 100644 --- a/tests/ui/fn/fn-trait-formatting.rs +++ b/tests/ui/fn/fn-trait-formatting.rs @@ -1,20 +1,20 @@ -fn needs_fn(x: F) where F: Fn(isize) -> isize {} - +//@ dont-require-annotations: NOTE +fn needs_fn(x: F) where F: Fn(isize) -> isize {} fn main() { let _: () = Box::new(|_: isize| {}) as Box; //~^ ERROR mismatched types - //~| expected unit type `()` - //~| found struct `Box` + //~| NOTE expected unit type `()` + //~| NOTE found struct `Box` let _: () = Box::new(|_: isize, isize| {}) as Box; //~^ ERROR mismatched types - //~| expected unit type `()` - //~| found struct `Box` + //~| NOTE expected unit type `()` + //~| NOTE found struct `Box` let _: () = Box::new(|| -> isize { unimplemented!() }) as Box isize>; //~^ ERROR mismatched types - //~| expected unit type `()` - //~| found struct `Box isize>` + //~| NOTE expected unit type `()` + //~| NOTE found struct `Box isize>` needs_fn(1); //~^ ERROR expected a `Fn(isize)` closure, found `{integer}` diff --git a/tests/ui/fn/fn-trait-formatting.stderr b/tests/ui/fn/fn-trait-formatting.stderr index 9fdef49c5ef..bfd86106bf9 100644 --- a/tests/ui/fn/fn-trait-formatting.stderr +++ b/tests/ui/fn/fn-trait-formatting.stderr @@ -49,7 +49,7 @@ LL | needs_fn(1); | = help: the trait `Fn(isize)` is not implemented for `{integer}` note: required by a bound in `needs_fn` - --> $DIR/fn-trait-formatting.rs:1:31 + --> $DIR/fn-trait-formatting.rs:3:31 | LL | fn needs_fn(x: F) where F: Fn(isize) -> isize {} | ^^^^^^^^^^^^^^^^^^ required by this bound in `needs_fn` diff --git a/tests/ui/foreign/issue-91370-foreign-fn-block-impl.rs b/tests/ui/foreign/issue-91370-foreign-fn-block-impl.rs index 23e08e01e6a..5317531cecd 100644 --- a/tests/ui/foreign/issue-91370-foreign-fn-block-impl.rs +++ b/tests/ui/foreign/issue-91370-foreign-fn-block-impl.rs @@ -1,10 +1,11 @@ // Regression test for issue #91370. extern "C" { - //~^ `extern` blocks define existing foreign functions + //~^ NOTE `extern` blocks define existing foreign functions fn f() { //~^ ERROR incorrect function inside `extern` block - //~| cannot have a body + //~| NOTE cannot have a body + //~| NOTE for more information, visit https://doc.rust-lang.org/std/keyword.extern.html impl Copy for u8 {} } } diff --git a/tests/ui/foreign/issue-91370-foreign-fn-block-impl.stderr b/tests/ui/foreign/issue-91370-foreign-fn-block-impl.stderr index 155fdf9d09a..ad6aff5d8c1 100644 --- a/tests/ui/foreign/issue-91370-foreign-fn-block-impl.stderr +++ b/tests/ui/foreign/issue-91370-foreign-fn-block-impl.stderr @@ -8,9 +8,7 @@ LL | fn f() { | ________^___- | | | | | cannot have a body -LL | | -LL | | -LL | | impl Copy for u8 {} +... | LL | | } | |_____- help: remove the invalid body: `;` | diff --git a/tests/ui/fully-qualified-type/fully-qualified-type-name2.rs b/tests/ui/fully-qualified-type/fully-qualified-type-name2.rs index f26d3be6630..983d694c440 100644 --- a/tests/ui/fully-qualified-type/fully-qualified-type-name2.rs +++ b/tests/ui/fully-qualified-type/fully-qualified-type-name2.rs @@ -1,5 +1,7 @@ // Test that we use fully-qualified type names in error messages. +//@ dont-require-annotations: NOTE + mod x { pub enum Foo { } } @@ -11,7 +13,7 @@ mod y { fn bar(x: x::Foo) -> y::Foo { return x; //~^ ERROR mismatched types - //~| expected `y::Foo`, found `x::Foo` + //~| NOTE expected `y::Foo`, found `x::Foo` } fn main() { diff --git a/tests/ui/fully-qualified-type/fully-qualified-type-name2.stderr b/tests/ui/fully-qualified-type/fully-qualified-type-name2.stderr index af716916548..90e54dfea2f 100644 --- a/tests/ui/fully-qualified-type/fully-qualified-type-name2.stderr +++ b/tests/ui/fully-qualified-type/fully-qualified-type-name2.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/fully-qualified-type-name2.rs:12:12 + --> $DIR/fully-qualified-type-name2.rs:14:12 | LL | fn bar(x: x::Foo) -> y::Foo { | ------ expected `y::Foo` because of return type @@ -8,12 +8,12 @@ LL | return x; | = note: `x::Foo` and `y::Foo` have similar names, but are actually distinct types note: `x::Foo` is defined in module `crate::x` of the current crate - --> $DIR/fully-qualified-type-name2.rs:4:5 + --> $DIR/fully-qualified-type-name2.rs:6:5 | LL | pub enum Foo { } | ^^^^^^^^^^^^ note: `y::Foo` is defined in module `crate::y` of the current crate - --> $DIR/fully-qualified-type-name2.rs:8:5 + --> $DIR/fully-qualified-type-name2.rs:10:5 | LL | pub enum Foo { } | ^^^^^^^^^^^^ diff --git a/tests/ui/fully-qualified-type/fully-qualified-type-name4.rs b/tests/ui/fully-qualified-type/fully-qualified-type-name4.rs index 41f07bab809..4fb4bb314df 100644 --- a/tests/ui/fully-qualified-type/fully-qualified-type-name4.rs +++ b/tests/ui/fully-qualified-type/fully-qualified-type-name4.rs @@ -2,12 +2,12 @@ use std::option::Option; -fn bar(x: usize) -> Option { +fn bar(x: usize) -> Option { //~ NOTE expected `Option` because of return type return x; //~^ ERROR mismatched types - //~| expected enum `Option` - //~| found type `usize` - //~| expected `Option`, found `usize` + //~| NOTE expected enum `Option` + //~| NOTE found type `usize` + //~| NOTE expected `Option`, found `usize` } fn main() { diff --git a/tests/ui/generics/generic-type-params-name-repr.rs b/tests/ui/generics/generic-type-params-name-repr.rs index d60856b8904..bee8405a72c 100644 --- a/tests/ui/generics/generic-type-params-name-repr.rs +++ b/tests/ui/generics/generic-type-params-name-repr.rs @@ -1,3 +1,5 @@ +//@ dont-require-annotations: NOTE + use std::marker; struct A; @@ -12,40 +14,40 @@ fn main() { // Ensure that the printed type doesn't include the default type params... let _: Foo = (); //~^ ERROR mismatched types - //~| expected `Foo`, found `()` - //~| expected struct `Foo` - //~| found unit type `()` + //~| NOTE expected `Foo`, found `()` + //~| NOTE expected struct `Foo` + //~| NOTE found unit type `()` // ...even when they're present, but the same types as the defaults. let _: Foo = (); //~^ ERROR mismatched types - //~| expected `Foo`, found `()` - //~| expected struct `Foo` - //~| found unit type `()` + //~| NOTE expected `Foo`, found `()` + //~| NOTE expected struct `Foo` + //~| NOTE found unit type `()` // Including cases where the default is using previous type params. let _: HashMap = (); //~^ ERROR mismatched types - //~| expected `HashMap`, found `()` - //~| expected struct `HashMap` - //~| found unit type `()` + //~| NOTE expected `HashMap`, found `()` + //~| NOTE expected struct `HashMap` + //~| NOTE found unit type `()` let _: HashMap> = (); //~^ ERROR mismatched types - //~| expected `HashMap`, found `()` - //~| expected struct `HashMap` - //~| found unit type `()` + //~| NOTE expected `HashMap`, found `()` + //~| NOTE expected struct `HashMap` + //~| NOTE found unit type `()` // But not when there's a different type in between. let _: Foo = (); //~^ ERROR mismatched types - //~| expected `Foo`, found `()` - //~| expected struct `Foo` - //~| found unit type `()` + //~| NOTE expected `Foo`, found `()` + //~| NOTE expected struct `Foo` + //~| NOTE found unit type `()` // And don't print <> at all when there's just defaults. let _: Foo = (); //~^ ERROR mismatched types - //~| expected `Foo`, found `()` - //~| expected struct `Foo` - //~| found unit type `()` + //~| NOTE expected `Foo`, found `()` + //~| NOTE expected struct `Foo` + //~| NOTE found unit type `()` } diff --git a/tests/ui/generics/generic-type-params-name-repr.stderr b/tests/ui/generics/generic-type-params-name-repr.stderr index 946f14cc1c6..ab03e8182ab 100644 --- a/tests/ui/generics/generic-type-params-name-repr.stderr +++ b/tests/ui/generics/generic-type-params-name-repr.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/generic-type-params-name-repr.rs:13:25 + --> $DIR/generic-type-params-name-repr.rs:15:25 | LL | let _: Foo = (); | ---------- ^^ expected `Foo`, found `()` @@ -10,7 +10,7 @@ LL | let _: Foo = (); found unit type `()` error[E0308]: mismatched types - --> $DIR/generic-type-params-name-repr.rs:20:31 + --> $DIR/generic-type-params-name-repr.rs:22:31 | LL | let _: Foo = (); | ---------------- ^^ expected `Foo`, found `()` @@ -21,7 +21,7 @@ LL | let _: Foo = (); found unit type `()` error[E0308]: mismatched types - --> $DIR/generic-type-params-name-repr.rs:27:37 + --> $DIR/generic-type-params-name-repr.rs:29:37 | LL | let _: HashMap = (); | ---------------------- ^^ expected `HashMap`, found `()` @@ -32,7 +32,7 @@ LL | let _: HashMap = (); found unit type `()` error[E0308]: mismatched types - --> $DIR/generic-type-params-name-repr.rs:32:51 + --> $DIR/generic-type-params-name-repr.rs:34:51 | LL | let _: HashMap> = (); | ------------------------------------ ^^ expected `HashMap`, found `()` @@ -43,7 +43,7 @@ LL | let _: HashMap> = (); found unit type `()` error[E0308]: mismatched types - --> $DIR/generic-type-params-name-repr.rs:39:31 + --> $DIR/generic-type-params-name-repr.rs:41:31 | LL | let _: Foo = (); | ---------------- ^^ expected `Foo`, found `()` @@ -54,7 +54,7 @@ LL | let _: Foo = (); found unit type `()` error[E0308]: mismatched types - --> $DIR/generic-type-params-name-repr.rs:46:27 + --> $DIR/generic-type-params-name-repr.rs:48:27 | LL | let _: Foo = (); | ------------ ^^ expected `Foo`, found `()` diff --git a/tests/ui/generics/slightly-nice-generic-literal-messages.rs b/tests/ui/generics/slightly-nice-generic-literal-messages.rs index 268009f65a5..83c08e977b6 100644 --- a/tests/ui/generics/slightly-nice-generic-literal-messages.rs +++ b/tests/ui/generics/slightly-nice-generic-literal-messages.rs @@ -3,12 +3,12 @@ use std::marker; struct Foo(T, marker::PhantomData); fn main() { - match Foo(1.1, marker::PhantomData) { + match Foo(1.1, marker::PhantomData) { //~ NOTE this expression has type `Foo<{float}, _>` 1 => {} //~^ ERROR mismatched types - //~| expected struct `Foo<{float}, _>` - //~| found type `{integer}` - //~| expected `Foo<{float}, _>`, found integer + //~| NOTE expected struct `Foo<{float}, _>` + //~| NOTE found type `{integer}` + //~| NOTE expected `Foo<{float}, _>`, found integer } } diff --git a/tests/ui/impl-trait/equality.rs b/tests/ui/impl-trait/equality.rs index 828b5aac896..07fc4a5d41a 100644 --- a/tests/ui/impl-trait/equality.rs +++ b/tests/ui/impl-trait/equality.rs @@ -1,3 +1,5 @@ +//@ dont-require-annotations: NOTE + #![feature(specialization)] //~ WARN the feature `specialization` is incomplete trait Foo: Copy + ToString {} @@ -14,7 +16,7 @@ fn two(x: bool) -> impl Foo { } 0_u32 //~^ ERROR mismatched types - //~| expected `i32`, found `u32` + //~| NOTE expected `i32`, found `u32` } fn sum_to(n: u32) -> impl Foo { diff --git a/tests/ui/impl-trait/equality.stderr b/tests/ui/impl-trait/equality.stderr index 8106bab9878..424d56f67e0 100644 --- a/tests/ui/impl-trait/equality.stderr +++ b/tests/ui/impl-trait/equality.stderr @@ -1,5 +1,5 @@ warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/equality.rs:1:12 + --> $DIR/equality.rs:3:12 | LL | #![feature(specialization)] | ^^^^^^^^^^^^^^ @@ -9,7 +9,7 @@ LL | #![feature(specialization)] = note: `#[warn(incomplete_features)]` on by default error[E0308]: mismatched types - --> $DIR/equality.rs:15:5 + --> $DIR/equality.rs:17:5 | LL | fn two(x: bool) -> impl Foo { | -------- expected `i32` because of return type @@ -24,7 +24,7 @@ LL + 0_i32 | error[E0277]: cannot add `impl Foo` to `u32` - --> $DIR/equality.rs:24:11 + --> $DIR/equality.rs:26:11 | LL | n + sum_to(n - 1) | ^ no implementation for `u32 + impl Foo` diff --git a/tests/ui/impl-trait/equality2.rs b/tests/ui/impl-trait/equality2.rs index 2e325867da8..808c600ecb7 100644 --- a/tests/ui/impl-trait/equality2.rs +++ b/tests/ui/impl-trait/equality2.rs @@ -1,3 +1,5 @@ +//@ dont-require-annotations: NOTE + #![feature(specialization)] //~ WARN the feature `specialization` is incomplete trait Foo: Copy + ToString {} @@ -24,21 +26,21 @@ impl Leak for i32 { fn main() { let _: u32 = hide(0_u32); //~^ ERROR mismatched types - //~| expected type `u32` - //~| found opaque type `impl Foo` - //~| expected `u32`, found opaque type + //~| NOTE expected type `u32` + //~| NOTE found opaque type `impl Foo` + //~| NOTE expected `u32`, found opaque type let _: i32 = Leak::leak(hide(0_i32)); //~^ ERROR mismatched types - //~| expected type `i32` - //~| found associated type `::T` - //~| expected `i32`, found associated type + //~| NOTE expected type `i32` + //~| NOTE found associated type `::T` + //~| NOTE expected `i32`, found associated type let mut x = (hide(0_u32), hide(0_i32)); x = (x.1, //~^ ERROR mismatched types - //~| expected `u32`, found `i32` + //~| NOTE expected `u32`, found `i32` x.0); //~^ ERROR mismatched types - //~| expected `i32`, found `u32` + //~| NOTE expected `i32`, found `u32` } diff --git a/tests/ui/impl-trait/equality2.stderr b/tests/ui/impl-trait/equality2.stderr index 52f25d2458c..2fa7eb288ff 100644 --- a/tests/ui/impl-trait/equality2.stderr +++ b/tests/ui/impl-trait/equality2.stderr @@ -1,5 +1,5 @@ warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/equality2.rs:1:12 + --> $DIR/equality2.rs:3:12 | LL | #![feature(specialization)] | ^^^^^^^^^^^^^^ @@ -9,7 +9,7 @@ LL | #![feature(specialization)] = note: `#[warn(incomplete_features)]` on by default error[E0308]: mismatched types - --> $DIR/equality2.rs:25:18 + --> $DIR/equality2.rs:27:18 | LL | fn hide(x: T) -> impl Foo { | -------- the found opaque type @@ -23,7 +23,7 @@ LL | let _: u32 = hide(0_u32); found opaque type `impl Foo` error[E0308]: mismatched types - --> $DIR/equality2.rs:31:18 + --> $DIR/equality2.rs:33:18 | LL | fn hide(x: T) -> impl Foo { | -------- the found opaque type @@ -41,7 +41,7 @@ LL | fn hide(x: T) -> impl Foo { | +++++++++ error[E0308]: mismatched types - --> $DIR/equality2.rs:38:10 + --> $DIR/equality2.rs:40:10 | LL | fn hide(x: T) -> impl Foo { | -------- @@ -57,7 +57,7 @@ LL | x = (x.1, = note: distinct uses of `impl Trait` result in different opaque types error[E0308]: mismatched types - --> $DIR/equality2.rs:41:10 + --> $DIR/equality2.rs:43:10 | LL | fn hide(x: T) -> impl Foo { | -------- diff --git a/tests/ui/impl-trait/no-method-suggested-traits.rs b/tests/ui/impl-trait/no-method-suggested-traits.rs index 6fc96f27a67..5a9361310c3 100644 --- a/tests/ui/impl-trait/no-method-suggested-traits.rs +++ b/tests/ui/impl-trait/no-method-suggested-traits.rs @@ -1,4 +1,6 @@ //@ aux-build:no_method_suggested_traits.rs +//@ dont-require-annotations: HELP + extern crate no_method_suggested_traits; struct Foo; @@ -22,9 +24,9 @@ fn main() { 1u32.method(); //~^ ERROR no method named - //~|items from traits can only be used if the trait is in scope + //~| HELP items from traits can only be used if the trait is in scope std::rc::Rc::new(&mut Box::new(&1u32)).method(); - //~^items from traits can only be used if the trait is in scope + //~^ HELP items from traits can only be used if the trait is in scope //~| ERROR no method named `method` found for struct 'a'.method(); diff --git a/tests/ui/impl-trait/no-method-suggested-traits.stderr b/tests/ui/impl-trait/no-method-suggested-traits.stderr index 0a974668188..64202513ae2 100644 --- a/tests/ui/impl-trait/no-method-suggested-traits.stderr +++ b/tests/ui/impl-trait/no-method-suggested-traits.stderr @@ -1,5 +1,5 @@ error[E0599]: no method named `method` found for type `u32` in the current scope - --> $DIR/no-method-suggested-traits.rs:23:10 + --> $DIR/no-method-suggested-traits.rs:25:10 | LL | 1u32.method(); | ^^^^^^ @@ -21,7 +21,7 @@ LL | 1u32.method2(); | + error[E0599]: no method named `method` found for struct `Rc<&mut Box<&u32>>` in the current scope - --> $DIR/no-method-suggested-traits.rs:26:44 + --> $DIR/no-method-suggested-traits.rs:28:44 | LL | std::rc::Rc::new(&mut Box::new(&1u32)).method(); | ^^^^^^ @@ -43,7 +43,7 @@ LL | std::rc::Rc::new(&mut Box::new(&1u32)).method2(); | + error[E0599]: no method named `method` found for type `char` in the current scope - --> $DIR/no-method-suggested-traits.rs:30:9 + --> $DIR/no-method-suggested-traits.rs:32:9 | LL | fn method(&self) {} | ------ the method is available for `char` here @@ -62,7 +62,7 @@ LL | 'a'.method2(); | + error[E0599]: no method named `method` found for struct `Rc<&mut Box<&char>>` in the current scope - --> $DIR/no-method-suggested-traits.rs:32:43 + --> $DIR/no-method-suggested-traits.rs:34:43 | LL | std::rc::Rc::new(&mut Box::new(&'a')).method(); | ^^^^^^ @@ -78,7 +78,7 @@ LL | std::rc::Rc::new(&mut Box::new(&'a')).method2(); | + error[E0599]: no method named `method` found for type `i32` in the current scope - --> $DIR/no-method-suggested-traits.rs:35:10 + --> $DIR/no-method-suggested-traits.rs:37:10 | LL | 1i32.method(); | ^^^^^^ @@ -99,7 +99,7 @@ LL | 1i32.method3(); | + error[E0599]: no method named `method` found for struct `Rc<&mut Box<&i32>>` in the current scope - --> $DIR/no-method-suggested-traits.rs:37:44 + --> $DIR/no-method-suggested-traits.rs:39:44 | LL | std::rc::Rc::new(&mut Box::new(&1i32)).method(); | ^^^^^^ @@ -115,7 +115,7 @@ LL | std::rc::Rc::new(&mut Box::new(&1i32)).method3(); | + error[E0599]: no method named `method` found for struct `Foo` in the current scope - --> $DIR/no-method-suggested-traits.rs:40:9 + --> $DIR/no-method-suggested-traits.rs:42:9 | LL | struct Foo; | ---------- method `method` not found for this struct @@ -131,7 +131,7 @@ LL | Foo.method(); candidate #4: `no_method_suggested_traits::qux::PrivPub` error[E0599]: no method named `method` found for struct `Rc<&mut Box<&Foo>>` in the current scope - --> $DIR/no-method-suggested-traits.rs:42:43 + --> $DIR/no-method-suggested-traits.rs:44:43 | LL | std::rc::Rc::new(&mut Box::new(&Foo)).method(); | ^^^^^^ method not found in `Rc<&mut Box<&Foo>>` @@ -144,85 +144,85 @@ LL | std::rc::Rc::new(&mut Box::new(&Foo)).method(); candidate #4: `no_method_suggested_traits::qux::PrivPub` error[E0599]: no method named `method2` found for type `u64` in the current scope - --> $DIR/no-method-suggested-traits.rs:45:10 + --> $DIR/no-method-suggested-traits.rs:47:10 | LL | 1u64.method2(); | ^^^^^^^ method not found in `u64` | = help: items from traits can only be used if the trait is implemented and in scope note: `foo::Bar` defines an item `method2`, perhaps you need to implement it - --> $DIR/no-method-suggested-traits.rs:8:5 + --> $DIR/no-method-suggested-traits.rs:10:5 | LL | pub trait Bar { | ^^^^^^^^^^^^^ error[E0599]: no method named `method2` found for struct `Rc<&mut Box<&u64>>` in the current scope - --> $DIR/no-method-suggested-traits.rs:47:44 + --> $DIR/no-method-suggested-traits.rs:49:44 | LL | std::rc::Rc::new(&mut Box::new(&1u64)).method2(); | ^^^^^^^ method not found in `Rc<&mut Box<&u64>>` | = help: items from traits can only be used if the trait is implemented and in scope note: `foo::Bar` defines an item `method2`, perhaps you need to implement it - --> $DIR/no-method-suggested-traits.rs:8:5 + --> $DIR/no-method-suggested-traits.rs:10:5 | LL | pub trait Bar { | ^^^^^^^^^^^^^ error[E0599]: no method named `method2` found for struct `no_method_suggested_traits::Foo` in the current scope - --> $DIR/no-method-suggested-traits.rs:50:37 + --> $DIR/no-method-suggested-traits.rs:52:37 | LL | no_method_suggested_traits::Foo.method2(); | ^^^^^^^ method not found in `Foo` | = help: items from traits can only be used if the trait is implemented and in scope note: `foo::Bar` defines an item `method2`, perhaps you need to implement it - --> $DIR/no-method-suggested-traits.rs:8:5 + --> $DIR/no-method-suggested-traits.rs:10:5 | LL | pub trait Bar { | ^^^^^^^^^^^^^ error[E0599]: no method named `method2` found for struct `Rc<&mut Box<&no_method_suggested_traits::Foo>>` in the current scope - --> $DIR/no-method-suggested-traits.rs:52:71 + --> $DIR/no-method-suggested-traits.rs:54:71 | LL | std::rc::Rc::new(&mut Box::new(&no_method_suggested_traits::Foo)).method2(); | ^^^^^^^ method not found in `Rc<&mut Box<&Foo>>` | = help: items from traits can only be used if the trait is implemented and in scope note: `foo::Bar` defines an item `method2`, perhaps you need to implement it - --> $DIR/no-method-suggested-traits.rs:8:5 + --> $DIR/no-method-suggested-traits.rs:10:5 | LL | pub trait Bar { | ^^^^^^^^^^^^^ error[E0599]: no method named `method2` found for enum `no_method_suggested_traits::Bar` in the current scope - --> $DIR/no-method-suggested-traits.rs:54:40 + --> $DIR/no-method-suggested-traits.rs:56:40 | LL | no_method_suggested_traits::Bar::X.method2(); | ^^^^^^^ method not found in `Bar` | = help: items from traits can only be used if the trait is implemented and in scope note: `foo::Bar` defines an item `method2`, perhaps you need to implement it - --> $DIR/no-method-suggested-traits.rs:8:5 + --> $DIR/no-method-suggested-traits.rs:10:5 | LL | pub trait Bar { | ^^^^^^^^^^^^^ error[E0599]: no method named `method2` found for struct `Rc<&mut Box<&no_method_suggested_traits::Bar>>` in the current scope - --> $DIR/no-method-suggested-traits.rs:56:74 + --> $DIR/no-method-suggested-traits.rs:58:74 | LL | std::rc::Rc::new(&mut Box::new(&no_method_suggested_traits::Bar::X)).method2(); | ^^^^^^^ method not found in `Rc<&mut Box<&Bar>>` | = help: items from traits can only be used if the trait is implemented and in scope note: `foo::Bar` defines an item `method2`, perhaps you need to implement it - --> $DIR/no-method-suggested-traits.rs:8:5 + --> $DIR/no-method-suggested-traits.rs:10:5 | LL | pub trait Bar { | ^^^^^^^^^^^^^ error[E0599]: no method named `method3` found for struct `Foo` in the current scope - --> $DIR/no-method-suggested-traits.rs:59:9 + --> $DIR/no-method-suggested-traits.rs:61:9 | LL | struct Foo; | ---------- method `method3` not found for this struct @@ -235,7 +235,7 @@ LL | Foo.method3(); candidate #1: `PubPub` error[E0599]: no method named `method3` found for struct `Rc<&mut Box<&Foo>>` in the current scope - --> $DIR/no-method-suggested-traits.rs:61:43 + --> $DIR/no-method-suggested-traits.rs:63:43 | LL | std::rc::Rc::new(&mut Box::new(&Foo)).method3(); | ^^^^^^^ method not found in `Rc<&mut Box<&Foo>>` @@ -245,7 +245,7 @@ LL | std::rc::Rc::new(&mut Box::new(&Foo)).method3(); candidate #1: `PubPub` error[E0599]: no method named `method3` found for enum `Bar` in the current scope - --> $DIR/no-method-suggested-traits.rs:63:12 + --> $DIR/no-method-suggested-traits.rs:65:12 | LL | enum Bar { X } | -------- method `method3` not found for this enum @@ -258,7 +258,7 @@ LL | Bar::X.method3(); candidate #1: `PubPub` error[E0599]: no method named `method3` found for struct `Rc<&mut Box<&Bar>>` in the current scope - --> $DIR/no-method-suggested-traits.rs:65:46 + --> $DIR/no-method-suggested-traits.rs:67:46 | LL | std::rc::Rc::new(&mut Box::new(&Bar::X)).method3(); | ^^^^^^^ method not found in `Rc<&mut Box<&Bar>>` @@ -268,37 +268,37 @@ LL | std::rc::Rc::new(&mut Box::new(&Bar::X)).method3(); candidate #1: `PubPub` error[E0599]: no method named `method3` found for type `usize` in the current scope - --> $DIR/no-method-suggested-traits.rs:69:13 + --> $DIR/no-method-suggested-traits.rs:71:13 | LL | 1_usize.method3(); | ^^^^^^^ method not found in `usize` error[E0599]: no method named `method3` found for struct `Rc<&mut Box<&usize>>` in the current scope - --> $DIR/no-method-suggested-traits.rs:70:47 + --> $DIR/no-method-suggested-traits.rs:72:47 | LL | std::rc::Rc::new(&mut Box::new(&1_usize)).method3(); | ^^^^^^^ method not found in `Rc<&mut Box<&usize>>` error[E0599]: no method named `method3` found for struct `no_method_suggested_traits::Foo` in the current scope - --> $DIR/no-method-suggested-traits.rs:71:37 + --> $DIR/no-method-suggested-traits.rs:73:37 | LL | no_method_suggested_traits::Foo.method3(); | ^^^^^^^ method not found in `Foo` error[E0599]: no method named `method3` found for struct `Rc<&mut Box<&no_method_suggested_traits::Foo>>` in the current scope - --> $DIR/no-method-suggested-traits.rs:72:71 + --> $DIR/no-method-suggested-traits.rs:74:71 | LL | std::rc::Rc::new(&mut Box::new(&no_method_suggested_traits::Foo)).method3(); | ^^^^^^^ method not found in `Rc<&mut Box<&Foo>>` error[E0599]: no method named `method3` found for enum `no_method_suggested_traits::Bar` in the current scope - --> $DIR/no-method-suggested-traits.rs:74:40 + --> $DIR/no-method-suggested-traits.rs:76:40 | LL | no_method_suggested_traits::Bar::X.method3(); | ^^^^^^^ method not found in `Bar` error[E0599]: no method named `method3` found for struct `Rc<&mut Box<&no_method_suggested_traits::Bar>>` in the current scope - --> $DIR/no-method-suggested-traits.rs:75:74 + --> $DIR/no-method-suggested-traits.rs:77:74 | LL | std::rc::Rc::new(&mut Box::new(&no_method_suggested_traits::Bar::X)).method3(); | ^^^^^^^ method not found in `Rc<&mut Box<&Bar>>` diff --git a/tests/ui/implied-bounds/sod_service_chain.rs b/tests/ui/implied-bounds/sod_service_chain.rs index 73dce2fce24..df1d430b37b 100644 --- a/tests/ui/implied-bounds/sod_service_chain.rs +++ b/tests/ui/implied-bounds/sod_service_chain.rs @@ -1,5 +1,7 @@ // Found in a crater run on #118553 +//@ dont-require-annotations: NOTE + pub trait Debug {} pub trait Service { @@ -30,16 +32,16 @@ impl> ServiceChainBuilder { //~^ ERROR the associated type //~| ERROR the associated type //~| ERROR the associated type - //~| the associated type - //~| the associated type - //~| the associated type + //~| NOTE the associated type + //~| NOTE the associated type + //~| NOTE the associated type //~| ERROR may not live long enough self, ) -> ServiceChainBuilder, NS> { //~^ ERROR the associated type //~| ERROR the associated type - //~| the associated type - //~| the associated type + //~| NOTE the associated type + //~| NOTE the associated type panic!(); } } diff --git a/tests/ui/implied-bounds/sod_service_chain.stderr b/tests/ui/implied-bounds/sod_service_chain.stderr index f5221fc1105..a3cc131d235 100644 --- a/tests/ui/implied-bounds/sod_service_chain.stderr +++ b/tests/ui/implied-bounds/sod_service_chain.stderr @@ -1,5 +1,5 @@ error[E0310]: the associated type `

::Error` may not live long enough - --> $DIR/sod_service_chain.rs:29:5 + --> $DIR/sod_service_chain.rs:31:5 | LL | / pub fn next>( ... | @@ -16,7 +16,7 @@ LL | ) -> ServiceChainBuilder, NS> where

:: | ++++++++++++++++++++++++++++++++++++ error[E0310]: the associated type `::Error` may not live long enough - --> $DIR/sod_service_chain.rs:29:5 + --> $DIR/sod_service_chain.rs:31:5 | LL | / pub fn next>( ... | @@ -33,7 +33,7 @@ LL | ) -> ServiceChainBuilder, NS> where :: | ++++++++++++++++++++++++++++++++++++ error[E0310]: the associated type `

::Error` may not live long enough - --> $DIR/sod_service_chain.rs:38:10 + --> $DIR/sod_service_chain.rs:40:10 | LL | ) -> ServiceChainBuilder, NS> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -47,7 +47,7 @@ LL | ) -> ServiceChainBuilder, NS> where

:: | ++++++++++++++++++++++++++++++++++++ error[E0310]: the associated type `::Error` may not live long enough - --> $DIR/sod_service_chain.rs:38:10 + --> $DIR/sod_service_chain.rs:40:10 | LL | ) -> ServiceChainBuilder, NS> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -61,7 +61,7 @@ LL | ) -> ServiceChainBuilder, NS> where :: | ++++++++++++++++++++++++++++++++++++ error[E0310]: the associated type `

::Error` may not live long enough - --> $DIR/sod_service_chain.rs:29:5 + --> $DIR/sod_service_chain.rs:31:5 | LL | / pub fn next>( ... | @@ -79,7 +79,7 @@ LL | ) -> ServiceChainBuilder, NS> where

:: | ++++++++++++++++++++++++++++++++++++ error[E0310]: the associated type `::Error` may not live long enough - --> $DIR/sod_service_chain.rs:29:5 + --> $DIR/sod_service_chain.rs:31:5 | LL | / pub fn next>( ... | diff --git a/tests/ui/imports/import.rs b/tests/ui/imports/import.rs index 3170dd2fae1..39a087c7a43 100644 --- a/tests/ui/imports/import.rs +++ b/tests/ui/imports/import.rs @@ -1,6 +1,8 @@ +//@ dont-require-annotations: NOTE + use zed::bar; use zed::baz; //~ ERROR unresolved import `zed::baz` [E0432] - //~| no `baz` in `zed` + //~| NOTE no `baz` in `zed` //~| HELP a similar name exists in the module //~| SUGGESTION bar @@ -8,7 +10,7 @@ use zed::baz; //~ ERROR unresolved import `zed::baz` [E0432] mod zed { pub fn bar() { println!("bar"); } use foo; //~ ERROR unresolved import `foo` [E0432] - //~^ no `foo` in the root + //~^ NOTE no `foo` in the root } fn main() { diff --git a/tests/ui/imports/import.stderr b/tests/ui/imports/import.stderr index 797712e2db9..4dae164991b 100644 --- a/tests/ui/imports/import.stderr +++ b/tests/ui/imports/import.stderr @@ -1,5 +1,5 @@ error[E0432]: unresolved import `zed::baz` - --> $DIR/import.rs:2:5 + --> $DIR/import.rs:4:5 | LL | use zed::baz; | ^^^^^--- @@ -8,19 +8,19 @@ LL | use zed::baz; | no `baz` in `zed` error[E0432]: unresolved import `foo` - --> $DIR/import.rs:10:9 + --> $DIR/import.rs:12:9 | LL | use foo; | ^^^ no `foo` in the root error[E0603]: unresolved item import `foo` is private - --> $DIR/import.rs:15:10 + --> $DIR/import.rs:17:10 | LL | zed::foo(); | ^^^ private unresolved item import | note: the unresolved item import `foo` is defined here - --> $DIR/import.rs:10:9 + --> $DIR/import.rs:12:9 | LL | use foo; | ^^^ diff --git a/tests/ui/imports/issue-19498.rs b/tests/ui/imports/issue-19498.rs index 5fe6742f55e..5b9ce85fd8b 100644 --- a/tests/ui/imports/issue-19498.rs +++ b/tests/ui/imports/issue-19498.rs @@ -1,13 +1,15 @@ +//@ dont-require-annotations: NOTE + use self::A; use self::B; mod A {} //~ ERROR the name `A` is defined multiple times -//~| `A` redefined here +//~| NOTE `A` redefined here pub mod B {} //~ ERROR the name `B` is defined multiple times -//~| `B` redefined here +//~| NOTE `B` redefined here mod C { use C::D; mod D {} //~ ERROR the name `D` is defined multiple times - //~| `D` redefined here + //~| NOTE `D` redefined here } fn main() {} diff --git a/tests/ui/imports/issue-19498.stderr b/tests/ui/imports/issue-19498.stderr index 69bdb67d389..eb0d68a24c9 100644 --- a/tests/ui/imports/issue-19498.stderr +++ b/tests/ui/imports/issue-19498.stderr @@ -1,5 +1,5 @@ error[E0255]: the name `A` is defined multiple times - --> $DIR/issue-19498.rs:3:1 + --> $DIR/issue-19498.rs:5:1 | LL | use self::A; | ------- previous import of the module `A` here @@ -14,7 +14,7 @@ LL | use self::A as OtherA; | +++++++++ error[E0255]: the name `B` is defined multiple times - --> $DIR/issue-19498.rs:5:1 + --> $DIR/issue-19498.rs:7:1 | LL | use self::B; | ------- previous import of the module `B` here @@ -29,7 +29,7 @@ LL | use self::B as OtherB; | +++++++++ error[E0255]: the name `D` is defined multiple times - --> $DIR/issue-19498.rs:9:5 + --> $DIR/issue-19498.rs:11:5 | LL | use C::D; | ---- previous import of the module `D` here diff --git a/tests/ui/imports/issue-24081.rs b/tests/ui/imports/issue-24081.rs index 10983ce11b5..561bbb067b8 100644 --- a/tests/ui/imports/issue-24081.rs +++ b/tests/ui/imports/issue-24081.rs @@ -1,3 +1,5 @@ +//@ dont-require-annotations: NOTE + use std::ops::Add; use std::ops::Sub; use std::ops::Mul; @@ -5,14 +7,14 @@ use std::ops::Div; use std::ops::Rem; type Add = bool; //~ ERROR the name `Add` is defined multiple times -//~| `Add` redefined here +//~| NOTE `Add` redefined here struct Sub { x: f32 } //~ ERROR the name `Sub` is defined multiple times -//~| `Sub` redefined here +//~| NOTE `Sub` redefined here enum Mul { A, B } //~ ERROR the name `Mul` is defined multiple times -//~| `Mul` redefined here +//~| NOTE `Mul` redefined here mod Div { } //~ ERROR the name `Div` is defined multiple times -//~| `Div` redefined here +//~| NOTE `Div` redefined here trait Rem { } //~ ERROR the name `Rem` is defined multiple times -//~| `Rem` redefined here +//~| NOTE `Rem` redefined here fn main() {} diff --git a/tests/ui/imports/issue-24081.stderr b/tests/ui/imports/issue-24081.stderr index 6ceba6c7013..c2346f524ce 100644 --- a/tests/ui/imports/issue-24081.stderr +++ b/tests/ui/imports/issue-24081.stderr @@ -1,5 +1,5 @@ error[E0255]: the name `Add` is defined multiple times - --> $DIR/issue-24081.rs:7:1 + --> $DIR/issue-24081.rs:9:1 | LL | use std::ops::Add; | ------------- previous import of the trait `Add` here @@ -14,7 +14,7 @@ LL | use std::ops::Add as OtherAdd; | +++++++++++ error[E0255]: the name `Sub` is defined multiple times - --> $DIR/issue-24081.rs:9:1 + --> $DIR/issue-24081.rs:11:1 | LL | use std::ops::Sub; | ------------- previous import of the trait `Sub` here @@ -29,7 +29,7 @@ LL | use std::ops::Sub as OtherSub; | +++++++++++ error[E0255]: the name `Mul` is defined multiple times - --> $DIR/issue-24081.rs:11:1 + --> $DIR/issue-24081.rs:13:1 | LL | use std::ops::Mul; | ------------- previous import of the trait `Mul` here @@ -44,7 +44,7 @@ LL | use std::ops::Mul as OtherMul; | +++++++++++ error[E0255]: the name `Div` is defined multiple times - --> $DIR/issue-24081.rs:13:1 + --> $DIR/issue-24081.rs:15:1 | LL | use std::ops::Div; | ------------- previous import of the trait `Div` here @@ -59,7 +59,7 @@ LL | use std::ops::Div as OtherDiv; | +++++++++++ error[E0255]: the name `Rem` is defined multiple times - --> $DIR/issue-24081.rs:15:1 + --> $DIR/issue-24081.rs:17:1 | LL | use std::ops::Rem; | ------------- previous import of the trait `Rem` here diff --git a/tests/ui/imports/issue-26886.rs b/tests/ui/imports/issue-26886.rs index 6e6d406c656..91be86ae774 100644 --- a/tests/ui/imports/issue-26886.rs +++ b/tests/ui/imports/issue-26886.rs @@ -1,8 +1,10 @@ +//@ dont-require-annotations: NOTE + use std::sync::{self, Arc}; use std::sync::Arc; //~ ERROR the name `Arc` is defined multiple times - //~| `Arc` must be defined only once in the type namespace of this module + //~| NOTE `Arc` must be defined only once in the type namespace of this module use std::sync; //~ ERROR the name `sync` is defined multiple times - //~| `sync` must be defined only once in the type namespace of this module + //~| NOTE `sync` must be defined only once in the type namespace of this module fn main() { } diff --git a/tests/ui/imports/issue-26886.stderr b/tests/ui/imports/issue-26886.stderr index e2b925ec5a7..a6143543446 100644 --- a/tests/ui/imports/issue-26886.stderr +++ b/tests/ui/imports/issue-26886.stderr @@ -1,5 +1,5 @@ error[E0252]: the name `Arc` is defined multiple times - --> $DIR/issue-26886.rs:2:5 + --> $DIR/issue-26886.rs:4:5 | LL | use std::sync::{self, Arc}; | --- previous import of the type `Arc` here @@ -9,7 +9,7 @@ LL | use std::sync::Arc; = note: `Arc` must be defined only once in the type namespace of this module error[E0252]: the name `sync` is defined multiple times - --> $DIR/issue-26886.rs:4:5 + --> $DIR/issue-26886.rs:6:5 | LL | use std::sync::{self, Arc}; | ---- previous import of the module `sync` here diff --git a/tests/ui/inference/tutorial-suffix-inference-test.rs b/tests/ui/inference/tutorial-suffix-inference-test.rs index 849adfd5368..ca593ff1b70 100644 --- a/tests/ui/inference/tutorial-suffix-inference-test.rs +++ b/tests/ui/inference/tutorial-suffix-inference-test.rs @@ -1,3 +1,5 @@ +//@ dont-require-annotations: NOTE + fn main() { let x = 3; let y: i32 = 3; @@ -8,10 +10,10 @@ fn main() { identity_u8(x); // after this, `x` is assumed to have type `u8` identity_u16(x); //~^ ERROR mismatched types - //~| expected `u16`, found `u8` + //~| NOTE expected `u16`, found `u8` identity_u16(y); //~^ ERROR mismatched types - //~| expected `u16`, found `i32` + //~| NOTE expected `u16`, found `i32` let a = 3; @@ -20,5 +22,5 @@ fn main() { identity_i(a); // ok identity_u16(a); //~^ ERROR mismatched types - //~| expected `u16`, found `isize` + //~| NOTE expected `u16`, found `isize` } diff --git a/tests/ui/inference/tutorial-suffix-inference-test.stderr b/tests/ui/inference/tutorial-suffix-inference-test.stderr index d83a1367dbf..39627aa9fc4 100644 --- a/tests/ui/inference/tutorial-suffix-inference-test.stderr +++ b/tests/ui/inference/tutorial-suffix-inference-test.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/tutorial-suffix-inference-test.rs:9:18 + --> $DIR/tutorial-suffix-inference-test.rs:11:18 | LL | identity_u16(x); | ------------ ^ expected `u16`, found `u8` @@ -7,7 +7,7 @@ LL | identity_u16(x); | arguments to this function are incorrect | note: function defined here - --> $DIR/tutorial-suffix-inference-test.rs:6:8 + --> $DIR/tutorial-suffix-inference-test.rs:8:8 | LL | fn identity_u16(n: u16) -> u16 { n } | ^^^^^^^^^^^^ ------ @@ -17,7 +17,7 @@ LL | identity_u16(x.into()); | +++++++ error[E0308]: mismatched types - --> $DIR/tutorial-suffix-inference-test.rs:12:18 + --> $DIR/tutorial-suffix-inference-test.rs:14:18 | LL | identity_u16(y); | ------------ ^ expected `u16`, found `i32` @@ -25,7 +25,7 @@ LL | identity_u16(y); | arguments to this function are incorrect | note: function defined here - --> $DIR/tutorial-suffix-inference-test.rs:6:8 + --> $DIR/tutorial-suffix-inference-test.rs:8:8 | LL | fn identity_u16(n: u16) -> u16 { n } | ^^^^^^^^^^^^ ------ @@ -35,7 +35,7 @@ LL | identity_u16(y.try_into().unwrap()); | ++++++++++++++++++++ error[E0308]: mismatched types - --> $DIR/tutorial-suffix-inference-test.rs:21:18 + --> $DIR/tutorial-suffix-inference-test.rs:23:18 | LL | identity_u16(a); | ------------ ^ expected `u16`, found `isize` @@ -43,7 +43,7 @@ LL | identity_u16(a); | arguments to this function are incorrect | note: function defined here - --> $DIR/tutorial-suffix-inference-test.rs:6:8 + --> $DIR/tutorial-suffix-inference-test.rs:8:8 | LL | fn identity_u16(n: u16) -> u16 { n } | ^^^^^^^^^^^^ ------ diff --git a/tests/ui/issues/issue-13359.rs b/tests/ui/issues/issue-13359.rs index 9129790c501..5d31d7f861c 100644 --- a/tests/ui/issues/issue-13359.rs +++ b/tests/ui/issues/issue-13359.rs @@ -1,3 +1,5 @@ +//@ dont-require-annotations: NOTE + fn foo(_s: i16) { } fn bar(_s: u32) { } @@ -5,9 +7,9 @@ fn bar(_s: u32) { } fn main() { foo(1*(1 as isize)); //~^ ERROR mismatched types - //~| expected `i16`, found `isize` + //~| NOTE expected `i16`, found `isize` bar(1*(1 as usize)); //~^ ERROR mismatched types - //~| expected `u32`, found `usize` + //~| NOTE expected `u32`, found `usize` } diff --git a/tests/ui/issues/issue-13359.stderr b/tests/ui/issues/issue-13359.stderr index fef63680a86..91f5de8e8f3 100644 --- a/tests/ui/issues/issue-13359.stderr +++ b/tests/ui/issues/issue-13359.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/issue-13359.rs:6:9 + --> $DIR/issue-13359.rs:8:9 | LL | foo(1*(1 as isize)); | --- ^^^^^^^^^^^^^^ expected `i16`, found `isize` @@ -7,7 +7,7 @@ LL | foo(1*(1 as isize)); | arguments to this function are incorrect | note: function defined here - --> $DIR/issue-13359.rs:1:4 + --> $DIR/issue-13359.rs:3:4 | LL | fn foo(_s: i16) { } | ^^^ ------- @@ -17,7 +17,7 @@ LL | foo((1*(1 as isize)).try_into().unwrap()); | + +++++++++++++++++++++ error[E0308]: mismatched types - --> $DIR/issue-13359.rs:10:9 + --> $DIR/issue-13359.rs:12:9 | LL | bar(1*(1 as usize)); | --- ^^^^^^^^^^^^^^ expected `u32`, found `usize` @@ -25,7 +25,7 @@ LL | bar(1*(1 as usize)); | arguments to this function are incorrect | note: function defined here - --> $DIR/issue-13359.rs:3:4 + --> $DIR/issue-13359.rs:5:4 | LL | fn bar(_s: u32) { } | ^^^ ------- diff --git a/tests/ui/issues/issue-13466.rs b/tests/ui/issues/issue-13466.rs index 52d4d75d29d..78ce4c1d2f6 100644 --- a/tests/ui/issues/issue-13466.rs +++ b/tests/ui/issues/issue-13466.rs @@ -1,5 +1,7 @@ // Regression test for #13466 +//@ dont-require-annotations: NOTE + pub fn main() { // The expected arm type `Option` has one type parameter, while // the actual arm `Result` has two. typeck should not be @@ -7,14 +9,14 @@ pub fn main() { let _x: usize = match Some(1) { Ok(u) => u, //~^ ERROR mismatched types - //~| expected enum `Option<{integer}>` - //~| found enum `Result<_, _>` - //~| expected `Option<{integer}>`, found `Result<_, _>` + //~| NOTE expected enum `Option<{integer}>` + //~| NOTE found enum `Result<_, _>` + //~| NOTE expected `Option<{integer}>`, found `Result<_, _>` Err(e) => panic!(e) //~^ ERROR mismatched types - //~| expected enum `Option<{integer}>` - //~| found enum `Result<_, _>` - //~| expected `Option<{integer}>`, found `Result<_, _>` + //~| NOTE expected enum `Option<{integer}>` + //~| NOTE found enum `Result<_, _>` + //~| NOTE expected `Option<{integer}>`, found `Result<_, _>` }; } diff --git a/tests/ui/issues/issue-13466.stderr b/tests/ui/issues/issue-13466.stderr index fd928e45863..68a555a1626 100644 --- a/tests/ui/issues/issue-13466.stderr +++ b/tests/ui/issues/issue-13466.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/issue-13466.rs:8:9 + --> $DIR/issue-13466.rs:10:9 | LL | let _x: usize = match Some(1) { | ------- this expression has type `Option<{integer}>` @@ -10,7 +10,7 @@ LL | Ok(u) => u, found enum `Result<_, _>` error[E0308]: mismatched types - --> $DIR/issue-13466.rs:14:9 + --> $DIR/issue-13466.rs:16:9 | LL | let _x: usize = match Some(1) { | ------- this expression has type `Option<{integer}>` diff --git a/tests/ui/issues/issue-14541.rs b/tests/ui/issues/issue-14541.rs index 2ff1c1f8876..358d29419f9 100644 --- a/tests/ui/issues/issue-14541.rs +++ b/tests/ui/issues/issue-14541.rs @@ -4,7 +4,8 @@ struct Vec3 { y: f32, z: f32 } fn make(v: Vec2) { let Vec3 { y: _, z: _ } = v; //~^ ERROR mismatched types - //~| expected `Vec2`, found `Vec3` + //~| NOTE expected `Vec2`, found `Vec3` + //~| NOTE this expression has type `Vec2` } fn main() { } diff --git a/tests/ui/issues/issue-15094.rs b/tests/ui/issues/issue-15094.rs index cb27e2bcfb6..408ab82eb8c 100644 --- a/tests/ui/issues/issue-15094.rs +++ b/tests/ui/issues/issue-15094.rs @@ -10,8 +10,9 @@ impl ops::FnOnce<(),> for Debuger { type Output = (); fn call_once(self, _args: ()) { //~^ ERROR `call_once` has an incompatible type for trait - //~| expected signature `extern "rust-call" fn - //~| found signature `fn + //~| NOTE expected signature `extern "rust-call" fn + //~| NOTE found signature `fn + //~| NOTE expected "rust-call" fn, found "Rust" fn println!("{:?}", self.x); } } diff --git a/tests/ui/issues/issue-15381.rs b/tests/ui/issues/issue-15381.rs index 23b266bef1d..bd5f62ddc67 100644 --- a/tests/ui/issues/issue-15381.rs +++ b/tests/ui/issues/issue-15381.rs @@ -3,7 +3,8 @@ fn main() { for &[x,y,z] in values.chunks(3).filter(|&xs| xs.len() == 3) { //~^ ERROR refutable pattern in `for` loop binding - //~| patterns `&[]`, `&[_]`, `&[_, _]` and 1 more not covered + //~| NOTE patterns `&[]`, `&[_]`, `&[_, _]` and 1 more not covered + //~| NOTE the matched value is of type `&[u8]` println!("y={}", y); } } diff --git a/tests/ui/issues/issue-15783.rs b/tests/ui/issues/issue-15783.rs index ceb37a20e3f..ef948a1a88c 100644 --- a/tests/ui/issues/issue-15783.rs +++ b/tests/ui/issues/issue-15783.rs @@ -1,3 +1,5 @@ +//@ dont-require-annotations: NOTE + pub fn foo(params: Option<&[&str]>) -> usize { params.unwrap().first().unwrap().len() } @@ -7,8 +9,8 @@ fn main() { let x = Some(&[name]); let msg = foo(x); //~^ ERROR mismatched types - //~| expected enum `Option<&[&str]>` - //~| found enum `Option<&[&str; 1]>` - //~| expected `Option<&[&str]>`, found `Option<&[&str; 1]>` + //~| NOTE expected enum `Option<&[&str]>` + //~| NOTE found enum `Option<&[&str; 1]>` + //~| NOTE expected `Option<&[&str]>`, found `Option<&[&str; 1]>` assert_eq!(msg, 3); } diff --git a/tests/ui/issues/issue-15783.stderr b/tests/ui/issues/issue-15783.stderr index 7ed2e199130..c9c9a723a86 100644 --- a/tests/ui/issues/issue-15783.stderr +++ b/tests/ui/issues/issue-15783.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/issue-15783.rs:8:19 + --> $DIR/issue-15783.rs:10:19 | LL | let msg = foo(x); | --- ^ expected `Option<&[&str]>`, found `Option<&[&str; 1]>` @@ -9,7 +9,7 @@ LL | let msg = foo(x); = note: expected enum `Option<&[&str]>` found enum `Option<&[&str; 1]>` note: function defined here - --> $DIR/issue-15783.rs:1:8 + --> $DIR/issue-15783.rs:3:8 | LL | pub fn foo(params: Option<&[&str]>) -> usize { | ^^^ ----------------------- diff --git a/tests/ui/issues/issue-16401.rs b/tests/ui/issues/issue-16401.rs index 19ae7da107c..0985a6806d2 100644 --- a/tests/ui/issues/issue-16401.rs +++ b/tests/ui/issues/issue-16401.rs @@ -4,12 +4,12 @@ struct Slice { } fn main() { - match () { + match () { //~ NOTE this expression has type `()` Slice { data: data, len: len } => (), //~^ ERROR mismatched types - //~| expected unit type `()` - //~| found struct `Slice<_>` - //~| expected `()`, found `Slice<_>` + //~| NOTE expected unit type `()` + //~| NOTE found struct `Slice<_>` + //~| NOTE expected `()`, found `Slice<_>` _ => unreachable!() } } diff --git a/tests/ui/issues/issue-17033.rs b/tests/ui/issues/issue-17033.rs index 72a8cd9823a..b8eec3b6b25 100644 --- a/tests/ui/issues/issue-17033.rs +++ b/tests/ui/issues/issue-17033.rs @@ -1,6 +1,7 @@ fn f<'r>(p: &'r mut fn(p: &mut ())) { (*p)(()) //~ ERROR mismatched types - //~| expected `&mut ()`, found `()` + //~| NOTE expected `&mut ()`, found `()` + //~| NOTE arguments to this function are incorrect } fn main() {} diff --git a/tests/ui/issues/issue-17740.rs b/tests/ui/issues/issue-17740.rs index 574d3662b4f..20a73756ea3 100644 --- a/tests/ui/issues/issue-17740.rs +++ b/tests/ui/issues/issue-17740.rs @@ -1,3 +1,5 @@ +//@ dont-require-annotations: NOTE + struct Foo<'a> { data: &'a[u8], } @@ -5,13 +7,13 @@ struct Foo<'a> { impl <'a> Foo<'a>{ fn bar(self: &mut Foo) { //~^ ERROR mismatched `self` parameter type - //~| expected struct `Foo<'a>` - //~| found struct `Foo<'_>` - //~| lifetime mismatch + //~| NOTE expected struct `Foo<'a>` + //~| NOTE found struct `Foo<'_>` + //~| NOTE lifetime mismatch //~| ERROR mismatched `self` parameter type - //~| expected struct `Foo<'a>` - //~| found struct `Foo<'_>` - //~| lifetime mismatch + //~| NOTE expected struct `Foo<'a>` + //~| NOTE found struct `Foo<'_>` + //~| NOTE lifetime mismatch } } diff --git a/tests/ui/issues/issue-17740.stderr b/tests/ui/issues/issue-17740.stderr index d1773804155..198d7d5b37c 100644 --- a/tests/ui/issues/issue-17740.stderr +++ b/tests/ui/issues/issue-17740.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched `self` parameter type - --> $DIR/issue-17740.rs:6:18 + --> $DIR/issue-17740.rs:8:18 | LL | fn bar(self: &mut Foo) { | ^^^^^^^^ lifetime mismatch @@ -7,18 +7,18 @@ LL | fn bar(self: &mut Foo) { = note: expected struct `Foo<'a>` found struct `Foo<'_>` note: the anonymous lifetime defined here... - --> $DIR/issue-17740.rs:6:23 + --> $DIR/issue-17740.rs:8:23 | LL | fn bar(self: &mut Foo) { | ^^^ note: ...does not necessarily outlive the lifetime `'a` as defined here - --> $DIR/issue-17740.rs:5:7 + --> $DIR/issue-17740.rs:7:7 | LL | impl <'a> Foo<'a>{ | ^^ error[E0308]: mismatched `self` parameter type - --> $DIR/issue-17740.rs:6:18 + --> $DIR/issue-17740.rs:8:18 | LL | fn bar(self: &mut Foo) { | ^^^^^^^^ lifetime mismatch @@ -26,12 +26,12 @@ LL | fn bar(self: &mut Foo) { = note: expected struct `Foo<'a>` found struct `Foo<'_>` note: the lifetime `'a` as defined here... - --> $DIR/issue-17740.rs:5:7 + --> $DIR/issue-17740.rs:7:7 | LL | impl <'a> Foo<'a>{ | ^^ note: ...does not necessarily outlive the anonymous lifetime defined here - --> $DIR/issue-17740.rs:6:23 + --> $DIR/issue-17740.rs:8:23 | LL | fn bar(self: &mut Foo) { | ^^^ diff --git a/tests/ui/issues/issue-19991.rs b/tests/ui/issues/issue-19991.rs index dd0efa972ba..cb558b58697 100644 --- a/tests/ui/issues/issue-19991.rs +++ b/tests/ui/issues/issue-19991.rs @@ -1,9 +1,11 @@ // Test if the sugared `if let` construct correctly prints "missing an else clause" when an else // clause does not exist, instead of the unsympathetic "`match` arms have incompatible types" +//@ dont-require-annotations: NOTE + fn main() { if let Some(homura) = Some("madoka") { //~ ERROR missing an `else` clause - //~| expected integer, found `()` + //~| NOTE expected integer, found `()` 765 }; } diff --git a/tests/ui/issues/issue-19991.stderr b/tests/ui/issues/issue-19991.stderr index ff039f3adba..1449bab5142 100644 --- a/tests/ui/issues/issue-19991.stderr +++ b/tests/ui/issues/issue-19991.stderr @@ -1,5 +1,5 @@ error[E0317]: `if` may be missing an `else` clause - --> $DIR/issue-19991.rs:5:5 + --> $DIR/issue-19991.rs:7:5 | LL | / if let Some(homura) = Some("madoka") { LL | | diff --git a/tests/ui/issues/issue-21332.rs b/tests/ui/issues/issue-21332.rs index 4473d00fd5d..ad764f84aa8 100644 --- a/tests/ui/issues/issue-21332.rs +++ b/tests/ui/issues/issue-21332.rs @@ -4,7 +4,8 @@ impl Iterator for S { type Item = i32; fn next(&mut self) -> Result { Ok(7) } //~^ ERROR method `next` has an incompatible type for trait - //~| expected `Option`, found `Result` + //~| NOTE expected `Option`, found `Result` + //~| NOTE expected signature `fn(&mut S) -> Option` } fn main() {} diff --git a/tests/ui/issues/issue-24819.rs b/tests/ui/issues/issue-24819.rs index fb4cfb7b29e..97d288e5cb1 100644 --- a/tests/ui/issues/issue-24819.rs +++ b/tests/ui/issues/issue-24819.rs @@ -1,10 +1,12 @@ +//@ dont-require-annotations: NOTE + use std::collections::HashSet; fn main() { let mut v = Vec::new(); foo(&mut v); //~^ ERROR mismatched types - //~| expected `&mut HashSet`, found `&mut Vec<_>` + //~| NOTE expected `&mut HashSet`, found `&mut Vec<_>` } fn foo(h: &mut HashSet) { diff --git a/tests/ui/issues/issue-24819.stderr b/tests/ui/issues/issue-24819.stderr index 8ec34aa13fa..e144f37d6e4 100644 --- a/tests/ui/issues/issue-24819.stderr +++ b/tests/ui/issues/issue-24819.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/issue-24819.rs:5:9 + --> $DIR/issue-24819.rs:7:9 | LL | foo(&mut v); | --- ^^^^^^ expected `&mut HashSet`, found `&mut Vec<_>` @@ -9,7 +9,7 @@ LL | foo(&mut v); = note: expected mutable reference `&mut HashSet` found mutable reference `&mut Vec<_>` note: function defined here - --> $DIR/issue-24819.rs:10:4 + --> $DIR/issue-24819.rs:12:4 | LL | fn foo(h: &mut HashSet) { | ^^^ -------------------- diff --git a/tests/ui/issues/issue-27942.rs b/tests/ui/issues/issue-27942.rs index 34b34de3879..1c2e6456937 100644 --- a/tests/ui/issues/issue-27942.rs +++ b/tests/ui/issues/issue-27942.rs @@ -1,12 +1,14 @@ +//@ dont-require-annotations: NOTE + pub trait Resources<'a> {} pub trait Buffer<'a, R: Resources<'a>> { fn select(&self) -> BufferViewHandle; //~^ ERROR mismatched types - //~| lifetime mismatch + //~| NOTE lifetime mismatch //~| ERROR mismatched types - //~| lifetime mismatch + //~| NOTE lifetime mismatch } pub struct BufferViewHandle<'a, R: 'a+Resources<'a>>(&'a R); diff --git a/tests/ui/issues/issue-27942.stderr b/tests/ui/issues/issue-27942.stderr index 8ea46bae26d..671875aa7e2 100644 --- a/tests/ui/issues/issue-27942.stderr +++ b/tests/ui/issues/issue-27942.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/issue-27942.rs:5:25 + --> $DIR/issue-27942.rs:7:25 | LL | fn select(&self) -> BufferViewHandle; | ^^^^^^^^^^^^^^^^^^^ lifetime mismatch @@ -7,18 +7,18 @@ LL | fn select(&self) -> BufferViewHandle; = note: expected trait `Resources<'_>` found trait `Resources<'a>` note: the lifetime `'a` as defined here... - --> $DIR/issue-27942.rs:3:18 + --> $DIR/issue-27942.rs:5:18 | LL | pub trait Buffer<'a, R: Resources<'a>> { | ^^ note: ...does not necessarily outlive the anonymous lifetime defined here - --> $DIR/issue-27942.rs:5:15 + --> $DIR/issue-27942.rs:7:15 | LL | fn select(&self) -> BufferViewHandle; | ^^^^^ error[E0308]: mismatched types - --> $DIR/issue-27942.rs:5:25 + --> $DIR/issue-27942.rs:7:25 | LL | fn select(&self) -> BufferViewHandle; | ^^^^^^^^^^^^^^^^^^^ lifetime mismatch @@ -26,12 +26,12 @@ LL | fn select(&self) -> BufferViewHandle; = note: expected trait `Resources<'_>` found trait `Resources<'a>` note: the anonymous lifetime defined here... - --> $DIR/issue-27942.rs:5:15 + --> $DIR/issue-27942.rs:7:15 | LL | fn select(&self) -> BufferViewHandle; | ^^^^^ note: ...does not necessarily outlive the lifetime `'a` as defined here - --> $DIR/issue-27942.rs:3:18 + --> $DIR/issue-27942.rs:5:18 | LL | pub trait Buffer<'a, R: Resources<'a>> { | ^^ diff --git a/tests/ui/issues/issue-2951.rs b/tests/ui/issues/issue-2951.rs index 1798e3e7519..e28516fa307 100644 --- a/tests/ui/issues/issue-2951.rs +++ b/tests/ui/issues/issue-2951.rs @@ -1,10 +1,12 @@ +//@ dont-require-annotations: NOTE + fn foo(x: T, y: U) { let mut xx = x; xx = y; //~^ ERROR mismatched types - //~| expected type parameter `T`, found type parameter `U` - //~| expected type parameter `T` - //~| found type parameter `U` + //~| NOTE expected type parameter `T`, found type parameter `U` + //~| NOTE expected type parameter `T` + //~| NOTE found type parameter `U` } fn main() { diff --git a/tests/ui/issues/issue-2951.stderr b/tests/ui/issues/issue-2951.stderr index 134808b4d23..d4b45935bf9 100644 --- a/tests/ui/issues/issue-2951.stderr +++ b/tests/ui/issues/issue-2951.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/issue-2951.rs:3:10 + --> $DIR/issue-2951.rs:5:10 | LL | fn foo(x: T, y: U) { | - - found type parameter diff --git a/tests/ui/issues/issue-31011.rs b/tests/ui/issues/issue-31011.rs index 86fe16f48e2..078d8b2d50f 100644 --- a/tests/ui/issues/issue-31011.rs +++ b/tests/ui/issues/issue-31011.rs @@ -1,3 +1,5 @@ +//@ dont-require-annotations: NOTE + macro_rules! log { ( $ctx:expr, $( $args:expr),* ) => { if $ctx.trace { @@ -16,7 +18,7 @@ struct Foo { fn wrap(context: &T) -> () { log!(context, "entered wrapper"); - //~^ in this expansion of log! + //~^ NOTE in this expansion of log! } fn main() { diff --git a/tests/ui/issues/issue-31011.stderr b/tests/ui/issues/issue-31011.stderr index 9785d56f4fc..701141ee440 100644 --- a/tests/ui/issues/issue-31011.stderr +++ b/tests/ui/issues/issue-31011.stderr @@ -1,5 +1,5 @@ error[E0609]: no field `trace` on type `&T` - --> $DIR/issue-31011.rs:3:17 + --> $DIR/issue-31011.rs:5:17 | LL | if $ctx.trace { | ^^^^^ unknown field diff --git a/tests/ui/issues/issue-31910.rs b/tests/ui/issues/issue-31910.rs index 19cfc4627c7..fc82fda0ccd 100644 --- a/tests/ui/issues/issue-31910.rs +++ b/tests/ui/issues/issue-31910.rs @@ -1,8 +1,9 @@ enum Enum { - //~^ ERROR: `T` is never used + //~^ ERROR `T` is never used + //~| NOTE unused type parameter X = Trait::Number, //~^ ERROR mismatched types - //~| expected `isize`, found `i32` + //~| NOTE expected `isize`, found `i32` } trait Trait { diff --git a/tests/ui/issues/issue-31910.stderr b/tests/ui/issues/issue-31910.stderr index ca2d2f619e6..56e4cee53d6 100644 --- a/tests/ui/issues/issue-31910.stderr +++ b/tests/ui/issues/issue-31910.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/issue-31910.rs:3:9 + --> $DIR/issue-31910.rs:4:9 | LL | X = Trait::Number, | ^^^^^^^^^^^^^ expected `isize`, found `i32` diff --git a/tests/ui/issues/issue-3477.rs b/tests/ui/issues/issue-3477.rs index 3817d0e6a3e..eb94294d5a8 100644 --- a/tests/ui/issues/issue-3477.rs +++ b/tests/ui/issues/issue-3477.rs @@ -1,5 +1,6 @@ fn main() { let _p: char = 100; //~^ ERROR mismatched types - //~| expected `char`, found `u8` + //~| NOTE expected `char`, found `u8` + //~| NOTE expected due to this } diff --git a/tests/ui/issues/issue-3680.rs b/tests/ui/issues/issue-3680.rs index a0e52798122..7fdc6e179e4 100644 --- a/tests/ui/issues/issue-3680.rs +++ b/tests/ui/issues/issue-3680.rs @@ -1,9 +1,9 @@ fn main() { - match None { + match None { //~ NOTE this expression has type `Option<_>` Err(_) => () //~^ ERROR mismatched types - //~| expected enum `Option<_>` - //~| found enum `Result<_, _>` - //~| expected `Option<_>`, found `Result<_, _>` + //~| NOTE expected enum `Option<_>` + //~| NOTE found enum `Result<_, _>` + //~| NOTE expected `Option<_>`, found `Result<_, _>` } } diff --git a/tests/ui/issues/issue-37884.rs b/tests/ui/issues/issue-37884.rs index ee37481b23f..3480942d9d2 100644 --- a/tests/ui/issues/issue-37884.rs +++ b/tests/ui/issues/issue-37884.rs @@ -1,3 +1,5 @@ +//@ dont-require-annotations: NOTE + struct RepeatMut<'a, T>(T, &'a ()); impl<'a, T: 'a> Iterator for RepeatMut<'a, T> { @@ -5,7 +7,7 @@ impl<'a, T: 'a> Iterator for RepeatMut<'a, T> { type Item = &'a mut T; fn next(&'a mut self) -> Option //~^ ERROR method not compatible with trait - //~| lifetime mismatch + //~| NOTE lifetime mismatch { Some(&mut self.0) } diff --git a/tests/ui/issues/issue-37884.stderr b/tests/ui/issues/issue-37884.stderr index 17037d2180d..a7a19e3c6df 100644 --- a/tests/ui/issues/issue-37884.stderr +++ b/tests/ui/issues/issue-37884.stderr @@ -1,5 +1,5 @@ error[E0308]: method not compatible with trait - --> $DIR/issue-37884.rs:6:5 + --> $DIR/issue-37884.rs:8:5 | LL | fn next(&'a mut self) -> Option | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ lifetime mismatch @@ -9,7 +9,7 @@ LL | fn next(&'a mut self) -> Option note: the anonymous lifetime as defined here... --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL note: ...does not necessarily outlive the lifetime `'a` as defined here - --> $DIR/issue-37884.rs:3:6 + --> $DIR/issue-37884.rs:5:6 | LL | impl<'a, T: 'a> Iterator for RepeatMut<'a, T> { | ^^ diff --git a/tests/ui/issues/issue-43355.rs b/tests/ui/issues/issue-43355.rs index bf819af7962..597472b4f48 100644 --- a/tests/ui/issues/issue-43355.rs +++ b/tests/ui/issues/issue-43355.rs @@ -1,3 +1,5 @@ +//@ dont-require-annotations: NOTE + pub trait Trait1 { type Output; } @@ -12,7 +14,7 @@ impl Trait1 for T where T: Trait2 { impl Trait1> for A { //~^ ERROR conflicting implementations of trait -//~| downstream crates may implement trait `Trait2>` for type `A` +//~| NOTE downstream crates may implement trait `Trait2>` for type `A` type Output = i32; } diff --git a/tests/ui/issues/issue-43355.stderr b/tests/ui/issues/issue-43355.stderr index 25179ef6a96..5a089cb3d8b 100644 --- a/tests/ui/issues/issue-43355.stderr +++ b/tests/ui/issues/issue-43355.stderr @@ -1,5 +1,5 @@ error[E0119]: conflicting implementations of trait `Trait1>` for type `A` - --> $DIR/issue-43355.rs:13:1 + --> $DIR/issue-43355.rs:15:1 | LL | impl Trait1 for T where T: Trait2 { | --------------------------------------------- first implementation here diff --git a/tests/ui/issues/issue-4517.rs b/tests/ui/issues/issue-4517.rs index 469304e2cf7..778f8f97bcc 100644 --- a/tests/ui/issues/issue-4517.rs +++ b/tests/ui/issues/issue-4517.rs @@ -1,8 +1,10 @@ +//@ dont-require-annotations: NOTE + fn bar(int_param: usize) {} fn main() { let foo: [u8; 4] = [1; 4]; bar(foo); //~^ ERROR mismatched types - //~| expected `usize`, found `[u8; 4]` + //~| NOTE expected `usize`, found `[u8; 4]` } diff --git a/tests/ui/issues/issue-4517.stderr b/tests/ui/issues/issue-4517.stderr index 5d544ee10a9..d078c7eb95a 100644 --- a/tests/ui/issues/issue-4517.stderr +++ b/tests/ui/issues/issue-4517.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/issue-4517.rs:5:9 + --> $DIR/issue-4517.rs:7:9 | LL | bar(foo); | --- ^^^ expected `usize`, found `[u8; 4]` @@ -7,7 +7,7 @@ LL | bar(foo); | arguments to this function are incorrect | note: function defined here - --> $DIR/issue-4517.rs:1:4 + --> $DIR/issue-4517.rs:3:4 | LL | fn bar(int_param: usize) {} | ^^^ ---------------- diff --git a/tests/ui/issues/issue-4935.rs b/tests/ui/issues/issue-4935.rs index c95020a0c00..ef8a3eb32ab 100644 --- a/tests/ui/issues/issue-4935.rs +++ b/tests/ui/issues/issue-4935.rs @@ -1,6 +1,7 @@ // Regression test for issue #4935 fn foo(a: usize) {} -//~^ defined here +//~^ NOTE defined here fn main() { foo(5, 6) } //~^ ERROR function takes 1 argument but 2 arguments were supplied +//~| NOTE unexpected argument #2 of type `{integer}` diff --git a/tests/ui/issues/issue-4968.rs b/tests/ui/issues/issue-4968.rs index c8df46dc267..08539d6debd 100644 --- a/tests/ui/issues/issue-4968.rs +++ b/tests/ui/issues/issue-4968.rs @@ -1,10 +1,12 @@ // Regression test for issue #4968 +//@ dont-require-annotations: NOTE + const A: (isize,isize) = (4,2); fn main() { match 42 { A => () } //~^ ERROR mismatched types - //~| expected type `{integer}` - //~| found tuple `(isize, isize)` - //~| expected integer, found `(isize, isize)` + //~| NOTE expected type `{integer}` + //~| NOTE found tuple `(isize, isize)` + //~| NOTE expected integer, found `(isize, isize)` } diff --git a/tests/ui/issues/issue-4968.stderr b/tests/ui/issues/issue-4968.stderr index 549e5509474..2c1e1d7bfe5 100644 --- a/tests/ui/issues/issue-4968.stderr +++ b/tests/ui/issues/issue-4968.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/issue-4968.rs:5:16 + --> $DIR/issue-4968.rs:7:16 | LL | const A: (isize,isize) = (4,2); | ---------------------- constant defined here diff --git a/tests/ui/issues/issue-5100.rs b/tests/ui/issues/issue-5100.rs index 53ebdec8164..e9ae551bb77 100644 --- a/tests/ui/issues/issue-5100.rs +++ b/tests/ui/issues/issue-5100.rs @@ -1,5 +1,6 @@ -#![feature(box_patterns)] +//@ dont-require-annotations: NOTE +#![feature(box_patterns)] enum A { B, C } @@ -7,41 +8,41 @@ fn main() { match (true, false) { A::B => (), //~^ ERROR mismatched types -//~| expected `(bool, bool)`, found `A` -//~| expected tuple `(bool, bool)` -//~| found enum `A` +//~| NOTE expected `(bool, bool)`, found `A` +//~| NOTE expected tuple `(bool, bool)` +//~| NOTE found enum `A` _ => () } match (true, false) { (true, false, false) => () //~^ ERROR mismatched types -//~| expected a tuple with 2 elements, found one with 3 elements -//~| expected tuple `(bool, bool)` -//~| found tuple `(_, _, _)` +//~| NOTE expected a tuple with 2 elements, found one with 3 elements +//~| NOTE expected tuple `(bool, bool)` +//~| NOTE found tuple `(_, _, _)` } match (true, false) { (true, false, false) => () //~^ ERROR mismatched types -//~| expected a tuple with 2 elements, found one with 3 elements -//~| expected tuple `(bool, bool)` -//~| found tuple `(_, _, _)` +//~| NOTE expected a tuple with 2 elements, found one with 3 elements +//~| NOTE expected tuple `(bool, bool)` +//~| NOTE found tuple `(_, _, _)` } match (true, false) { box (true, false) => () //~^ ERROR mismatched types -//~| expected tuple `(bool, bool)` -//~| found struct `Box<_>` +//~| NOTE expected tuple `(bool, bool)` +//~| NOTE found struct `Box<_>` } match (true, false) { &(true, false) => () //~^ ERROR mismatched types -//~| expected `(bool, bool)`, found `&_` -//~| expected tuple `(bool, bool)` -//~| found reference `&_` +//~| NOTE expected `(bool, bool)`, found `&_` +//~| NOTE expected tuple `(bool, bool)` +//~| NOTE found reference `&_` } @@ -53,5 +54,5 @@ fn main() { // Make sure none of the errors above were fatal let x: char = true; //~ ERROR mismatched types - //~| expected `char`, found `bool` + //~| NOTE expected `char`, found `bool` } diff --git a/tests/ui/issues/issue-5100.stderr b/tests/ui/issues/issue-5100.stderr index b1680aacd16..24d41a1a8af 100644 --- a/tests/ui/issues/issue-5100.stderr +++ b/tests/ui/issues/issue-5100.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/issue-5100.rs:8:9 + --> $DIR/issue-5100.rs:9:9 | LL | enum A { B, C } | - unit variant defined here @@ -13,7 +13,7 @@ LL | A::B => (), found enum `A` error[E0308]: mismatched types - --> $DIR/issue-5100.rs:17:9 + --> $DIR/issue-5100.rs:18:9 | LL | match (true, false) { | ------------- this expression has type `(bool, bool)` @@ -24,7 +24,7 @@ LL | (true, false, false) => () found tuple `(_, _, _)` error[E0308]: mismatched types - --> $DIR/issue-5100.rs:25:9 + --> $DIR/issue-5100.rs:26:9 | LL | match (true, false) { | ------------- this expression has type `(bool, bool)` @@ -35,7 +35,7 @@ LL | (true, false, false) => () found tuple `(_, _, _)` error[E0308]: mismatched types - --> $DIR/issue-5100.rs:33:9 + --> $DIR/issue-5100.rs:34:9 | LL | match (true, false) { | ------------- this expression has type `(bool, bool)` @@ -46,7 +46,7 @@ LL | box (true, false) => () found struct `Box<_>` error[E0308]: mismatched types - --> $DIR/issue-5100.rs:40:9 + --> $DIR/issue-5100.rs:41:9 | LL | match (true, false) { | ------------- this expression has type `(bool, bool)` @@ -57,13 +57,13 @@ LL | &(true, false) => () found reference `&_` error[E0618]: expected function, found `(char, char)` - --> $DIR/issue-5100.rs:48:14 + --> $DIR/issue-5100.rs:49:14 | LL | let v = [('a', 'b') | ^^^^^^^^^^- help: consider separating array elements with a comma: `,` error[E0308]: mismatched types - --> $DIR/issue-5100.rs:55:19 + --> $DIR/issue-5100.rs:56:19 | LL | let x: char = true; | ---- ^^^^ expected `char`, found `bool` diff --git a/tests/ui/issues/issue-5358-1.rs b/tests/ui/issues/issue-5358-1.rs index 14ee962b722..281f219c039 100644 --- a/tests/ui/issues/issue-5358-1.rs +++ b/tests/ui/issues/issue-5358-1.rs @@ -2,12 +2,12 @@ enum Either { Left(T), Right(U) } struct S(Either); fn main() { - match S(Either::Left(5)) { + match S(Either::Left(5)) { //~ NOTE this expression has type `S` Either::Right(_) => {} //~^ ERROR mismatched types - //~| expected `S`, found `Either<_, _>` - //~| expected struct `S` - //~| found enum `Either<_, _>` + //~| NOTE expected `S`, found `Either<_, _>` + //~| NOTE expected struct `S` + //~| NOTE found enum `Either<_, _>` _ => {} } } diff --git a/tests/ui/issues/issue-7061.rs b/tests/ui/issues/issue-7061.rs index 8a6ee920a3a..c5d5a9d9498 100644 --- a/tests/ui/issues/issue-7061.rs +++ b/tests/ui/issues/issue-7061.rs @@ -1,10 +1,12 @@ +//@ dont-require-annotations: NOTE + struct BarStruct; impl<'a> BarStruct { fn foo(&'a mut self) -> Box { self } //~^ ERROR mismatched types - //~| expected struct `Box` - //~| found mutable reference `&'a mut BarStruct` + //~| NOTE expected struct `Box` + //~| NOTE found mutable reference `&'a mut BarStruct` } fn main() {} diff --git a/tests/ui/issues/issue-7061.stderr b/tests/ui/issues/issue-7061.stderr index 4fca2ff39fe..b4c0ebfbdd5 100644 --- a/tests/ui/issues/issue-7061.stderr +++ b/tests/ui/issues/issue-7061.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/issue-7061.rs:4:46 + --> $DIR/issue-7061.rs:6:46 | LL | fn foo(&'a mut self) -> Box { self } | -------------- ^^^^ expected `Box`, found `&mut BarStruct` diff --git a/tests/ui/issues/issue-7092.rs b/tests/ui/issues/issue-7092.rs index c3c96c7d3f6..fab18bd7cf7 100644 --- a/tests/ui/issues/issue-7092.rs +++ b/tests/ui/issues/issue-7092.rs @@ -2,12 +2,12 @@ enum Whatever { } fn foo(x: Whatever) { - match x { + match x { //~ NOTE this expression has type `Whatever` Some(field) => //~^ ERROR mismatched types -//~| expected `Whatever`, found `Option<_>` -//~| expected enum `Whatever` -//~| found enum `Option<_>` +//~| NOTE expected `Whatever`, found `Option<_>` +//~| NOTE expected enum `Whatever` +//~| NOTE found enum `Option<_>` field.access(), } } diff --git a/tests/ui/issues/issue-7867.rs b/tests/ui/issues/issue-7867.rs index e9fd10c6613..87e7c831e68 100644 --- a/tests/ui/issues/issue-7867.rs +++ b/tests/ui/issues/issue-7867.rs @@ -1,3 +1,5 @@ +//@ dont-require-annotations: NOTE + enum A { B, C } mod foo { pub fn bar() {} } @@ -6,9 +8,9 @@ fn main() { match (true, false) { A::B => (), //~^ ERROR mismatched types - //~| expected `(bool, bool)`, found `A` - //~| expected tuple `(bool, bool)` - //~| found enum `A` + //~| NOTE expected `(bool, bool)`, found `A` + //~| NOTE expected tuple `(bool, bool)` + //~| NOTE found enum `A` _ => () } } diff --git a/tests/ui/issues/issue-7867.stderr b/tests/ui/issues/issue-7867.stderr index 1a0cf5da8be..fcb69d775fa 100644 --- a/tests/ui/issues/issue-7867.stderr +++ b/tests/ui/issues/issue-7867.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/issue-7867.rs:7:9 + --> $DIR/issue-7867.rs:9:9 | LL | enum A { B, C } | - unit variant defined here diff --git a/tests/ui/macros/issue-118786.rs b/tests/ui/macros/issue-118786.rs index a73b737fe07..78fd6ab6edd 100644 --- a/tests/ui/macros/issue-118786.rs +++ b/tests/ui/macros/issue-118786.rs @@ -1,4 +1,5 @@ //@ compile-flags: --crate-type lib -O -C debug-assertions=yes +//@ dont-require-annotations: NOTE // Regression test for issue 118786 @@ -7,7 +8,7 @@ macro_rules! make_macro { macro_rules! $macro_name { //~^ ERROR macro expansion ignores `{` and any tokens following //~| ERROR cannot find macro `macro_rules` in this scope - //~| put a macro name here + //~| NOTE put a macro name here () => {} } } diff --git a/tests/ui/macros/issue-118786.stderr b/tests/ui/macros/issue-118786.stderr index af4cc9ad863..ddec281b823 100644 --- a/tests/ui/macros/issue-118786.stderr +++ b/tests/ui/macros/issue-118786.stderr @@ -1,5 +1,5 @@ error: macros that expand to items must be delimited with braces or followed by a semicolon - --> $DIR/issue-118786.rs:16:13 + --> $DIR/issue-118786.rs:17:13 | LL | make_macro!((meow)); | ^^^^^^ @@ -15,7 +15,7 @@ LL | macro_rules! $macro_name; { | + error: macro expansion ignores `{` and any tokens following - --> $DIR/issue-118786.rs:7:34 + --> $DIR/issue-118786.rs:8:34 | LL | macro_rules! $macro_name { | ^ @@ -26,7 +26,7 @@ LL | make_macro!((meow)); = note: the usage of `make_macro!` is likely invalid in item context error: cannot find macro `macro_rules` in this scope - --> $DIR/issue-118786.rs:7:9 + --> $DIR/issue-118786.rs:8:9 | LL | macro_rules! $macro_name { | ^^^^^^^^^^^ @@ -35,7 +35,7 @@ LL | make_macro!((meow)); | ------------------- in this macro invocation | note: maybe you have forgotten to define a name for this `macro_rules!` - --> $DIR/issue-118786.rs:7:20 + --> $DIR/issue-118786.rs:8:20 | LL | macro_rules! $macro_name { | ^ put a macro name here diff --git a/tests/ui/macros/issue-29084.rs b/tests/ui/macros/issue-29084.rs index d1625268669..a0a2966f75b 100644 --- a/tests/ui/macros/issue-29084.rs +++ b/tests/ui/macros/issue-29084.rs @@ -1,13 +1,15 @@ +//@ dont-require-annotations: NOTE + macro_rules! foo { ($d:expr) => {{ fn bar(d: u8) { } bar(&mut $d); //~^ ERROR mismatched types - //~| expected `u8`, found `&mut u8` + //~| NOTE expected `u8`, found `&mut u8` }} } fn main() { foo!(0u8); - //~^ in this expansion of foo! + //~^ NOTE in this expansion of foo! } diff --git a/tests/ui/macros/issue-29084.stderr b/tests/ui/macros/issue-29084.stderr index 9c33e4e8427..6e7474c5b3f 100644 --- a/tests/ui/macros/issue-29084.stderr +++ b/tests/ui/macros/issue-29084.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/issue-29084.rs:4:13 + --> $DIR/issue-29084.rs:6:13 | LL | bar(&mut $d); | --- ^^^^^^^ expected `u8`, found `&mut u8` @@ -10,7 +10,7 @@ LL | foo!(0u8); | --------- in this macro invocation | note: function defined here - --> $DIR/issue-29084.rs:3:12 + --> $DIR/issue-29084.rs:5:12 | LL | fn bar(d: u8) { } | ^^^ ----- diff --git a/tests/ui/match/match-struct.rs b/tests/ui/match/match-struct.rs index 4da7b436ba8..2160571302f 100644 --- a/tests/ui/match/match-struct.rs +++ b/tests/ui/match/match-struct.rs @@ -2,10 +2,10 @@ struct S { a: isize } enum E { C(isize) } fn main() { - match (S { a: 1 }) { + match (S { a: 1 }) { //~ NOTE this expression has type `S` E::C(_) => (), //~^ ERROR mismatched types - //~| expected `S`, found `E` + //~| NOTE expected `S`, found `E` _ => () } } diff --git a/tests/ui/methods/method-deref-to-same-trait-object-with-separate-params.rs b/tests/ui/methods/method-deref-to-same-trait-object-with-separate-params.rs index 9e53ff07917..5ef1d0c6dc9 100644 --- a/tests/ui/methods/method-deref-to-same-trait-object-with-separate-params.rs +++ b/tests/ui/methods/method-deref-to-same-trait-object-with-separate-params.rs @@ -1,3 +1,5 @@ +//@ dont-require-annotations: NOTE + #![feature(arbitrary_self_types, coerce_unsized, dispatch_from_dyn, unsize)] #![feature(unsized_locals, unsized_fn_params)] //~^ WARN the feature `unsized_locals` is incomplete @@ -85,7 +87,7 @@ fn objectcandidate_impl() { // Observe the type of `z` is `u32` let _seetype: () = z; //~ ERROR mismatched types - //~| expected `()`, found `u32` + //~| NOTE expected `()`, found `u32` } fn traitcandidate_impl() { @@ -102,7 +104,7 @@ fn traitcandidate_impl() { // Observe the type of `z` is `u64` let _seetype: () = z; //~ ERROR mismatched types - //~| expected `()`, found `u64` + //~| NOTE expected `()`, found `u64` } fn traitcandidate_impl_with_nuisance() { @@ -137,7 +139,7 @@ fn neither_impl() { // Observe the type of `z` is `u8` let _seetype: () = z; //~ ERROR mismatched types - //~| expected `()`, found `u8` + //~| NOTE expected `()`, found `u8` } fn both_impls() { @@ -155,7 +157,7 @@ fn both_impls() { // Observe the type of `z` is `u32` let _seetype: () = z; //~ ERROR mismatched types - //~| expected `()`, found `u32` + //~| NOTE expected `()`, found `u32` } @@ -172,7 +174,7 @@ fn both_impls_with_nuisance() { // Observe the type of `z` is `u32` let _seetype: () = z; //~ ERROR mismatched types - //~| expected `()`, found `u32` + //~| NOTE expected `()`, found `u32` } fn main() { diff --git a/tests/ui/methods/method-deref-to-same-trait-object-with-separate-params.stderr b/tests/ui/methods/method-deref-to-same-trait-object-with-separate-params.stderr index d6da3f2cc39..213139a9b0b 100644 --- a/tests/ui/methods/method-deref-to-same-trait-object-with-separate-params.stderr +++ b/tests/ui/methods/method-deref-to-same-trait-object-with-separate-params.stderr @@ -1,5 +1,5 @@ warning: the feature `unsized_locals` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:2:12 + --> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:4:12 | LL | #![feature(unsized_locals, unsized_fn_params)] | ^^^^^^^^^^^^^^ @@ -8,7 +8,7 @@ LL | #![feature(unsized_locals, unsized_fn_params)] = note: `#[warn(incomplete_features)]` on by default error[E0308]: mismatched types - --> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:87:24 + --> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:89:24 | LL | let _seetype: () = z; | -- ^ expected `()`, found `u32` @@ -16,7 +16,7 @@ LL | let _seetype: () = z; | expected due to this error[E0308]: mismatched types - --> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:104:24 + --> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:106:24 | LL | let _seetype: () = z; | -- ^ expected `()`, found `u64` @@ -24,23 +24,23 @@ LL | let _seetype: () = z; | expected due to this error[E0034]: multiple applicable items in scope - --> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:122:15 + --> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:124:15 | LL | let z = x.foo(); | ^^^ multiple `foo` found | note: candidate #1 is defined in the trait `FinalFoo` - --> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:59:5 + --> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:61:5 | LL | fn foo(&self) -> u8; | ^^^^^^^^^^^^^^^^^^^^ note: candidate #2 is defined in an impl of the trait `NuisanceFoo` for the type `T` - --> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:72:9 + --> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:74:9 | LL | fn foo(self) {} | ^^^^^^^^^^^^ note: candidate #3 is defined in an impl of the trait `X` for the type `T` - --> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:45:9 + --> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:47:9 | LL | fn foo(self: Smaht) -> u64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -61,7 +61,7 @@ LL + let z = X::foo(x); | error[E0308]: mismatched types - --> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:139:24 + --> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:141:24 | LL | let _seetype: () = z; | -- ^ expected `()`, found `u8` @@ -69,7 +69,7 @@ LL | let _seetype: () = z; | expected due to this error[E0308]: mismatched types - --> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:157:24 + --> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:159:24 | LL | let _seetype: () = z; | -- ^ expected `()`, found `u32` @@ -77,7 +77,7 @@ LL | let _seetype: () = z; | expected due to this error[E0308]: mismatched types - --> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:174:24 + --> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:176:24 | LL | let _seetype: () = z; | -- ^ expected `()`, found `u32` diff --git a/tests/ui/methods/method-self-arg-1.rs b/tests/ui/methods/method-self-arg-1.rs index 5912b4ec2c3..a0056b540a7 100644 --- a/tests/ui/methods/method-self-arg-1.rs +++ b/tests/ui/methods/method-self-arg-1.rs @@ -1,5 +1,7 @@ // Test method calls with self as an argument cannot subvert type checking. +//@ dont-require-annotations: NOTE + struct Foo; impl Foo { @@ -9,9 +11,9 @@ impl Foo { fn main() { let x = Foo; Foo::bar(x); //~ ERROR mismatched types - //~| expected `&Foo`, found `Foo` + //~| NOTE expected `&Foo`, found `Foo` Foo::bar(&42); //~ ERROR mismatched types - //~| expected `&Foo`, found `&{integer}` - //~| expected reference `&Foo` - //~| found reference `&{integer}` + //~| NOTE expected `&Foo`, found `&{integer}` + //~| NOTE expected reference `&Foo` + //~| NOTE found reference `&{integer}` } diff --git a/tests/ui/methods/method-self-arg-1.stderr b/tests/ui/methods/method-self-arg-1.stderr index dcc21acc5c0..1d5927da97f 100644 --- a/tests/ui/methods/method-self-arg-1.stderr +++ b/tests/ui/methods/method-self-arg-1.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/method-self-arg-1.rs:11:14 + --> $DIR/method-self-arg-1.rs:13:14 | LL | Foo::bar(x); | -------- ^ expected `&Foo`, found `Foo` @@ -7,7 +7,7 @@ LL | Foo::bar(x); | arguments to this function are incorrect | note: method defined here - --> $DIR/method-self-arg-1.rs:6:8 + --> $DIR/method-self-arg-1.rs:8:8 | LL | fn bar(&self) {} | ^^^ ----- @@ -17,7 +17,7 @@ LL | Foo::bar(&x); | + error[E0308]: mismatched types - --> $DIR/method-self-arg-1.rs:13:14 + --> $DIR/method-self-arg-1.rs:15:14 | LL | Foo::bar(&42); | -------- ^^^ expected `&Foo`, found `&{integer}` @@ -27,7 +27,7 @@ LL | Foo::bar(&42); = note: expected reference `&Foo` found reference `&{integer}` note: method defined here - --> $DIR/method-self-arg-1.rs:6:8 + --> $DIR/method-self-arg-1.rs:8:8 | LL | fn bar(&self) {} | ^^^ ----- diff --git a/tests/ui/mismatched_types/issue-13033.rs b/tests/ui/mismatched_types/issue-13033.rs index fdb356e70c5..3b08857d780 100644 --- a/tests/ui/mismatched_types/issue-13033.rs +++ b/tests/ui/mismatched_types/issue-13033.rs @@ -1,3 +1,5 @@ +//@ dont-require-annotations: NOTE + trait Foo { fn bar(&mut self, other: &mut dyn Foo); } @@ -7,8 +9,8 @@ struct Baz; impl Foo for Baz { fn bar(&mut self, other: &dyn Foo) {} //~^ ERROR method `bar` has an incompatible type for trait - //~| expected signature `fn(&mut Baz, &mut dyn Foo)` - //~| found signature `fn(&mut Baz, &dyn Foo)` + //~| NOTE expected signature `fn(&mut Baz, &mut dyn Foo)` + //~| NOTE found signature `fn(&mut Baz, &dyn Foo)` } fn main() {} diff --git a/tests/ui/mismatched_types/issue-13033.stderr b/tests/ui/mismatched_types/issue-13033.stderr index 61786ef14c2..f12f81dcfa5 100644 --- a/tests/ui/mismatched_types/issue-13033.stderr +++ b/tests/ui/mismatched_types/issue-13033.stderr @@ -1,11 +1,11 @@ error[E0053]: method `bar` has an incompatible type for trait - --> $DIR/issue-13033.rs:8:30 + --> $DIR/issue-13033.rs:10:30 | LL | fn bar(&mut self, other: &dyn Foo) {} | ^^^^^^^^ types differ in mutability | note: type in trait - --> $DIR/issue-13033.rs:2:30 + --> $DIR/issue-13033.rs:4:30 | LL | fn bar(&mut self, other: &mut dyn Foo); | ^^^^^^^^^^^^ diff --git a/tests/ui/moves/moves-based-on-type-match-bindings.rs b/tests/ui/moves/moves-based-on-type-match-bindings.rs index 4fb9b40e875..407f0976900 100644 --- a/tests/ui/moves/moves-based-on-type-match-bindings.rs +++ b/tests/ui/moves/moves-based-on-type-match-bindings.rs @@ -10,12 +10,12 @@ fn f10() { let x = Foo {f: "hi".to_string()}; let y = match x { - Foo {f} => {} + Foo {f} => {} //~ NOTE value partially moved here }; touch(&x); //~ ERROR borrow of partially moved value: `x` - //~^ value borrowed here after partial move - //~| partial move occurs because `x.f` has type `String` + //~^ NOTE value borrowed here after partial move + //~| NOTE partial move occurs because `x.f` has type `String` } fn main() {} diff --git a/tests/ui/mut/mut-pattern-mismatched.rs b/tests/ui/mut/mut-pattern-mismatched.rs index 700261fe40b..d99831bdaf5 100644 --- a/tests/ui/mut/mut-pattern-mismatched.rs +++ b/tests/ui/mut/mut-pattern-mismatched.rs @@ -1,20 +1,22 @@ +//@ dont-require-annotations: NOTE + fn main() { let foo = &mut 1; // (separate lines to ensure the spans are accurate) let &_ //~ ERROR mismatched types - //~| expected mutable reference `&mut {integer}` - //~| found reference `&_` - //~| types differ in mutability + //~| NOTE expected mutable reference `&mut {integer}` + //~| NOTE found reference `&_` + //~| NOTE types differ in mutability = foo; let &mut _ = foo; let bar = &1; let &_ = bar; let &mut _ //~ ERROR mismatched types - //~| expected reference `&{integer}` - //~| found mutable reference `&mut _` - //~| types differ in mutability + //~| NOTE expected reference `&{integer}` + //~| NOTE found mutable reference `&mut _` + //~| NOTE types differ in mutability = bar; } diff --git a/tests/ui/mut/mut-pattern-mismatched.stderr b/tests/ui/mut/mut-pattern-mismatched.stderr index cad1cef5155..25b1bfefaa2 100644 --- a/tests/ui/mut/mut-pattern-mismatched.stderr +++ b/tests/ui/mut/mut-pattern-mismatched.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/mut-pattern-mismatched.rs:6:10 + --> $DIR/mut-pattern-mismatched.rs:8:10 | LL | let &_ | ^^ types differ in mutability @@ -11,7 +11,7 @@ LL | = foo; found reference `&_` error[E0308]: mismatched types - --> $DIR/mut-pattern-mismatched.rs:15:9 + --> $DIR/mut-pattern-mismatched.rs:17:9 | LL | let &mut _ | ^^^^^^ types differ in mutability diff --git a/tests/ui/never_type/issue-10176.rs b/tests/ui/never_type/issue-10176.rs index 5ac4359c501..41e012d023f 100644 --- a/tests/ui/never_type/issue-10176.rs +++ b/tests/ui/never_type/issue-10176.rs @@ -1,9 +1,9 @@ -fn f() -> isize { +fn f() -> isize { //~ NOTE expected `isize` because of return type (return 1, return 2) //~^ ERROR mismatched types -//~| expected type `isize` -//~| found tuple `(!, !)` -//~| expected `isize`, found `(!, !)` +//~| NOTE expected type `isize` +//~| NOTE found tuple `(!, !)` +//~| NOTE expected `isize`, found `(!, !)` } fn main() {} diff --git a/tests/ui/noexporttypeexe.rs b/tests/ui/noexporttypeexe.rs index 6b4402a81f0..35257b20ccd 100644 --- a/tests/ui/noexporttypeexe.rs +++ b/tests/ui/noexporttypeexe.rs @@ -9,7 +9,8 @@ fn main() { // not convertible to a path. let x: isize = noexporttypelib::foo(); //~^ ERROR mismatched types - //~| expected type `isize` - //~| found enum `Option` - //~| expected `isize`, found `Option` + //~| NOTE expected type `isize` + //~| NOTE found enum `Option` + //~| NOTE expected `isize`, found `Option` + //~| NOTE expected due to this } diff --git a/tests/ui/numeric/integer-literal-suffix-inference.rs b/tests/ui/numeric/integer-literal-suffix-inference.rs index c320f2bb7b4..775e374e571 100644 --- a/tests/ui/numeric/integer-literal-suffix-inference.rs +++ b/tests/ui/numeric/integer-literal-suffix-inference.rs @@ -1,3 +1,5 @@ +//@ dont-require-annotations: NOTE + fn main() { // the smallest positive values that need these types @@ -37,184 +39,184 @@ fn main() { id_i8(a8); // ok id_i8(a16); //~^ ERROR mismatched types - //~| expected `i8`, found `i16` + //~| NOTE expected `i8`, found `i16` id_i8(a32); //~^ ERROR mismatched types - //~| expected `i8`, found `i32` + //~| NOTE expected `i8`, found `i32` id_i8(a64); //~^ ERROR mismatched types - //~| expected `i8`, found `i64` + //~| NOTE expected `i8`, found `i64` id_i8(asize); //~^ ERROR mismatched types - //~| expected `i8`, found `isize` + //~| NOTE expected `i8`, found `isize` id_i16(a8); //~^ ERROR mismatched types - //~| expected `i16`, found `i8` + //~| NOTE expected `i16`, found `i8` id_i16(a16); // ok id_i16(a32); //~^ ERROR mismatched types - //~| expected `i16`, found `i32` + //~| NOTE expected `i16`, found `i32` id_i16(a64); //~^ ERROR mismatched types - //~| expected `i16`, found `i64` + //~| NOTE expected `i16`, found `i64` id_i16(asize); //~^ ERROR mismatched types - //~| expected `i16`, found `isize` + //~| NOTE expected `i16`, found `isize` id_i32(a8); //~^ ERROR mismatched types - //~| expected `i32`, found `i8` + //~| NOTE expected `i32`, found `i8` id_i32(a16); //~^ ERROR mismatched types - //~| expected `i32`, found `i16` + //~| NOTE expected `i32`, found `i16` id_i32(a32); // ok id_i32(a64); //~^ ERROR mismatched types - //~| expected `i32`, found `i64` + //~| NOTE expected `i32`, found `i64` id_i32(asize); //~^ ERROR mismatched types - //~| expected `i32`, found `isize` + //~| NOTE expected `i32`, found `isize` id_i64(a8); //~^ ERROR mismatched types - //~| expected `i64`, found `i8` + //~| NOTE expected `i64`, found `i8` id_i64(a16); //~^ ERROR mismatched types - //~| expected `i64`, found `i16` + //~| NOTE expected `i64`, found `i16` id_i64(a32); //~^ ERROR mismatched types - //~| expected `i64`, found `i32` + //~| NOTE expected `i64`, found `i32` id_i64(a64); // ok id_i64(asize); //~^ ERROR mismatched types - //~| expected `i64`, found `isize` + //~| NOTE expected `i64`, found `isize` id_isize(a8); //~^ ERROR mismatched types - //~| expected `isize`, found `i8` + //~| NOTE expected `isize`, found `i8` id_isize(a16); //~^ ERROR mismatched types - //~| expected `isize`, found `i16` + //~| NOTE expected `isize`, found `i16` id_isize(a32); //~^ ERROR mismatched types - //~| expected `isize`, found `i32` + //~| NOTE expected `isize`, found `i32` id_isize(a64); //~^ ERROR mismatched types - //~| expected `isize`, found `i64` + //~| NOTE expected `isize`, found `i64` id_isize(asize); //ok id_i8(c8); // ok id_i8(c16); //~^ ERROR mismatched types - //~| expected `i8`, found `i16` + //~| NOTE expected `i8`, found `i16` id_i8(c32); //~^ ERROR mismatched types - //~| expected `i8`, found `i32` + //~| NOTE expected `i8`, found `i32` id_i8(c64); //~^ ERROR mismatched types - //~| expected `i8`, found `i64` + //~| NOTE expected `i8`, found `i64` id_i16(c8); //~^ ERROR mismatched types - //~| expected `i16`, found `i8` + //~| NOTE expected `i16`, found `i8` id_i16(c16); // ok id_i16(c32); //~^ ERROR mismatched types - //~| expected `i16`, found `i32` + //~| NOTE expected `i16`, found `i32` id_i16(c64); //~^ ERROR mismatched types - //~| expected `i16`, found `i64` + //~| NOTE expected `i16`, found `i64` id_i32(c8); //~^ ERROR mismatched types - //~| expected `i32`, found `i8` + //~| NOTE expected `i32`, found `i8` id_i32(c16); //~^ ERROR mismatched types - //~| expected `i32`, found `i16` + //~| NOTE expected `i32`, found `i16` id_i32(c32); // ok id_i32(c64); //~^ ERROR mismatched types - //~| expected `i32`, found `i64` + //~| NOTE expected `i32`, found `i64` id_i64(a8); //~^ ERROR mismatched types - //~| expected `i64`, found `i8` + //~| NOTE expected `i64`, found `i8` id_i64(a16); //~^ ERROR mismatched types - //~| expected `i64`, found `i16` + //~| NOTE expected `i64`, found `i16` id_i64(a32); //~^ ERROR mismatched types - //~| expected `i64`, found `i32` + //~| NOTE expected `i64`, found `i32` id_i64(a64); // ok id_u8(b8); // ok id_u8(b16); //~^ ERROR mismatched types - //~| expected `u8`, found `u16` + //~| NOTE expected `u8`, found `u16` id_u8(b32); //~^ ERROR mismatched types - //~| expected `u8`, found `u32` + //~| NOTE expected `u8`, found `u32` id_u8(b64); //~^ ERROR mismatched types - //~| expected `u8`, found `u64` + //~| NOTE expected `u8`, found `u64` id_u8(bsize); //~^ ERROR mismatched types - //~| expected `u8`, found `usize` + //~| NOTE expected `u8`, found `usize` id_u16(b8); //~^ ERROR mismatched types - //~| expected `u16`, found `u8` + //~| NOTE expected `u16`, found `u8` id_u16(b16); // ok id_u16(b32); //~^ ERROR mismatched types - //~| expected `u16`, found `u32` + //~| NOTE expected `u16`, found `u32` id_u16(b64); //~^ ERROR mismatched types - //~| expected `u16`, found `u64` + //~| NOTE expected `u16`, found `u64` id_u16(bsize); //~^ ERROR mismatched types - //~| expected `u16`, found `usize` + //~| NOTE expected `u16`, found `usize` id_u32(b8); //~^ ERROR mismatched types - //~| expected `u32`, found `u8` + //~| NOTE expected `u32`, found `u8` id_u32(b16); //~^ ERROR mismatched types - //~| expected `u32`, found `u16` + //~| NOTE expected `u32`, found `u16` id_u32(b32); // ok id_u32(b64); //~^ ERROR mismatched types - //~| expected `u32`, found `u64` + //~| NOTE expected `u32`, found `u64` id_u32(bsize); //~^ ERROR mismatched types - //~| expected `u32`, found `usize` + //~| NOTE expected `u32`, found `usize` id_u64(b8); //~^ ERROR mismatched types - //~| expected `u64`, found `u8` + //~| NOTE expected `u64`, found `u8` id_u64(b16); //~^ ERROR mismatched types - //~| expected `u64`, found `u16` + //~| NOTE expected `u64`, found `u16` id_u64(b32); //~^ ERROR mismatched types - //~| expected `u64`, found `u32` + //~| NOTE expected `u64`, found `u32` id_u64(b64); // ok id_u64(bsize); //~^ ERROR mismatched types - //~| expected `u64`, found `usize` + //~| NOTE expected `u64`, found `usize` id_usize(b8); //~^ ERROR mismatched types - //~| expected `usize`, found `u8` + //~| NOTE expected `usize`, found `u8` id_usize(b16); //~^ ERROR mismatched types - //~| expected `usize`, found `u16` + //~| NOTE expected `usize`, found `u16` id_usize(b32); //~^ ERROR mismatched types - //~| expected `usize`, found `u32` + //~| NOTE expected `usize`, found `u32` id_usize(b64); //~^ ERROR mismatched types - //~| expected `usize`, found `u64` + //~| NOTE expected `usize`, found `u64` id_usize(bsize); //ok } diff --git a/tests/ui/numeric/integer-literal-suffix-inference.stderr b/tests/ui/numeric/integer-literal-suffix-inference.stderr index 5045f584c89..30232e4d375 100644 --- a/tests/ui/numeric/integer-literal-suffix-inference.stderr +++ b/tests/ui/numeric/integer-literal-suffix-inference.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/integer-literal-suffix-inference.rs:38:11 + --> $DIR/integer-literal-suffix-inference.rs:40:11 | LL | id_i8(a16); | ----- ^^^ expected `i8`, found `i16` @@ -7,7 +7,7 @@ LL | id_i8(a16); | arguments to this function are incorrect | note: function defined here - --> $DIR/integer-literal-suffix-inference.rs:15:8 + --> $DIR/integer-literal-suffix-inference.rs:17:8 | LL | fn id_i8(n: i8) -> i8 { n } | ^^^^^ ----- @@ -17,7 +17,7 @@ LL | id_i8(a16.try_into().unwrap()); | ++++++++++++++++++++ error[E0308]: mismatched types - --> $DIR/integer-literal-suffix-inference.rs:41:11 + --> $DIR/integer-literal-suffix-inference.rs:43:11 | LL | id_i8(a32); | ----- ^^^ expected `i8`, found `i32` @@ -25,7 +25,7 @@ LL | id_i8(a32); | arguments to this function are incorrect | note: function defined here - --> $DIR/integer-literal-suffix-inference.rs:15:8 + --> $DIR/integer-literal-suffix-inference.rs:17:8 | LL | fn id_i8(n: i8) -> i8 { n } | ^^^^^ ----- @@ -35,7 +35,7 @@ LL | id_i8(a32.try_into().unwrap()); | ++++++++++++++++++++ error[E0308]: mismatched types - --> $DIR/integer-literal-suffix-inference.rs:44:11 + --> $DIR/integer-literal-suffix-inference.rs:46:11 | LL | id_i8(a64); | ----- ^^^ expected `i8`, found `i64` @@ -43,7 +43,7 @@ LL | id_i8(a64); | arguments to this function are incorrect | note: function defined here - --> $DIR/integer-literal-suffix-inference.rs:15:8 + --> $DIR/integer-literal-suffix-inference.rs:17:8 | LL | fn id_i8(n: i8) -> i8 { n } | ^^^^^ ----- @@ -53,7 +53,7 @@ LL | id_i8(a64.try_into().unwrap()); | ++++++++++++++++++++ error[E0308]: mismatched types - --> $DIR/integer-literal-suffix-inference.rs:47:11 + --> $DIR/integer-literal-suffix-inference.rs:49:11 | LL | id_i8(asize); | ----- ^^^^^ expected `i8`, found `isize` @@ -61,7 +61,7 @@ LL | id_i8(asize); | arguments to this function are incorrect | note: function defined here - --> $DIR/integer-literal-suffix-inference.rs:15:8 + --> $DIR/integer-literal-suffix-inference.rs:17:8 | LL | fn id_i8(n: i8) -> i8 { n } | ^^^^^ ----- @@ -71,7 +71,7 @@ LL | id_i8(asize.try_into().unwrap()); | ++++++++++++++++++++ error[E0308]: mismatched types - --> $DIR/integer-literal-suffix-inference.rs:51:12 + --> $DIR/integer-literal-suffix-inference.rs:53:12 | LL | id_i16(a8); | ------ ^^ expected `i16`, found `i8` @@ -79,7 +79,7 @@ LL | id_i16(a8); | arguments to this function are incorrect | note: function defined here - --> $DIR/integer-literal-suffix-inference.rs:16:8 + --> $DIR/integer-literal-suffix-inference.rs:18:8 | LL | fn id_i16(n: i16) -> i16 { n } | ^^^^^^ ------ @@ -89,7 +89,7 @@ LL | id_i16(a8.into()); | +++++++ error[E0308]: mismatched types - --> $DIR/integer-literal-suffix-inference.rs:55:12 + --> $DIR/integer-literal-suffix-inference.rs:57:12 | LL | id_i16(a32); | ------ ^^^ expected `i16`, found `i32` @@ -97,7 +97,7 @@ LL | id_i16(a32); | arguments to this function are incorrect | note: function defined here - --> $DIR/integer-literal-suffix-inference.rs:16:8 + --> $DIR/integer-literal-suffix-inference.rs:18:8 | LL | fn id_i16(n: i16) -> i16 { n } | ^^^^^^ ------ @@ -107,7 +107,7 @@ LL | id_i16(a32.try_into().unwrap()); | ++++++++++++++++++++ error[E0308]: mismatched types - --> $DIR/integer-literal-suffix-inference.rs:58:12 + --> $DIR/integer-literal-suffix-inference.rs:60:12 | LL | id_i16(a64); | ------ ^^^ expected `i16`, found `i64` @@ -115,7 +115,7 @@ LL | id_i16(a64); | arguments to this function are incorrect | note: function defined here - --> $DIR/integer-literal-suffix-inference.rs:16:8 + --> $DIR/integer-literal-suffix-inference.rs:18:8 | LL | fn id_i16(n: i16) -> i16 { n } | ^^^^^^ ------ @@ -125,7 +125,7 @@ LL | id_i16(a64.try_into().unwrap()); | ++++++++++++++++++++ error[E0308]: mismatched types - --> $DIR/integer-literal-suffix-inference.rs:61:12 + --> $DIR/integer-literal-suffix-inference.rs:63:12 | LL | id_i16(asize); | ------ ^^^^^ expected `i16`, found `isize` @@ -133,7 +133,7 @@ LL | id_i16(asize); | arguments to this function are incorrect | note: function defined here - --> $DIR/integer-literal-suffix-inference.rs:16:8 + --> $DIR/integer-literal-suffix-inference.rs:18:8 | LL | fn id_i16(n: i16) -> i16 { n } | ^^^^^^ ------ @@ -143,7 +143,7 @@ LL | id_i16(asize.try_into().unwrap()); | ++++++++++++++++++++ error[E0308]: mismatched types - --> $DIR/integer-literal-suffix-inference.rs:65:12 + --> $DIR/integer-literal-suffix-inference.rs:67:12 | LL | id_i32(a8); | ------ ^^ expected `i32`, found `i8` @@ -151,7 +151,7 @@ LL | id_i32(a8); | arguments to this function are incorrect | note: function defined here - --> $DIR/integer-literal-suffix-inference.rs:17:8 + --> $DIR/integer-literal-suffix-inference.rs:19:8 | LL | fn id_i32(n: i32) -> i32 { n } | ^^^^^^ ------ @@ -161,7 +161,7 @@ LL | id_i32(a8.into()); | +++++++ error[E0308]: mismatched types - --> $DIR/integer-literal-suffix-inference.rs:68:12 + --> $DIR/integer-literal-suffix-inference.rs:70:12 | LL | id_i32(a16); | ------ ^^^ expected `i32`, found `i16` @@ -169,7 +169,7 @@ LL | id_i32(a16); | arguments to this function are incorrect | note: function defined here - --> $DIR/integer-literal-suffix-inference.rs:17:8 + --> $DIR/integer-literal-suffix-inference.rs:19:8 | LL | fn id_i32(n: i32) -> i32 { n } | ^^^^^^ ------ @@ -179,7 +179,7 @@ LL | id_i32(a16.into()); | +++++++ error[E0308]: mismatched types - --> $DIR/integer-literal-suffix-inference.rs:72:12 + --> $DIR/integer-literal-suffix-inference.rs:74:12 | LL | id_i32(a64); | ------ ^^^ expected `i32`, found `i64` @@ -187,7 +187,7 @@ LL | id_i32(a64); | arguments to this function are incorrect | note: function defined here - --> $DIR/integer-literal-suffix-inference.rs:17:8 + --> $DIR/integer-literal-suffix-inference.rs:19:8 | LL | fn id_i32(n: i32) -> i32 { n } | ^^^^^^ ------ @@ -197,7 +197,7 @@ LL | id_i32(a64.try_into().unwrap()); | ++++++++++++++++++++ error[E0308]: mismatched types - --> $DIR/integer-literal-suffix-inference.rs:75:12 + --> $DIR/integer-literal-suffix-inference.rs:77:12 | LL | id_i32(asize); | ------ ^^^^^ expected `i32`, found `isize` @@ -205,7 +205,7 @@ LL | id_i32(asize); | arguments to this function are incorrect | note: function defined here - --> $DIR/integer-literal-suffix-inference.rs:17:8 + --> $DIR/integer-literal-suffix-inference.rs:19:8 | LL | fn id_i32(n: i32) -> i32 { n } | ^^^^^^ ------ @@ -215,7 +215,7 @@ LL | id_i32(asize.try_into().unwrap()); | ++++++++++++++++++++ error[E0308]: mismatched types - --> $DIR/integer-literal-suffix-inference.rs:79:12 + --> $DIR/integer-literal-suffix-inference.rs:81:12 | LL | id_i64(a8); | ------ ^^ expected `i64`, found `i8` @@ -223,7 +223,7 @@ LL | id_i64(a8); | arguments to this function are incorrect | note: function defined here - --> $DIR/integer-literal-suffix-inference.rs:18:8 + --> $DIR/integer-literal-suffix-inference.rs:20:8 | LL | fn id_i64(n: i64) -> i64 { n } | ^^^^^^ ------ @@ -233,7 +233,7 @@ LL | id_i64(a8.into()); | +++++++ error[E0308]: mismatched types - --> $DIR/integer-literal-suffix-inference.rs:82:12 + --> $DIR/integer-literal-suffix-inference.rs:84:12 | LL | id_i64(a16); | ------ ^^^ expected `i64`, found `i16` @@ -241,7 +241,7 @@ LL | id_i64(a16); | arguments to this function are incorrect | note: function defined here - --> $DIR/integer-literal-suffix-inference.rs:18:8 + --> $DIR/integer-literal-suffix-inference.rs:20:8 | LL | fn id_i64(n: i64) -> i64 { n } | ^^^^^^ ------ @@ -251,7 +251,7 @@ LL | id_i64(a16.into()); | +++++++ error[E0308]: mismatched types - --> $DIR/integer-literal-suffix-inference.rs:85:12 + --> $DIR/integer-literal-suffix-inference.rs:87:12 | LL | id_i64(a32); | ------ ^^^ expected `i64`, found `i32` @@ -259,7 +259,7 @@ LL | id_i64(a32); | arguments to this function are incorrect | note: function defined here - --> $DIR/integer-literal-suffix-inference.rs:18:8 + --> $DIR/integer-literal-suffix-inference.rs:20:8 | LL | fn id_i64(n: i64) -> i64 { n } | ^^^^^^ ------ @@ -269,7 +269,7 @@ LL | id_i64(a32.into()); | +++++++ error[E0308]: mismatched types - --> $DIR/integer-literal-suffix-inference.rs:89:12 + --> $DIR/integer-literal-suffix-inference.rs:91:12 | LL | id_i64(asize); | ------ ^^^^^ expected `i64`, found `isize` @@ -277,7 +277,7 @@ LL | id_i64(asize); | arguments to this function are incorrect | note: function defined here - --> $DIR/integer-literal-suffix-inference.rs:18:8 + --> $DIR/integer-literal-suffix-inference.rs:20:8 | LL | fn id_i64(n: i64) -> i64 { n } | ^^^^^^ ------ @@ -287,7 +287,7 @@ LL | id_i64(asize.try_into().unwrap()); | ++++++++++++++++++++ error[E0308]: mismatched types - --> $DIR/integer-literal-suffix-inference.rs:93:14 + --> $DIR/integer-literal-suffix-inference.rs:95:14 | LL | id_isize(a8); | -------- ^^ expected `isize`, found `i8` @@ -295,7 +295,7 @@ LL | id_isize(a8); | arguments to this function are incorrect | note: function defined here - --> $DIR/integer-literal-suffix-inference.rs:19:8 + --> $DIR/integer-literal-suffix-inference.rs:21:8 | LL | fn id_isize(n: isize) -> isize { n } | ^^^^^^^^ -------- @@ -305,7 +305,7 @@ LL | id_isize(a8.into()); | +++++++ error[E0308]: mismatched types - --> $DIR/integer-literal-suffix-inference.rs:96:14 + --> $DIR/integer-literal-suffix-inference.rs:98:14 | LL | id_isize(a16); | -------- ^^^ expected `isize`, found `i16` @@ -313,7 +313,7 @@ LL | id_isize(a16); | arguments to this function are incorrect | note: function defined here - --> $DIR/integer-literal-suffix-inference.rs:19:8 + --> $DIR/integer-literal-suffix-inference.rs:21:8 | LL | fn id_isize(n: isize) -> isize { n } | ^^^^^^^^ -------- @@ -323,7 +323,7 @@ LL | id_isize(a16.into()); | +++++++ error[E0308]: mismatched types - --> $DIR/integer-literal-suffix-inference.rs:99:14 + --> $DIR/integer-literal-suffix-inference.rs:101:14 | LL | id_isize(a32); | -------- ^^^ expected `isize`, found `i32` @@ -331,7 +331,7 @@ LL | id_isize(a32); | arguments to this function are incorrect | note: function defined here - --> $DIR/integer-literal-suffix-inference.rs:19:8 + --> $DIR/integer-literal-suffix-inference.rs:21:8 | LL | fn id_isize(n: isize) -> isize { n } | ^^^^^^^^ -------- @@ -341,7 +341,7 @@ LL | id_isize(a32.try_into().unwrap()); | ++++++++++++++++++++ error[E0308]: mismatched types - --> $DIR/integer-literal-suffix-inference.rs:102:14 + --> $DIR/integer-literal-suffix-inference.rs:104:14 | LL | id_isize(a64); | -------- ^^^ expected `isize`, found `i64` @@ -349,7 +349,7 @@ LL | id_isize(a64); | arguments to this function are incorrect | note: function defined here - --> $DIR/integer-literal-suffix-inference.rs:19:8 + --> $DIR/integer-literal-suffix-inference.rs:21:8 | LL | fn id_isize(n: isize) -> isize { n } | ^^^^^^^^ -------- @@ -359,7 +359,7 @@ LL | id_isize(a64.try_into().unwrap()); | ++++++++++++++++++++ error[E0308]: mismatched types - --> $DIR/integer-literal-suffix-inference.rs:108:11 + --> $DIR/integer-literal-suffix-inference.rs:110:11 | LL | id_i8(c16); | ----- ^^^ expected `i8`, found `i16` @@ -367,7 +367,7 @@ LL | id_i8(c16); | arguments to this function are incorrect | note: function defined here - --> $DIR/integer-literal-suffix-inference.rs:15:8 + --> $DIR/integer-literal-suffix-inference.rs:17:8 | LL | fn id_i8(n: i8) -> i8 { n } | ^^^^^ ----- @@ -377,7 +377,7 @@ LL | id_i8(c16.try_into().unwrap()); | ++++++++++++++++++++ error[E0308]: mismatched types - --> $DIR/integer-literal-suffix-inference.rs:111:11 + --> $DIR/integer-literal-suffix-inference.rs:113:11 | LL | id_i8(c32); | ----- ^^^ expected `i8`, found `i32` @@ -385,7 +385,7 @@ LL | id_i8(c32); | arguments to this function are incorrect | note: function defined here - --> $DIR/integer-literal-suffix-inference.rs:15:8 + --> $DIR/integer-literal-suffix-inference.rs:17:8 | LL | fn id_i8(n: i8) -> i8 { n } | ^^^^^ ----- @@ -395,7 +395,7 @@ LL | id_i8(c32.try_into().unwrap()); | ++++++++++++++++++++ error[E0308]: mismatched types - --> $DIR/integer-literal-suffix-inference.rs:114:11 + --> $DIR/integer-literal-suffix-inference.rs:116:11 | LL | id_i8(c64); | ----- ^^^ expected `i8`, found `i64` @@ -403,7 +403,7 @@ LL | id_i8(c64); | arguments to this function are incorrect | note: function defined here - --> $DIR/integer-literal-suffix-inference.rs:15:8 + --> $DIR/integer-literal-suffix-inference.rs:17:8 | LL | fn id_i8(n: i8) -> i8 { n } | ^^^^^ ----- @@ -413,7 +413,7 @@ LL | id_i8(c64.try_into().unwrap()); | ++++++++++++++++++++ error[E0308]: mismatched types - --> $DIR/integer-literal-suffix-inference.rs:118:12 + --> $DIR/integer-literal-suffix-inference.rs:120:12 | LL | id_i16(c8); | ------ ^^ expected `i16`, found `i8` @@ -421,7 +421,7 @@ LL | id_i16(c8); | arguments to this function are incorrect | note: function defined here - --> $DIR/integer-literal-suffix-inference.rs:16:8 + --> $DIR/integer-literal-suffix-inference.rs:18:8 | LL | fn id_i16(n: i16) -> i16 { n } | ^^^^^^ ------ @@ -431,7 +431,7 @@ LL | id_i16(c8.into()); | +++++++ error[E0308]: mismatched types - --> $DIR/integer-literal-suffix-inference.rs:122:12 + --> $DIR/integer-literal-suffix-inference.rs:124:12 | LL | id_i16(c32); | ------ ^^^ expected `i16`, found `i32` @@ -439,7 +439,7 @@ LL | id_i16(c32); | arguments to this function are incorrect | note: function defined here - --> $DIR/integer-literal-suffix-inference.rs:16:8 + --> $DIR/integer-literal-suffix-inference.rs:18:8 | LL | fn id_i16(n: i16) -> i16 { n } | ^^^^^^ ------ @@ -449,7 +449,7 @@ LL | id_i16(c32.try_into().unwrap()); | ++++++++++++++++++++ error[E0308]: mismatched types - --> $DIR/integer-literal-suffix-inference.rs:125:12 + --> $DIR/integer-literal-suffix-inference.rs:127:12 | LL | id_i16(c64); | ------ ^^^ expected `i16`, found `i64` @@ -457,7 +457,7 @@ LL | id_i16(c64); | arguments to this function are incorrect | note: function defined here - --> $DIR/integer-literal-suffix-inference.rs:16:8 + --> $DIR/integer-literal-suffix-inference.rs:18:8 | LL | fn id_i16(n: i16) -> i16 { n } | ^^^^^^ ------ @@ -467,7 +467,7 @@ LL | id_i16(c64.try_into().unwrap()); | ++++++++++++++++++++ error[E0308]: mismatched types - --> $DIR/integer-literal-suffix-inference.rs:129:12 + --> $DIR/integer-literal-suffix-inference.rs:131:12 | LL | id_i32(c8); | ------ ^^ expected `i32`, found `i8` @@ -475,7 +475,7 @@ LL | id_i32(c8); | arguments to this function are incorrect | note: function defined here - --> $DIR/integer-literal-suffix-inference.rs:17:8 + --> $DIR/integer-literal-suffix-inference.rs:19:8 | LL | fn id_i32(n: i32) -> i32 { n } | ^^^^^^ ------ @@ -485,7 +485,7 @@ LL | id_i32(c8.into()); | +++++++ error[E0308]: mismatched types - --> $DIR/integer-literal-suffix-inference.rs:132:12 + --> $DIR/integer-literal-suffix-inference.rs:134:12 | LL | id_i32(c16); | ------ ^^^ expected `i32`, found `i16` @@ -493,7 +493,7 @@ LL | id_i32(c16); | arguments to this function are incorrect | note: function defined here - --> $DIR/integer-literal-suffix-inference.rs:17:8 + --> $DIR/integer-literal-suffix-inference.rs:19:8 | LL | fn id_i32(n: i32) -> i32 { n } | ^^^^^^ ------ @@ -503,7 +503,7 @@ LL | id_i32(c16.into()); | +++++++ error[E0308]: mismatched types - --> $DIR/integer-literal-suffix-inference.rs:136:12 + --> $DIR/integer-literal-suffix-inference.rs:138:12 | LL | id_i32(c64); | ------ ^^^ expected `i32`, found `i64` @@ -511,7 +511,7 @@ LL | id_i32(c64); | arguments to this function are incorrect | note: function defined here - --> $DIR/integer-literal-suffix-inference.rs:17:8 + --> $DIR/integer-literal-suffix-inference.rs:19:8 | LL | fn id_i32(n: i32) -> i32 { n } | ^^^^^^ ------ @@ -521,7 +521,7 @@ LL | id_i32(c64.try_into().unwrap()); | ++++++++++++++++++++ error[E0308]: mismatched types - --> $DIR/integer-literal-suffix-inference.rs:140:12 + --> $DIR/integer-literal-suffix-inference.rs:142:12 | LL | id_i64(a8); | ------ ^^ expected `i64`, found `i8` @@ -529,7 +529,7 @@ LL | id_i64(a8); | arguments to this function are incorrect | note: function defined here - --> $DIR/integer-literal-suffix-inference.rs:18:8 + --> $DIR/integer-literal-suffix-inference.rs:20:8 | LL | fn id_i64(n: i64) -> i64 { n } | ^^^^^^ ------ @@ -539,7 +539,7 @@ LL | id_i64(a8.into()); | +++++++ error[E0308]: mismatched types - --> $DIR/integer-literal-suffix-inference.rs:143:12 + --> $DIR/integer-literal-suffix-inference.rs:145:12 | LL | id_i64(a16); | ------ ^^^ expected `i64`, found `i16` @@ -547,7 +547,7 @@ LL | id_i64(a16); | arguments to this function are incorrect | note: function defined here - --> $DIR/integer-literal-suffix-inference.rs:18:8 + --> $DIR/integer-literal-suffix-inference.rs:20:8 | LL | fn id_i64(n: i64) -> i64 { n } | ^^^^^^ ------ @@ -557,7 +557,7 @@ LL | id_i64(a16.into()); | +++++++ error[E0308]: mismatched types - --> $DIR/integer-literal-suffix-inference.rs:146:12 + --> $DIR/integer-literal-suffix-inference.rs:148:12 | LL | id_i64(a32); | ------ ^^^ expected `i64`, found `i32` @@ -565,7 +565,7 @@ LL | id_i64(a32); | arguments to this function are incorrect | note: function defined here - --> $DIR/integer-literal-suffix-inference.rs:18:8 + --> $DIR/integer-literal-suffix-inference.rs:20:8 | LL | fn id_i64(n: i64) -> i64 { n } | ^^^^^^ ------ @@ -575,7 +575,7 @@ LL | id_i64(a32.into()); | +++++++ error[E0308]: mismatched types - --> $DIR/integer-literal-suffix-inference.rs:152:11 + --> $DIR/integer-literal-suffix-inference.rs:154:11 | LL | id_u8(b16); | ----- ^^^ expected `u8`, found `u16` @@ -583,7 +583,7 @@ LL | id_u8(b16); | arguments to this function are incorrect | note: function defined here - --> $DIR/integer-literal-suffix-inference.rs:27:8 + --> $DIR/integer-literal-suffix-inference.rs:29:8 | LL | fn id_u8(n: u8) -> u8 { n } | ^^^^^ ----- @@ -593,7 +593,7 @@ LL | id_u8(b16.try_into().unwrap()); | ++++++++++++++++++++ error[E0308]: mismatched types - --> $DIR/integer-literal-suffix-inference.rs:155:11 + --> $DIR/integer-literal-suffix-inference.rs:157:11 | LL | id_u8(b32); | ----- ^^^ expected `u8`, found `u32` @@ -601,7 +601,7 @@ LL | id_u8(b32); | arguments to this function are incorrect | note: function defined here - --> $DIR/integer-literal-suffix-inference.rs:27:8 + --> $DIR/integer-literal-suffix-inference.rs:29:8 | LL | fn id_u8(n: u8) -> u8 { n } | ^^^^^ ----- @@ -611,7 +611,7 @@ LL | id_u8(b32.try_into().unwrap()); | ++++++++++++++++++++ error[E0308]: mismatched types - --> $DIR/integer-literal-suffix-inference.rs:158:11 + --> $DIR/integer-literal-suffix-inference.rs:160:11 | LL | id_u8(b64); | ----- ^^^ expected `u8`, found `u64` @@ -619,7 +619,7 @@ LL | id_u8(b64); | arguments to this function are incorrect | note: function defined here - --> $DIR/integer-literal-suffix-inference.rs:27:8 + --> $DIR/integer-literal-suffix-inference.rs:29:8 | LL | fn id_u8(n: u8) -> u8 { n } | ^^^^^ ----- @@ -629,7 +629,7 @@ LL | id_u8(b64.try_into().unwrap()); | ++++++++++++++++++++ error[E0308]: mismatched types - --> $DIR/integer-literal-suffix-inference.rs:161:11 + --> $DIR/integer-literal-suffix-inference.rs:163:11 | LL | id_u8(bsize); | ----- ^^^^^ expected `u8`, found `usize` @@ -637,7 +637,7 @@ LL | id_u8(bsize); | arguments to this function are incorrect | note: function defined here - --> $DIR/integer-literal-suffix-inference.rs:27:8 + --> $DIR/integer-literal-suffix-inference.rs:29:8 | LL | fn id_u8(n: u8) -> u8 { n } | ^^^^^ ----- @@ -647,7 +647,7 @@ LL | id_u8(bsize.try_into().unwrap()); | ++++++++++++++++++++ error[E0308]: mismatched types - --> $DIR/integer-literal-suffix-inference.rs:165:12 + --> $DIR/integer-literal-suffix-inference.rs:167:12 | LL | id_u16(b8); | ------ ^^ expected `u16`, found `u8` @@ -655,7 +655,7 @@ LL | id_u16(b8); | arguments to this function are incorrect | note: function defined here - --> $DIR/integer-literal-suffix-inference.rs:28:8 + --> $DIR/integer-literal-suffix-inference.rs:30:8 | LL | fn id_u16(n: u16) -> u16 { n } | ^^^^^^ ------ @@ -665,7 +665,7 @@ LL | id_u16(b8.into()); | +++++++ error[E0308]: mismatched types - --> $DIR/integer-literal-suffix-inference.rs:169:12 + --> $DIR/integer-literal-suffix-inference.rs:171:12 | LL | id_u16(b32); | ------ ^^^ expected `u16`, found `u32` @@ -673,7 +673,7 @@ LL | id_u16(b32); | arguments to this function are incorrect | note: function defined here - --> $DIR/integer-literal-suffix-inference.rs:28:8 + --> $DIR/integer-literal-suffix-inference.rs:30:8 | LL | fn id_u16(n: u16) -> u16 { n } | ^^^^^^ ------ @@ -683,7 +683,7 @@ LL | id_u16(b32.try_into().unwrap()); | ++++++++++++++++++++ error[E0308]: mismatched types - --> $DIR/integer-literal-suffix-inference.rs:172:12 + --> $DIR/integer-literal-suffix-inference.rs:174:12 | LL | id_u16(b64); | ------ ^^^ expected `u16`, found `u64` @@ -691,7 +691,7 @@ LL | id_u16(b64); | arguments to this function are incorrect | note: function defined here - --> $DIR/integer-literal-suffix-inference.rs:28:8 + --> $DIR/integer-literal-suffix-inference.rs:30:8 | LL | fn id_u16(n: u16) -> u16 { n } | ^^^^^^ ------ @@ -701,7 +701,7 @@ LL | id_u16(b64.try_into().unwrap()); | ++++++++++++++++++++ error[E0308]: mismatched types - --> $DIR/integer-literal-suffix-inference.rs:175:12 + --> $DIR/integer-literal-suffix-inference.rs:177:12 | LL | id_u16(bsize); | ------ ^^^^^ expected `u16`, found `usize` @@ -709,7 +709,7 @@ LL | id_u16(bsize); | arguments to this function are incorrect | note: function defined here - --> $DIR/integer-literal-suffix-inference.rs:28:8 + --> $DIR/integer-literal-suffix-inference.rs:30:8 | LL | fn id_u16(n: u16) -> u16 { n } | ^^^^^^ ------ @@ -719,7 +719,7 @@ LL | id_u16(bsize.try_into().unwrap()); | ++++++++++++++++++++ error[E0308]: mismatched types - --> $DIR/integer-literal-suffix-inference.rs:179:12 + --> $DIR/integer-literal-suffix-inference.rs:181:12 | LL | id_u32(b8); | ------ ^^ expected `u32`, found `u8` @@ -727,7 +727,7 @@ LL | id_u32(b8); | arguments to this function are incorrect | note: function defined here - --> $DIR/integer-literal-suffix-inference.rs:29:8 + --> $DIR/integer-literal-suffix-inference.rs:31:8 | LL | fn id_u32(n: u32) -> u32 { n } | ^^^^^^ ------ @@ -737,7 +737,7 @@ LL | id_u32(b8.into()); | +++++++ error[E0308]: mismatched types - --> $DIR/integer-literal-suffix-inference.rs:182:12 + --> $DIR/integer-literal-suffix-inference.rs:184:12 | LL | id_u32(b16); | ------ ^^^ expected `u32`, found `u16` @@ -745,7 +745,7 @@ LL | id_u32(b16); | arguments to this function are incorrect | note: function defined here - --> $DIR/integer-literal-suffix-inference.rs:29:8 + --> $DIR/integer-literal-suffix-inference.rs:31:8 | LL | fn id_u32(n: u32) -> u32 { n } | ^^^^^^ ------ @@ -755,7 +755,7 @@ LL | id_u32(b16.into()); | +++++++ error[E0308]: mismatched types - --> $DIR/integer-literal-suffix-inference.rs:186:12 + --> $DIR/integer-literal-suffix-inference.rs:188:12 | LL | id_u32(b64); | ------ ^^^ expected `u32`, found `u64` @@ -763,7 +763,7 @@ LL | id_u32(b64); | arguments to this function are incorrect | note: function defined here - --> $DIR/integer-literal-suffix-inference.rs:29:8 + --> $DIR/integer-literal-suffix-inference.rs:31:8 | LL | fn id_u32(n: u32) -> u32 { n } | ^^^^^^ ------ @@ -773,7 +773,7 @@ LL | id_u32(b64.try_into().unwrap()); | ++++++++++++++++++++ error[E0308]: mismatched types - --> $DIR/integer-literal-suffix-inference.rs:189:12 + --> $DIR/integer-literal-suffix-inference.rs:191:12 | LL | id_u32(bsize); | ------ ^^^^^ expected `u32`, found `usize` @@ -781,7 +781,7 @@ LL | id_u32(bsize); | arguments to this function are incorrect | note: function defined here - --> $DIR/integer-literal-suffix-inference.rs:29:8 + --> $DIR/integer-literal-suffix-inference.rs:31:8 | LL | fn id_u32(n: u32) -> u32 { n } | ^^^^^^ ------ @@ -791,7 +791,7 @@ LL | id_u32(bsize.try_into().unwrap()); | ++++++++++++++++++++ error[E0308]: mismatched types - --> $DIR/integer-literal-suffix-inference.rs:193:12 + --> $DIR/integer-literal-suffix-inference.rs:195:12 | LL | id_u64(b8); | ------ ^^ expected `u64`, found `u8` @@ -799,7 +799,7 @@ LL | id_u64(b8); | arguments to this function are incorrect | note: function defined here - --> $DIR/integer-literal-suffix-inference.rs:30:8 + --> $DIR/integer-literal-suffix-inference.rs:32:8 | LL | fn id_u64(n: u64) -> u64 { n } | ^^^^^^ ------ @@ -809,7 +809,7 @@ LL | id_u64(b8.into()); | +++++++ error[E0308]: mismatched types - --> $DIR/integer-literal-suffix-inference.rs:196:12 + --> $DIR/integer-literal-suffix-inference.rs:198:12 | LL | id_u64(b16); | ------ ^^^ expected `u64`, found `u16` @@ -817,7 +817,7 @@ LL | id_u64(b16); | arguments to this function are incorrect | note: function defined here - --> $DIR/integer-literal-suffix-inference.rs:30:8 + --> $DIR/integer-literal-suffix-inference.rs:32:8 | LL | fn id_u64(n: u64) -> u64 { n } | ^^^^^^ ------ @@ -827,7 +827,7 @@ LL | id_u64(b16.into()); | +++++++ error[E0308]: mismatched types - --> $DIR/integer-literal-suffix-inference.rs:199:12 + --> $DIR/integer-literal-suffix-inference.rs:201:12 | LL | id_u64(b32); | ------ ^^^ expected `u64`, found `u32` @@ -835,7 +835,7 @@ LL | id_u64(b32); | arguments to this function are incorrect | note: function defined here - --> $DIR/integer-literal-suffix-inference.rs:30:8 + --> $DIR/integer-literal-suffix-inference.rs:32:8 | LL | fn id_u64(n: u64) -> u64 { n } | ^^^^^^ ------ @@ -845,7 +845,7 @@ LL | id_u64(b32.into()); | +++++++ error[E0308]: mismatched types - --> $DIR/integer-literal-suffix-inference.rs:203:12 + --> $DIR/integer-literal-suffix-inference.rs:205:12 | LL | id_u64(bsize); | ------ ^^^^^ expected `u64`, found `usize` @@ -853,7 +853,7 @@ LL | id_u64(bsize); | arguments to this function are incorrect | note: function defined here - --> $DIR/integer-literal-suffix-inference.rs:30:8 + --> $DIR/integer-literal-suffix-inference.rs:32:8 | LL | fn id_u64(n: u64) -> u64 { n } | ^^^^^^ ------ @@ -863,7 +863,7 @@ LL | id_u64(bsize.try_into().unwrap()); | ++++++++++++++++++++ error[E0308]: mismatched types - --> $DIR/integer-literal-suffix-inference.rs:207:14 + --> $DIR/integer-literal-suffix-inference.rs:209:14 | LL | id_usize(b8); | -------- ^^ expected `usize`, found `u8` @@ -871,7 +871,7 @@ LL | id_usize(b8); | arguments to this function are incorrect | note: function defined here - --> $DIR/integer-literal-suffix-inference.rs:31:8 + --> $DIR/integer-literal-suffix-inference.rs:33:8 | LL | fn id_usize(n: usize) -> usize { n } | ^^^^^^^^ -------- @@ -881,7 +881,7 @@ LL | id_usize(b8.into()); | +++++++ error[E0308]: mismatched types - --> $DIR/integer-literal-suffix-inference.rs:210:14 + --> $DIR/integer-literal-suffix-inference.rs:212:14 | LL | id_usize(b16); | -------- ^^^ expected `usize`, found `u16` @@ -889,7 +889,7 @@ LL | id_usize(b16); | arguments to this function are incorrect | note: function defined here - --> $DIR/integer-literal-suffix-inference.rs:31:8 + --> $DIR/integer-literal-suffix-inference.rs:33:8 | LL | fn id_usize(n: usize) -> usize { n } | ^^^^^^^^ -------- @@ -899,7 +899,7 @@ LL | id_usize(b16.into()); | +++++++ error[E0308]: mismatched types - --> $DIR/integer-literal-suffix-inference.rs:213:14 + --> $DIR/integer-literal-suffix-inference.rs:215:14 | LL | id_usize(b32); | -------- ^^^ expected `usize`, found `u32` @@ -907,7 +907,7 @@ LL | id_usize(b32); | arguments to this function are incorrect | note: function defined here - --> $DIR/integer-literal-suffix-inference.rs:31:8 + --> $DIR/integer-literal-suffix-inference.rs:33:8 | LL | fn id_usize(n: usize) -> usize { n } | ^^^^^^^^ -------- @@ -917,7 +917,7 @@ LL | id_usize(b32.try_into().unwrap()); | ++++++++++++++++++++ error[E0308]: mismatched types - --> $DIR/integer-literal-suffix-inference.rs:216:14 + --> $DIR/integer-literal-suffix-inference.rs:218:14 | LL | id_usize(b64); | -------- ^^^ expected `usize`, found `u64` @@ -925,7 +925,7 @@ LL | id_usize(b64); | arguments to this function are incorrect | note: function defined here - --> $DIR/integer-literal-suffix-inference.rs:31:8 + --> $DIR/integer-literal-suffix-inference.rs:33:8 | LL | fn id_usize(n: usize) -> usize { n } | ^^^^^^^^ -------- diff --git a/tests/ui/parser/diagnostics-parenthesized-type-arguments-ice-issue-122345.rs b/tests/ui/parser/diagnostics-parenthesized-type-arguments-ice-issue-122345.rs index 47df107a261..6bfe16ae37d 100644 --- a/tests/ui/parser/diagnostics-parenthesized-type-arguments-ice-issue-122345.rs +++ b/tests/ui/parser/diagnostics-parenthesized-type-arguments-ice-issue-122345.rs @@ -1,7 +1,9 @@ +//@ dont-require-annotations: NOTE + fn main() { unsafe { dealloc(ptr2, Layout::(x: !)(1, 1)); //~ ERROR: expected one of `!`, `(`, `)`, `+`, `,`, `::`, or `<`, found `:` //~^ ERROR: expected one of `.`, `;`, `?`, `}`, or an operator, found `)` - //~| while parsing this parenthesized list of type arguments starting here + //~| NOTE while parsing this parenthesized list of type arguments starting here } } diff --git a/tests/ui/parser/diagnostics-parenthesized-type-arguments-ice-issue-122345.stderr b/tests/ui/parser/diagnostics-parenthesized-type-arguments-ice-issue-122345.stderr index 8067c97ae4b..c12bf7f9e3f 100644 --- a/tests/ui/parser/diagnostics-parenthesized-type-arguments-ice-issue-122345.stderr +++ b/tests/ui/parser/diagnostics-parenthesized-type-arguments-ice-issue-122345.stderr @@ -1,5 +1,5 @@ error: expected one of `!`, `(`, `)`, `+`, `,`, `::`, or `<`, found `:` - --> $DIR/diagnostics-parenthesized-type-arguments-ice-issue-122345.rs:3:33 + --> $DIR/diagnostics-parenthesized-type-arguments-ice-issue-122345.rs:5:33 | LL | dealloc(ptr2, Layout::(x: !)(1, 1)); | --- ^ expected one of 7 possible tokens @@ -7,7 +7,7 @@ LL | dealloc(ptr2, Layout::(x: !)(1, 1)); | while parsing this parenthesized list of type arguments starting here error: expected one of `.`, `;`, `?`, `}`, or an operator, found `)` - --> $DIR/diagnostics-parenthesized-type-arguments-ice-issue-122345.rs:3:43 + --> $DIR/diagnostics-parenthesized-type-arguments-ice-issue-122345.rs:5:43 | LL | dealloc(ptr2, Layout::(x: !)(1, 1)); | ^ expected one of `.`, `;`, `?`, `}`, or an operator diff --git a/tests/ui/parser/do-catch-suggests-try.rs b/tests/ui/parser/do-catch-suggests-try.rs index fcd55ce4059..af85373e120 100644 --- a/tests/ui/parser/do-catch-suggests-try.rs +++ b/tests/ui/parser/do-catch-suggests-try.rs @@ -1,10 +1,12 @@ +//@ dont-require-annotations: NOTE + #![feature(try_blocks)] fn main() { let _: Option<()> = do catch {}; //~^ ERROR found removed `do catch` syntax //~| HELP replace with the new syntax - //~| following RFC #2388, the new non-placeholder syntax is `try` + //~| NOTE following RFC #2388, the new non-placeholder syntax is `try` let _recovery_witness: () = 1; //~ ERROR mismatched types } diff --git a/tests/ui/parser/do-catch-suggests-try.stderr b/tests/ui/parser/do-catch-suggests-try.stderr index 2eaab836075..eecf588c5e9 100644 --- a/tests/ui/parser/do-catch-suggests-try.stderr +++ b/tests/ui/parser/do-catch-suggests-try.stderr @@ -1,5 +1,5 @@ error: found removed `do catch` syntax - --> $DIR/do-catch-suggests-try.rs:4:25 + --> $DIR/do-catch-suggests-try.rs:6:25 | LL | let _: Option<()> = do catch {}; | ^^^^^^^^ @@ -12,7 +12,7 @@ LL + let _: Option<()> = try {}; | error[E0308]: mismatched types - --> $DIR/do-catch-suggests-try.rs:9:33 + --> $DIR/do-catch-suggests-try.rs:11:33 | LL | let _recovery_witness: () = 1; | -- ^ expected `()`, found integer diff --git a/tests/ui/parser/mut-patterns.rs b/tests/ui/parser/mut-patterns.rs index ed33968c627..a2af8160740 100644 --- a/tests/ui/parser/mut-patterns.rs +++ b/tests/ui/parser/mut-patterns.rs @@ -1,6 +1,7 @@ // Can't put mut in non-ident pattern //@ edition:2018 +//@ dont-require-annotations: HELP #![feature(box_patterns)] #![allow(warnings)] @@ -13,20 +14,20 @@ pub fn main() { let mut mut x = 0; //~^ ERROR `mut` on a binding may not be repeated - //~| remove the additional `mut`s + //~| HELP remove the additional `mut`s let mut mut mut mut mut x = 0; //~^ ERROR `mut` on a binding may not be repeated - //~| remove the additional `mut`s + //~| HELP remove the additional `mut`s struct Foo { x: isize } let mut Foo { x: x } = Foo { x: 3 }; //~^ ERROR `mut` must be attached to each individual binding - //~| add `mut` to each binding + //~| HELP add `mut` to each binding let mut Foo { x } = Foo { x: 3 }; //~^ ERROR `mut` must be attached to each individual binding - //~| add `mut` to each binding + //~| HELP add `mut` to each binding struct r#yield(u8, u8); let mut mut yield(become, await) = r#yield(0, 0); diff --git a/tests/ui/parser/mut-patterns.stderr b/tests/ui/parser/mut-patterns.stderr index 9dda2499f03..70099989c9f 100644 --- a/tests/ui/parser/mut-patterns.stderr +++ b/tests/ui/parser/mut-patterns.stderr @@ -1,5 +1,5 @@ error: `mut` must be followed by a named binding - --> $DIR/mut-patterns.rs:9:9 + --> $DIR/mut-patterns.rs:10:9 | LL | let mut _ = 0; | ^^^^ @@ -12,7 +12,7 @@ LL + let _ = 0; | error: `mut` must be followed by a named binding - --> $DIR/mut-patterns.rs:10:9 + --> $DIR/mut-patterns.rs:11:9 | LL | let mut (_, _) = (0, 0); | ^^^^ @@ -25,7 +25,7 @@ LL + let (_, _) = (0, 0); | error: `mut` must be attached to each individual binding - --> $DIR/mut-patterns.rs:12:9 + --> $DIR/mut-patterns.rs:13:9 | LL | let mut (x @ y) = 0; | ^^^^^^^^^^^ @@ -38,7 +38,7 @@ LL + let (mut x @ mut y) = 0; | error: `mut` on a binding may not be repeated - --> $DIR/mut-patterns.rs:14:13 + --> $DIR/mut-patterns.rs:15:13 | LL | let mut mut x = 0; | ^^^ @@ -50,7 +50,7 @@ LL + let mut x = 0; | error: `mut` on a binding may not be repeated - --> $DIR/mut-patterns.rs:18:13 + --> $DIR/mut-patterns.rs:19:13 | LL | let mut mut mut mut mut x = 0; | ^^^^^^^^^^^^^^^ @@ -62,7 +62,7 @@ LL + let mut x = 0; | error: `mut` must be attached to each individual binding - --> $DIR/mut-patterns.rs:23:9 + --> $DIR/mut-patterns.rs:24:9 | LL | let mut Foo { x: x } = Foo { x: 3 }; | ^^^^^^^^^^^^^^^^ @@ -75,7 +75,7 @@ LL + let Foo { x: mut x } = Foo { x: 3 }; | error: `mut` must be attached to each individual binding - --> $DIR/mut-patterns.rs:27:9 + --> $DIR/mut-patterns.rs:28:9 | LL | let mut Foo { x } = Foo { x: 3 }; | ^^^^^^^^^^^^^ @@ -88,7 +88,7 @@ LL + let Foo { mut x } = Foo { x: 3 }; | error: `mut` on a binding may not be repeated - --> $DIR/mut-patterns.rs:32:13 + --> $DIR/mut-patterns.rs:33:13 | LL | let mut mut yield(become, await) = r#yield(0, 0); | ^^^ @@ -100,7 +100,7 @@ LL + let mut yield(become, await) = r#yield(0, 0); | error: expected identifier, found reserved keyword `yield` - --> $DIR/mut-patterns.rs:32:17 + --> $DIR/mut-patterns.rs:33:17 | LL | let mut mut yield(become, await) = r#yield(0, 0); | ^^^^^ expected identifier, found reserved keyword @@ -111,7 +111,7 @@ LL | let mut mut r#yield(become, await) = r#yield(0, 0); | ++ error: expected identifier, found reserved keyword `become` - --> $DIR/mut-patterns.rs:32:23 + --> $DIR/mut-patterns.rs:33:23 | LL | let mut mut yield(become, await) = r#yield(0, 0); | ^^^^^^ expected identifier, found reserved keyword @@ -122,7 +122,7 @@ LL | let mut mut yield(r#become, await) = r#yield(0, 0); | ++ error: expected identifier, found keyword `await` - --> $DIR/mut-patterns.rs:32:31 + --> $DIR/mut-patterns.rs:33:31 | LL | let mut mut yield(become, await) = r#yield(0, 0); | ^^^^^ expected identifier, found keyword @@ -133,7 +133,7 @@ LL | let mut mut yield(become, r#await) = r#yield(0, 0); | ++ error: `mut` must be followed by a named binding - --> $DIR/mut-patterns.rs:32:9 + --> $DIR/mut-patterns.rs:33:9 | LL | let mut mut yield(become, await) = r#yield(0, 0); | ^^^^^^^^ @@ -146,7 +146,7 @@ LL + let yield(become, await) = r#yield(0, 0); | error: `mut` must be attached to each individual binding - --> $DIR/mut-patterns.rs:41:9 + --> $DIR/mut-patterns.rs:42:9 | LL | let mut W(mut a, W(b, W(ref c, W(d, B { box f })))) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -159,7 +159,7 @@ LL + let W(mut a, W(mut b, W(ref c, W(mut d, B { box mut f })))) | error: expected identifier, found metavariable - --> $DIR/mut-patterns.rs:48:21 + --> $DIR/mut-patterns.rs:49:21 | LL | let mut $p = 0; | ^^ expected identifier, found metavariable diff --git a/tests/ui/parser/recover/recover-pat-exprs.rs b/tests/ui/parser/recover/recover-pat-exprs.rs index a78bb82828d..41b44ec9642 100644 --- a/tests/ui/parser/recover/recover-pat-exprs.rs +++ b/tests/ui/parser/recover/recover-pat-exprs.rs @@ -1,3 +1,5 @@ +//@ dont-require-annotations: HELP + // FieldExpression, TupleIndexingExpression fn field_access() { match 0 { @@ -28,7 +30,7 @@ fn array_indexing() { { let x[0; 20]; } //~ error: expected one of `:`, `;`, `=`, `@`, or `|`, found `[` { let x[]; } //~ error: expected one of `:`, `;`, `=`, `@`, or `|`, found `[` { let (x[]); } //~ error: expected one of `)`, `,`, `@`, `if`, or `|`, found `[` - //~^ missing `,` + //~^ HELP missing `,` } // MethodCallExpression, CallExpression, ErrorPropagationExpression diff --git a/tests/ui/parser/recover/recover-pat-exprs.stderr b/tests/ui/parser/recover/recover-pat-exprs.stderr index 69bc5107cca..33000022b8f 100644 --- a/tests/ui/parser/recover/recover-pat-exprs.stderr +++ b/tests/ui/parser/recover/recover-pat-exprs.stderr @@ -1,5 +1,5 @@ error: expected a pattern, found an expression - --> $DIR/recover-pat-exprs.rs:5:9 + --> $DIR/recover-pat-exprs.rs:7:9 | LL | x.y => (), | ^^^ not a pattern @@ -19,7 +19,7 @@ LL ~ VAL => (), | error: expected a pattern, found an expression - --> $DIR/recover-pat-exprs.rs:6:9 + --> $DIR/recover-pat-exprs.rs:8:9 | LL | x.0 => (), | ^^^ not a pattern @@ -40,7 +40,7 @@ LL ~ VAL => (), | error: expected a pattern, found an expression - --> $DIR/recover-pat-exprs.rs:7:9 + --> $DIR/recover-pat-exprs.rs:9:9 | LL | x._0 => (), | ^^^^ not a pattern @@ -62,7 +62,7 @@ LL ~ VAL => (), | error: expected a pattern, found an expression - --> $DIR/recover-pat-exprs.rs:8:9 + --> $DIR/recover-pat-exprs.rs:10:9 | LL | x.0.1 => (), | ^^^^^ not a pattern @@ -84,7 +84,7 @@ LL ~ VAL => (), | error: expected a pattern, found an expression - --> $DIR/recover-pat-exprs.rs:9:9 + --> $DIR/recover-pat-exprs.rs:11:9 | LL | x.4.y.17.__z => (), | ^^^^^^^^^^^^ not a pattern @@ -106,37 +106,37 @@ LL ~ VAL => (), | error: expected one of `:`, `;`, `=`, `@`, or `|`, found `.` - --> $DIR/recover-pat-exprs.rs:12:12 + --> $DIR/recover-pat-exprs.rs:14:12 | LL | { let x.0e0; } | ^ expected one of `:`, `;`, `=`, `@`, or `|` error: expected one of `:`, `;`, `=`, `@`, or `|`, found `.` - --> $DIR/recover-pat-exprs.rs:13:12 + --> $DIR/recover-pat-exprs.rs:15:12 | LL | { let x.-0.0; } | ^ expected one of `:`, `;`, `=`, `@`, or `|` error: expected one of `:`, `;`, `=`, `@`, or `|`, found `.` - --> $DIR/recover-pat-exprs.rs:14:12 + --> $DIR/recover-pat-exprs.rs:16:12 | LL | { let x.-0; } | ^ expected one of `:`, `;`, `=`, `@`, or `|` error: expected one of `:`, `;`, `=`, `@`, or `|`, found `.` - --> $DIR/recover-pat-exprs.rs:16:12 + --> $DIR/recover-pat-exprs.rs:18:12 | LL | { let x.0u32; } | ^ expected one of `:`, `;`, `=`, `@`, or `|` error: expected one of `:`, `;`, `=`, `@`, or `|`, found `.` - --> $DIR/recover-pat-exprs.rs:17:12 + --> $DIR/recover-pat-exprs.rs:19:12 | LL | { let x.0.0_f64; } | ^ expected one of `:`, `;`, `=`, `@`, or `|` error: expected a pattern, found an expression - --> $DIR/recover-pat-exprs.rs:23:9 + --> $DIR/recover-pat-exprs.rs:25:9 | LL | x[0] => (), | ^^^^ not a pattern @@ -155,7 +155,7 @@ LL ~ VAL => (), | error: expected a pattern, found an expression - --> $DIR/recover-pat-exprs.rs:24:9 + --> $DIR/recover-pat-exprs.rs:26:9 | LL | x[..] => (), | ^^^^^ not a pattern @@ -175,25 +175,25 @@ LL ~ VAL => (), | error: expected one of `:`, `;`, `=`, `@`, or `|`, found `[` - --> $DIR/recover-pat-exprs.rs:27:12 + --> $DIR/recover-pat-exprs.rs:29:12 | LL | { let x[0, 1, 2]; } | ^ expected one of `:`, `;`, `=`, `@`, or `|` error: expected one of `:`, `;`, `=`, `@`, or `|`, found `[` - --> $DIR/recover-pat-exprs.rs:28:12 + --> $DIR/recover-pat-exprs.rs:30:12 | LL | { let x[0; 20]; } | ^ expected one of `:`, `;`, `=`, `@`, or `|` error: expected one of `:`, `;`, `=`, `@`, or `|`, found `[` - --> $DIR/recover-pat-exprs.rs:29:12 + --> $DIR/recover-pat-exprs.rs:31:12 | LL | { let x[]; } | ^ expected one of `:`, `;`, `=`, `@`, or `|` error: expected one of `)`, `,`, `@`, `if`, or `|`, found `[` - --> $DIR/recover-pat-exprs.rs:30:13 + --> $DIR/recover-pat-exprs.rs:32:13 | LL | { let (x[]); } | ^ @@ -202,7 +202,7 @@ LL | { let (x[]); } | help: missing `,` error: expected a pattern, found an expression - --> $DIR/recover-pat-exprs.rs:37:9 + --> $DIR/recover-pat-exprs.rs:39:9 | LL | x.f() => (), | ^^^^^ not a pattern @@ -221,7 +221,7 @@ LL ~ VAL => (), | error: expected a pattern, found an expression - --> $DIR/recover-pat-exprs.rs:38:9 + --> $DIR/recover-pat-exprs.rs:40:9 | LL | x._f() => (), | ^^^^^^ not a pattern @@ -241,7 +241,7 @@ LL ~ VAL => (), | error: expected a pattern, found an expression - --> $DIR/recover-pat-exprs.rs:39:9 + --> $DIR/recover-pat-exprs.rs:41:9 | LL | x? => (), | ^^ not a pattern @@ -262,7 +262,7 @@ LL ~ VAL => (), | error: expected a pattern, found an expression - --> $DIR/recover-pat-exprs.rs:40:9 + --> $DIR/recover-pat-exprs.rs:42:9 | LL | ().f() => (), | ^^^^^^ not a pattern @@ -284,7 +284,7 @@ LL ~ VAL => (), | error: expected a pattern, found an expression - --> $DIR/recover-pat-exprs.rs:41:9 + --> $DIR/recover-pat-exprs.rs:43:9 | LL | (0, x)?.f() => (), | ^^^^^^^^^^^ not a pattern @@ -306,7 +306,7 @@ LL ~ VAL => (), | error: expected a pattern, found an expression - --> $DIR/recover-pat-exprs.rs:42:9 + --> $DIR/recover-pat-exprs.rs:44:9 | LL | x.f().g() => (), | ^^^^^^^^^ not a pattern @@ -328,7 +328,7 @@ LL ~ VAL => (), | error: expected a pattern, found an expression - --> $DIR/recover-pat-exprs.rs:43:9 + --> $DIR/recover-pat-exprs.rs:45:9 | LL | 0.f()?.g()?? => (), | ^^^^^^^^^^^^ not a pattern @@ -350,7 +350,7 @@ LL ~ VAL => (), | error: expected a pattern, found an expression - --> $DIR/recover-pat-exprs.rs:50:9 + --> $DIR/recover-pat-exprs.rs:52:9 | LL | x as usize => (), | ^^^^^^^^^^ not a pattern @@ -369,7 +369,7 @@ LL ~ VAL => (), | error: expected a pattern, found an expression - --> $DIR/recover-pat-exprs.rs:51:9 + --> $DIR/recover-pat-exprs.rs:53:9 | LL | 0 as usize => (), | ^^^^^^^^^^ not a pattern @@ -389,7 +389,7 @@ LL ~ VAL => (), | error: expected a pattern, found an expression - --> $DIR/recover-pat-exprs.rs:52:9 + --> $DIR/recover-pat-exprs.rs:54:9 | LL | x.f().0.4 as f32 => (), | ^^^^^^^^^^^^^^^^ not a pattern @@ -410,7 +410,7 @@ LL ~ VAL => (), | error: expected a pattern, found an expression - --> $DIR/recover-pat-exprs.rs:59:9 + --> $DIR/recover-pat-exprs.rs:61:9 | LL | 1 + 1 => (), | ^^^^^ not a pattern @@ -429,7 +429,7 @@ LL ~ VAL => (), | error: expected a pattern, found an expression - --> $DIR/recover-pat-exprs.rs:60:9 + --> $DIR/recover-pat-exprs.rs:62:9 | LL | (1 + 2) * 3 => (), | ^^^^^^^^^^^ not a pattern @@ -449,7 +449,7 @@ LL ~ VAL => (), | error: expected a pattern, found an expression - --> $DIR/recover-pat-exprs.rs:63:9 + --> $DIR/recover-pat-exprs.rs:65:9 | LL | x.0 > 2 => (), | ^^^^^^^ not a pattern @@ -471,7 +471,7 @@ LL ~ VAL => (), | error: expected a pattern, found an expression - --> $DIR/recover-pat-exprs.rs:64:9 + --> $DIR/recover-pat-exprs.rs:66:9 | LL | x.0 == 2 => (), | ^^^^^^^^ not a pattern @@ -493,7 +493,7 @@ LL ~ VAL => (), | error: expected a pattern, found an expression - --> $DIR/recover-pat-exprs.rs:69:13 + --> $DIR/recover-pat-exprs.rs:71:13 | LL | (x, y.0 > 2) if x != 0 => (), | ^^^^^^^ not a pattern @@ -512,7 +512,7 @@ LL ~ (x, VAL) if x != 0 => (), | error: expected a pattern, found an expression - --> $DIR/recover-pat-exprs.rs:70:13 + --> $DIR/recover-pat-exprs.rs:72:13 | LL | (x, y.0 > 2) if x != 0 || x != 1 => (), | ^^^^^^^ not a pattern @@ -532,7 +532,7 @@ LL ~ (x, VAL) if x != 0 || x != 1 => (), | error: left-hand side of `@` must be a binding - --> $DIR/recover-pat-exprs.rs:83:9 + --> $DIR/recover-pat-exprs.rs:85:9 | LL | x.sqrt() @ .. => (), | --------^^^-- @@ -543,13 +543,13 @@ LL | x.sqrt() @ .. => (), = note: bindings are `x`, `mut x`, `ref x`, and `ref mut x` error: expected one of `)`, `,`, `if`, or `|`, found `+` - --> $DIR/recover-pat-exprs.rs:97:12 + --> $DIR/recover-pat-exprs.rs:99:12 | LL | (_ + 1) => (), | ^ expected one of `)`, `,`, `if`, or `|` error: expected a pattern, found an expression - --> $DIR/recover-pat-exprs.rs:81:9 + --> $DIR/recover-pat-exprs.rs:83:9 | LL | u8::MAX.abs() => (), | ^^^^^^^^^^^^^ not a pattern @@ -568,7 +568,7 @@ LL ~ VAL => (), | error: expected a pattern, found an expression - --> $DIR/recover-pat-exprs.rs:86:17 + --> $DIR/recover-pat-exprs.rs:88:17 | LL | z @ w @ v.u() => (), | ^^^^^ not a pattern @@ -590,7 +590,7 @@ LL ~ z @ w @ VAL => (), | error: expected a pattern, found an expression - --> $DIR/recover-pat-exprs.rs:88:9 + --> $DIR/recover-pat-exprs.rs:90:9 | LL | y.ilog(3) => (), | ^^^^^^^^^ not a pattern @@ -612,7 +612,7 @@ LL ~ VAL => (), | error: expected a pattern, found an expression - --> $DIR/recover-pat-exprs.rs:90:9 + --> $DIR/recover-pat-exprs.rs:92:9 | LL | n + 1 => (), | ^^^^^ not a pattern @@ -634,7 +634,7 @@ LL ~ VAL => (), | error: expected a pattern, found an expression - --> $DIR/recover-pat-exprs.rs:92:10 + --> $DIR/recover-pat-exprs.rs:94:10 | LL | ("".f() + 14 * 8) => (), | ^^^^^^^^^^^^^^^ not a pattern @@ -656,7 +656,7 @@ LL ~ (VAL) => (), | error: expected a pattern, found an expression - --> $DIR/recover-pat-exprs.rs:95:9 + --> $DIR/recover-pat-exprs.rs:97:9 | LL | f?() => (), | ^^^^ not a pattern @@ -678,7 +678,7 @@ LL ~ VAL => (), | error: expected a pattern, found an expression - --> $DIR/recover-pat-exprs.rs:101:9 + --> $DIR/recover-pat-exprs.rs:103:9 | LL | let 1 + 1 = 2; | ^^^^^ not a pattern @@ -686,7 +686,7 @@ LL | let 1 + 1 = 2; = note: arbitrary expressions are not allowed in patterns: error: expected one of `)`, `,`, `@`, `if`, or `|`, found `*` - --> $DIR/recover-pat-exprs.rs:104:28 + --> $DIR/recover-pat-exprs.rs:106:28 | LL | let b = matches!(x, (x * x | x.f()) | x[0]); | ^ expected one of `)`, `,`, `@`, `if`, or `|` @@ -695,7 +695,7 @@ LL | let b = matches!(x, (x * x | x.f()) | x[0]); = note: while parsing argument for this `pat` macro fragment error: expected a pattern, found an expression - --> $DIR/recover-pat-exprs.rs:60:10 + --> $DIR/recover-pat-exprs.rs:62:10 | LL | (1 + 2) * 3 => (), | ^^^^^ not a pattern @@ -703,7 +703,7 @@ LL | (1 + 2) * 3 => (), = note: arbitrary expressions are not allowed in patterns: error: expected a pattern, found an expression - --> $DIR/recover-pat-exprs.rs:75:5 + --> $DIR/recover-pat-exprs.rs:77:5 | LL | 1 + 2 * PI.cos() => 2, | ^^^^^^^^^^^^^^^^ not a pattern @@ -711,7 +711,7 @@ LL | 1 + 2 * PI.cos() => 2, = note: arbitrary expressions are not allowed in patterns: error: expected a pattern, found an expression - --> $DIR/recover-pat-exprs.rs:83:9 + --> $DIR/recover-pat-exprs.rs:85:9 | LL | x.sqrt() @ .. => (), | ^^^^^^^^ not a pattern diff --git a/tests/ui/pattern/byte-string-mutability-mismatch.rs b/tests/ui/pattern/byte-string-mutability-mismatch.rs index 4ffdb5f9b99..9f7054ae82e 100644 --- a/tests/ui/pattern/byte-string-mutability-mismatch.rs +++ b/tests/ui/pattern/byte-string-mutability-mismatch.rs @@ -2,18 +2,20 @@ //! the pattern's scrutinee. Since byte string literals are always shared references, it's a //! mismatch to use a byte string literal pattern to match on a mutable array or slice reference. +//@ dont-require-annotations: NOTE + fn main() { let mut val = [97u8, 10u8]; match &mut val { b"a\n" => {}, //~^ ERROR mismatched types - //~| types differ in mutability + //~| NOTE types differ in mutability _ => {}, } match &mut val[..] { b"a\n" => {}, //~^ ERROR mismatched types - //~| types differ in mutability + //~| NOTE types differ in mutability _ => {}, } } diff --git a/tests/ui/pattern/byte-string-mutability-mismatch.stderr b/tests/ui/pattern/byte-string-mutability-mismatch.stderr index ee796278e69..f64b452b594 100644 --- a/tests/ui/pattern/byte-string-mutability-mismatch.stderr +++ b/tests/ui/pattern/byte-string-mutability-mismatch.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/byte-string-mutability-mismatch.rs:8:9 + --> $DIR/byte-string-mutability-mismatch.rs:10:9 | LL | match &mut val { | -------- this expression has type `&mut [u8; 2]` @@ -10,7 +10,7 @@ LL | b"a\n" => {}, found reference `&'static _` error[E0308]: mismatched types - --> $DIR/byte-string-mutability-mismatch.rs:14:10 + --> $DIR/byte-string-mutability-mismatch.rs:16:10 | LL | match &mut val[..] { | ------------ this expression has type `&mut [u8]` diff --git a/tests/ui/pattern/deref-patterns/byte-string-type-errors.rs b/tests/ui/pattern/deref-patterns/byte-string-type-errors.rs index 29a33e3e2c3..64acc4748af 100644 --- a/tests/ui/pattern/deref-patterns/byte-string-type-errors.rs +++ b/tests/ui/pattern/deref-patterns/byte-string-type-errors.rs @@ -2,6 +2,8 @@ //! patterns to have type `[u8]` or `[u8; N]` when matching on a slice or array; this can affect the //! "found" type reported in error messages when matching on a slice or array of the wrong type. +//@ dont-require-annotations: NOTE + #![feature(deref_patterns)] #![expect(incomplete_features)] @@ -10,25 +12,25 @@ fn main() { // the same as byte string literals. if let b"test" = () {} //~^ ERROR mismatched types - //~| expected `()`, found `&[u8; 4]` + //~| NOTE expected `()`, found `&[u8; 4]` // Baseline 2: there's a special case for byte string patterns in stable rust, allowing them to // match on slice references. This affects the error when matching on a non-`&[u8]` slice ref, // reporting the "found" type as `&[u8]`. if let b"test" = &[] as &[i8] {} //~^ ERROR mismatched types - //~| expected `&[i8]`, found `&[u8]` + //~| NOTE expected `&[i8]`, found `&[u8]` // Test matching on a non-`[u8]` slice: the pattern has type `[u8]` if a slice is expected. if let b"test" = *(&[] as &[i8]) {} //~^ ERROR mismatched types - //~| expected `[i8]`, found `[u8]` + //~| NOTE expected `[i8]`, found `[u8]` // Test matching on a non-`[u8;4]` array: the pattern has type `[u8;4]` if an array is expected. if let b"test" = [()] {} //~^ ERROR mismatched types - //~| expected `[(); 1]`, found `[u8; 4]` + //~| NOTE expected `[(); 1]`, found `[u8; 4]` if let b"test" = *b"this array is too long" {} //~^ ERROR mismatched types - //~| expected an array with a size of 22, found one with a size of 4 + //~| NOTE expected an array with a size of 22, found one with a size of 4 } diff --git a/tests/ui/pattern/deref-patterns/byte-string-type-errors.stderr b/tests/ui/pattern/deref-patterns/byte-string-type-errors.stderr index d29a5b59252..0317b7209e1 100644 --- a/tests/ui/pattern/deref-patterns/byte-string-type-errors.stderr +++ b/tests/ui/pattern/deref-patterns/byte-string-type-errors.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/byte-string-type-errors.rs:11:12 + --> $DIR/byte-string-type-errors.rs:13:12 | LL | if let b"test" = () {} | ^^^^^^^ -- this expression has type `()` @@ -7,7 +7,7 @@ LL | if let b"test" = () {} | expected `()`, found `&[u8; 4]` error[E0308]: mismatched types - --> $DIR/byte-string-type-errors.rs:18:12 + --> $DIR/byte-string-type-errors.rs:20:12 | LL | if let b"test" = &[] as &[i8] {} | ^^^^^^^ ------------ this expression has type `&[i8]` @@ -18,7 +18,7 @@ LL | if let b"test" = &[] as &[i8] {} found reference `&'static [u8]` error[E0308]: mismatched types - --> $DIR/byte-string-type-errors.rs:23:12 + --> $DIR/byte-string-type-errors.rs:25:12 | LL | if let b"test" = *(&[] as &[i8]) {} | ^^^^^^^ --------------- this expression has type `[i8]` @@ -29,7 +29,7 @@ LL | if let b"test" = *(&[] as &[i8]) {} found slice `[u8]` error[E0308]: mismatched types - --> $DIR/byte-string-type-errors.rs:28:12 + --> $DIR/byte-string-type-errors.rs:30:12 | LL | if let b"test" = [()] {} | ^^^^^^^ ---- this expression has type `[(); 1]` @@ -40,7 +40,7 @@ LL | if let b"test" = [()] {} found array `[u8; 4]` error[E0308]: mismatched types - --> $DIR/byte-string-type-errors.rs:31:12 + --> $DIR/byte-string-type-errors.rs:33:12 | LL | if let b"test" = *b"this array is too long" {} | ^^^^^^^ -------------------------- this expression has type `[u8; 22]` diff --git a/tests/ui/pattern/deref-patterns/unsatisfied-bounds.rs b/tests/ui/pattern/deref-patterns/unsatisfied-bounds.rs index 00064b2320c..9e95f4ec409 100644 --- a/tests/ui/pattern/deref-patterns/unsatisfied-bounds.rs +++ b/tests/ui/pattern/deref-patterns/unsatisfied-bounds.rs @@ -15,7 +15,7 @@ fn main() { // FIXME(deref_patterns): there should be a special diagnostic for missing `DerefPure`. match MyPointer { () => {} - //~^ the trait bound `MyPointer: DerefPure` is not satisfied + //~^ ERROR the trait bound `MyPointer: DerefPure` is not satisfied _ => {} } } diff --git a/tests/ui/pattern/pattern-error-continue.rs b/tests/ui/pattern/pattern-error-continue.rs index bed94943923..664d4e80ef5 100644 --- a/tests/ui/pattern/pattern-error-continue.rs +++ b/tests/ui/pattern/pattern-error-continue.rs @@ -1,5 +1,7 @@ // Test that certain pattern-match type errors are non-fatal +//@ dont-require-annotations: NOTE + enum A { B(isize, isize), C(isize, isize, isize), @@ -21,13 +23,13 @@ fn main() { match 'c' { S { .. } => (), //~^ ERROR mismatched types - //~| expected `char`, found `S` + //~| NOTE expected `char`, found `S` _ => () } f(true); //~^ ERROR mismatched types - //~| expected `char`, found `bool` + //~| NOTE expected `char`, found `bool` match () { E::V => {} //~ ERROR failed to resolve: use of undeclared type `E` diff --git a/tests/ui/pattern/pattern-error-continue.stderr b/tests/ui/pattern/pattern-error-continue.stderr index bb5582dd873..a9ac96e3eaf 100644 --- a/tests/ui/pattern/pattern-error-continue.stderr +++ b/tests/ui/pattern/pattern-error-continue.stderr @@ -1,5 +1,5 @@ error[E0532]: expected tuple struct or tuple variant, found unit variant `A::D` - --> $DIR/pattern-error-continue.rs:18:9 + --> $DIR/pattern-error-continue.rs:20:9 | LL | B(isize, isize), | --------------- similarly named tuple variant `B` defined here @@ -22,7 +22,7 @@ LL + A::B(_) => (), | error[E0023]: this pattern has 3 fields, but the corresponding tuple variant has 2 fields - --> $DIR/pattern-error-continue.rs:17:14 + --> $DIR/pattern-error-continue.rs:19:14 | LL | B(isize, isize), | ----- ----- tuple variant has 2 fields @@ -31,7 +31,7 @@ LL | A::B(_, _, _) => (), | ^ ^ ^ expected 2 fields, found 3 error[E0308]: mismatched types - --> $DIR/pattern-error-continue.rs:22:9 + --> $DIR/pattern-error-continue.rs:24:9 | LL | match 'c' { | --- this expression has type `char` @@ -39,7 +39,7 @@ LL | S { .. } => (), | ^^^^^^^^ expected `char`, found `S` error[E0308]: mismatched types - --> $DIR/pattern-error-continue.rs:28:7 + --> $DIR/pattern-error-continue.rs:30:7 | LL | f(true); | - ^^^^ expected `char`, found `bool` @@ -47,13 +47,13 @@ LL | f(true); | arguments to this function are incorrect | note: function defined here - --> $DIR/pattern-error-continue.rs:13:4 + --> $DIR/pattern-error-continue.rs:15:4 | LL | fn f(_c: char) {} | ^ -------- error[E0433]: failed to resolve: use of undeclared type `E` - --> $DIR/pattern-error-continue.rs:33:9 + --> $DIR/pattern-error-continue.rs:35:9 | LL | E::V => {} | ^ diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.classic2021.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.classic2021.stderr index 355a8af6760..4d795d5c385 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.classic2021.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.classic2021.stderr @@ -1,5 +1,5 @@ error[E0507]: cannot move out of a shared reference - --> $DIR/borrowck-errors.rs:31:29 + --> $DIR/borrowck-errors.rs:33:29 | LL | if let Some(&Some(x)) = Some(&Some(&mut 0)) { | - ^^^^^^^^^^^^^^^^^^^ @@ -14,19 +14,19 @@ LL + if let Some(Some(x)) = Some(&Some(&mut 0)) { | error[E0596]: cannot borrow data in a `&` reference as mutable - --> $DIR/borrowck-errors.rs:36:10 + --> $DIR/borrowck-errors.rs:38:10 | LL | let &ref mut x = &0; | ^^^^^^^^^ cannot borrow as mutable error[E0596]: cannot borrow data in a `&` reference as mutable - --> $DIR/borrowck-errors.rs:41:23 + --> $DIR/borrowck-errors.rs:43:23 | LL | if let &Some(Some(x)) = &Some(&mut Some(0)) { | ^ cannot borrow as mutable error[E0596]: cannot borrow data in a `&` reference as mutable - --> $DIR/borrowck-errors.rs:46:11 + --> $DIR/borrowck-errors.rs:48:11 | LL | let &[x] = &&mut [0]; | ^ cannot borrow as mutable diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.classic2024.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.classic2024.stderr index d40bdb9111b..6cc6c58bf7a 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.classic2024.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.classic2024.stderr @@ -1,5 +1,5 @@ error[E0508]: cannot move out of type `[&mut i32; 1]`, a non-copy array - --> $DIR/borrowck-errors.rs:15:16 + --> $DIR/borrowck-errors.rs:17:16 | LL | let [&x] = &[&mut 0]; | - ^^^^^^^^^ cannot move out of here @@ -13,7 +13,7 @@ LL | let [&ref x] = &[&mut 0]; | +++ error[E0508]: cannot move out of type `[&mut i32; 1]`, a non-copy array - --> $DIR/borrowck-errors.rs:22:16 + --> $DIR/borrowck-errors.rs:24:16 | LL | let [&x] = &mut [&mut 0]; | - ^^^^^^^^^^^^^ cannot move out of here @@ -27,7 +27,7 @@ LL | let [&ref x] = &mut [&mut 0]; | +++ error[E0507]: cannot move out of a shared reference - --> $DIR/borrowck-errors.rs:31:29 + --> $DIR/borrowck-errors.rs:33:29 | LL | if let Some(&Some(x)) = Some(&Some(&mut 0)) { | - ^^^^^^^^^^^^^^^^^^^ @@ -42,25 +42,25 @@ LL + if let Some(Some(x)) = Some(&Some(&mut 0)) { | error[E0596]: cannot borrow data in a `&` reference as mutable - --> $DIR/borrowck-errors.rs:36:10 + --> $DIR/borrowck-errors.rs:38:10 | LL | let &ref mut x = &0; | ^^^^^^^^^ cannot borrow as mutable error[E0596]: cannot borrow data in a `&` reference as mutable - --> $DIR/borrowck-errors.rs:41:23 + --> $DIR/borrowck-errors.rs:43:23 | LL | if let &Some(Some(x)) = &Some(&mut Some(0)) { | ^ cannot borrow as mutable error[E0596]: cannot borrow data in a `&` reference as mutable - --> $DIR/borrowck-errors.rs:46:11 + --> $DIR/borrowck-errors.rs:48:11 | LL | let &[x] = &&mut [0]; | ^ cannot borrow as mutable error[E0508]: cannot move out of type `[&mut i32; 1]`, a non-copy array - --> $DIR/borrowck-errors.rs:50:20 + --> $DIR/borrowck-errors.rs:52:20 | LL | let [&mut x] = &mut [&mut 0]; | - ^^^^^^^^^^^^^ cannot move out of here diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.rs index c171dcf0ca6..15575510e16 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.rs +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.rs @@ -4,6 +4,8 @@ //@[structural2021] edition: 2021 //@[classic2024] edition: 2024 //@[structural2024] edition: 2024 +//@ dont-require-annotations: NOTE + //! Tests for pattern errors not handled by the pattern typing rules, but by borrowck. #![allow(incomplete_features)] #![cfg_attr(any(classic2021, classic2024), feature(ref_pat_eat_one_layer_2024))] @@ -14,14 +16,14 @@ fn errors_caught_in_hir_typeck_on_stable() { let [&x] = &[&mut 0]; //[stable2021]~^ ERROR mismatched types - //[stable2021]~| types differ in mutability + //[stable2021]~| NOTE types differ in mutability //[classic2024]~^^^ ERROR: cannot move out of type #[cfg(any(classic2021, structural2021))] let _: u32 = x; #[cfg(structural2024)] let _: &u32 = x; let [&x] = &mut [&mut 0]; //[stable2021]~^ ERROR mismatched types - //[stable2021]~| types differ in mutability + //[stable2021]~| NOTE types differ in mutability //[classic2024]~^^^ ERROR: cannot move out of type #[cfg(any(classic2021, structural2021))] let _: u32 = x; #[cfg(structural2024)] let _: &u32 = x; diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.stable2021.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.stable2021.stderr index edcf9f30357..036b3dbeae3 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.stable2021.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.stable2021.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/borrowck-errors.rs:15:10 + --> $DIR/borrowck-errors.rs:17:10 | LL | let [&x] = &[&mut 0]; | ^^ --------- this expression has type `&[&mut {integer}; 1]` @@ -15,7 +15,7 @@ LL + let [x] = &[&mut 0]; | error[E0308]: mismatched types - --> $DIR/borrowck-errors.rs:22:10 + --> $DIR/borrowck-errors.rs:24:10 | LL | let [&x] = &mut [&mut 0]; | ^^ ------------- this expression has type `&mut [&mut {integer}; 1]` @@ -31,7 +31,7 @@ LL + let [x] = &mut [&mut 0]; | error[E0507]: cannot move out of a shared reference - --> $DIR/borrowck-errors.rs:31:29 + --> $DIR/borrowck-errors.rs:33:29 | LL | if let Some(&Some(x)) = Some(&Some(&mut 0)) { | - ^^^^^^^^^^^^^^^^^^^ @@ -46,19 +46,19 @@ LL + if let Some(Some(x)) = Some(&Some(&mut 0)) { | error[E0596]: cannot borrow data in a `&` reference as mutable - --> $DIR/borrowck-errors.rs:36:10 + --> $DIR/borrowck-errors.rs:38:10 | LL | let &ref mut x = &0; | ^^^^^^^^^ cannot borrow as mutable error[E0596]: cannot borrow data in a `&` reference as mutable - --> $DIR/borrowck-errors.rs:41:23 + --> $DIR/borrowck-errors.rs:43:23 | LL | if let &Some(Some(x)) = &Some(&mut Some(0)) { | ^ cannot borrow as mutable error[E0596]: cannot borrow data in a `&` reference as mutable - --> $DIR/borrowck-errors.rs:46:11 + --> $DIR/borrowck-errors.rs:48:11 | LL | let &[x] = &&mut [0]; | ^ cannot borrow as mutable diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.structural2021.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.structural2021.stderr index 208f6c8bbed..e1764fa1d55 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.structural2021.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.structural2021.stderr @@ -1,5 +1,5 @@ error[E0507]: cannot move out of a shared reference - --> $DIR/borrowck-errors.rs:31:29 + --> $DIR/borrowck-errors.rs:33:29 | LL | if let Some(&Some(x)) = Some(&Some(&mut 0)) { | - ^^^^^^^^^^^^^^^^^^^ @@ -14,7 +14,7 @@ LL + if let Some(Some(x)) = Some(&Some(&mut 0)) { | error[E0596]: cannot borrow data in a `&` reference as mutable - --> $DIR/borrowck-errors.rs:36:10 + --> $DIR/borrowck-errors.rs:38:10 | LL | let &ref mut x = &0; | ^^^^^^^^^ cannot borrow as mutable diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.structural2024.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.structural2024.stderr index 208f6c8bbed..e1764fa1d55 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.structural2024.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.structural2024.stderr @@ -1,5 +1,5 @@ error[E0507]: cannot move out of a shared reference - --> $DIR/borrowck-errors.rs:31:29 + --> $DIR/borrowck-errors.rs:33:29 | LL | if let Some(&Some(x)) = Some(&Some(&mut 0)) { | - ^^^^^^^^^^^^^^^^^^^ @@ -14,7 +14,7 @@ LL + if let Some(Some(x)) = Some(&Some(&mut 0)) { | error[E0596]: cannot borrow data in a `&` reference as mutable - --> $DIR/borrowck-errors.rs:36:10 + --> $DIR/borrowck-errors.rs:38:10 | LL | let &ref mut x = &0; | ^^^^^^^^^ cannot borrow as mutable diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mut-ref-mut.classic2024.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mut-ref-mut.classic2024.stderr index 6ddced3d168..97c74b5c448 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mut-ref-mut.classic2024.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mut-ref-mut.classic2024.stderr @@ -1,5 +1,5 @@ error[E0658]: binding cannot be both mutable and by-reference - --> $DIR/mut-ref-mut.rs:18:13 + --> $DIR/mut-ref-mut.rs:20:13 | LL | let Foo(mut a) = &Foo(0); | ^^^^ @@ -9,7 +9,7 @@ LL | let Foo(mut a) = &Foo(0); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: binding cannot be both mutable and by-reference - --> $DIR/mut-ref-mut.rs:23:13 + --> $DIR/mut-ref-mut.rs:25:13 | LL | let Foo(mut a) = &mut Foo(0); | ^^^^ @@ -19,7 +19,7 @@ LL | let Foo(mut a) = &mut Foo(0); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0308]: mismatched types - --> $DIR/mut-ref-mut.rs:28:10 + --> $DIR/mut-ref-mut.rs:30:10 | LL | let [&mut mut x] = &[&mut 0]; | ^^^^^ diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mut-ref-mut.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mut-ref-mut.rs index 94691e77bd8..814c7d90c8c 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mut-ref-mut.rs +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mut-ref-mut.rs @@ -7,6 +7,8 @@ //@[stable2021] run-pass //@[classic2021] run-pass //@[structural2021] run-pass +//@ dont-require-annotations: NOTE + //! Test diagnostics for binding with `mut` when the default binding mode is by-ref. #![allow(incomplete_features, unused_assignments, unused_variables)] #![cfg_attr(any(classic2021, classic2024), feature(ref_pat_eat_one_layer_2024))] @@ -27,7 +29,7 @@ pub fn main() { let [&mut mut x] = &[&mut 0]; //[classic2024]~^ ERROR: mismatched types - //[classic2024]~| cannot match inherited `&` with `&mut` pattern + //[classic2024]~| NOTE cannot match inherited `&` with `&mut` pattern //[structural2024]~^^^ ERROR binding cannot be both mutable and by-reference #[cfg(any(stable2021, classic2021, structural2021))] { x = 0 } } diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mut-ref-mut.structural2024.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mut-ref-mut.structural2024.stderr index c0c0f966b68..a3e8f2af6e9 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mut-ref-mut.structural2024.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mut-ref-mut.structural2024.stderr @@ -1,5 +1,5 @@ error[E0658]: binding cannot be both mutable and by-reference - --> $DIR/mut-ref-mut.rs:18:13 + --> $DIR/mut-ref-mut.rs:20:13 | LL | let Foo(mut a) = &Foo(0); | ^^^^ @@ -9,7 +9,7 @@ LL | let Foo(mut a) = &Foo(0); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: binding cannot be both mutable and by-reference - --> $DIR/mut-ref-mut.rs:23:13 + --> $DIR/mut-ref-mut.rs:25:13 | LL | let Foo(mut a) = &mut Foo(0); | ^^^^ @@ -19,7 +19,7 @@ LL | let Foo(mut a) = &mut Foo(0); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: binding cannot be both mutable and by-reference - --> $DIR/mut-ref-mut.rs:28:15 + --> $DIR/mut-ref-mut.rs:30:15 | LL | let [&mut mut x] = &[&mut 0]; | ^^^^ diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.classic2021.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.classic2021.stderr index a856a0eaf2a..208873c1bab 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.classic2021.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.classic2021.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:20:27 + --> $DIR/pattern-errors.rs:22:27 | LL | if let Some(&mut Some(&x)) = &Some(&mut Some(0)) { | ^^ ------------------- this expression has type `&Option<&mut Option<{integer}>>` @@ -15,7 +15,7 @@ LL + if let Some(&mut Some(x)) = &Some(&mut Some(0)) { | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:33:17 + --> $DIR/pattern-errors.rs:35:17 | LL | if let Some(&mut Some(&_)) = &Some(&Some(0)) { | ^^^^^^^^^^^^^ --------------- this expression has type `&Option<&Option<{integer}>>` @@ -26,7 +26,7 @@ LL | if let Some(&mut Some(&_)) = &Some(&Some(0)) { found mutable reference `&mut _` error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:38:23 + --> $DIR/pattern-errors.rs:40:23 | LL | if let Some(&Some(&mut x)) = &Some(&mut Some(0)) { | ^^^^^^ ------------------- this expression has type `&Option<&mut Option<{integer}>>` @@ -36,7 +36,7 @@ LL | if let Some(&Some(&mut x)) = &Some(&mut Some(0)) { = note: expected type `{integer}` found mutable reference `&mut _` note: to declare a mutable binding use: `mut x` - --> $DIR/pattern-errors.rs:38:23 + --> $DIR/pattern-errors.rs:40:23 | LL | if let Some(&Some(&mut x)) = &Some(&mut Some(0)) { | ^^^^^^ @@ -47,7 +47,7 @@ LL + if let Some(&Some(x)) = &Some(&mut Some(0)) { | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:45:23 + --> $DIR/pattern-errors.rs:47:23 | LL | if let Some(&Some(&mut _)) = &mut Some(&Some(0)) { | ^^^^^^ ------------------- this expression has type `&mut Option<&Option<{integer}>>` @@ -58,7 +58,7 @@ LL | if let Some(&Some(&mut _)) = &mut Some(&Some(0)) { found mutable reference `&mut _` error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:56:17 + --> $DIR/pattern-errors.rs:58:17 | LL | if let Some(&mut Some(x)) = &Some(Some(0)) { | ^^^^^ @@ -71,7 +71,7 @@ LL + if let Some(&Some(x)) = &Some(Some(0)) { | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:114:11 + --> $DIR/pattern-errors.rs:116:11 | LL | let [&&mut x] = &[&mut 0]; | ^^^^^^ --------- this expression has type `&[&mut {integer}; 1]` @@ -87,7 +87,7 @@ LL + let [&x] = &[&mut 0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:121:11 + --> $DIR/pattern-errors.rs:123:11 | LL | let [&&mut x] = &mut [&mut 0]; | ^^^^^^ ------------- this expression has type `&mut [&mut {integer}; 1]` @@ -103,7 +103,7 @@ LL + let [&x] = &mut [&mut 0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:128:11 + --> $DIR/pattern-errors.rs:130:11 | LL | let [&&mut ref x] = &[&mut 0]; | ^^^^^^^^^^ --------- this expression has type `&[&mut {integer}; 1]` @@ -119,7 +119,7 @@ LL + let [&ref x] = &[&mut 0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:135:11 + --> $DIR/pattern-errors.rs:137:11 | LL | let [&&mut ref x] = &mut [&mut 0]; | ^^^^^^^^^^ ------------- this expression has type `&mut [&mut {integer}; 1]` @@ -135,7 +135,7 @@ LL + let [&ref x] = &mut [&mut 0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:142:11 + --> $DIR/pattern-errors.rs:144:11 | LL | let [&&mut mut x] = &[&mut 0]; | ^^^^^^^^^^ --------- this expression has type `&[&mut {integer}; 1]` @@ -151,7 +151,7 @@ LL + let [&mut x] = &[&mut 0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:149:11 + --> $DIR/pattern-errors.rs:151:11 | LL | let [&&mut mut x] = &mut [&mut 0]; | ^^^^^^^^^^ ------------- this expression has type `&mut [&mut {integer}; 1]` @@ -167,7 +167,7 @@ LL + let [&mut x] = &mut [&mut 0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:164:15 + --> $DIR/pattern-errors.rs:166:15 | LL | let [&mut &x] = &[&mut 0]; | ^^ --------- this expression has type `&[&mut {integer}; 1]` @@ -183,7 +183,7 @@ LL + let [&mut x] = &[&mut 0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:170:15 + --> $DIR/pattern-errors.rs:172:15 | LL | let [&mut &ref x] = &[&mut 0]; | ^^^^^^ --------- this expression has type `&[&mut {integer}; 1]` @@ -199,7 +199,7 @@ LL + let [&mut ref x] = &[&mut 0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:176:15 + --> $DIR/pattern-errors.rs:178:15 | LL | let [&mut &(mut x)] = &[&mut 0]; | ^^^^^^^^ --------- this expression has type `&[&mut {integer}; 1]` diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.classic2024.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.classic2024.stderr index 90510d23e66..4f778e04ece 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.classic2024.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.classic2024.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:14:17 + --> $DIR/pattern-errors.rs:16:17 | LL | if let Some(&mut x) = &Some(&mut 0) { | ^^^^^ @@ -12,7 +12,7 @@ LL + if let Some(&x) = &Some(&mut 0) { | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:20:17 + --> $DIR/pattern-errors.rs:22:17 | LL | if let Some(&mut Some(&x)) = &Some(&mut Some(0)) { | ^^^^^ @@ -25,7 +25,7 @@ LL + if let Some(&Some(&x)) = &Some(&mut Some(0)) { | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:26:22 + --> $DIR/pattern-errors.rs:28:22 | LL | if let Some(Some(&mut x)) = &Some(Some(&mut 0)) { | ^^^^^ @@ -38,7 +38,7 @@ LL + if let Some(Some(&x)) = &Some(Some(&mut 0)) { | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:33:17 + --> $DIR/pattern-errors.rs:35:17 | LL | if let Some(&mut Some(&_)) = &Some(&Some(0)) { | ^^^^^ @@ -51,7 +51,7 @@ LL + if let Some(&Some(&_)) = &Some(&Some(0)) { | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:45:23 + --> $DIR/pattern-errors.rs:47:23 | LL | if let Some(&Some(&mut _)) = &mut Some(&Some(0)) { | ^^^^^ @@ -64,7 +64,7 @@ LL + if let Some(&Some(&_)) = &mut Some(&Some(0)) { | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:56:17 + --> $DIR/pattern-errors.rs:58:17 | LL | if let Some(&mut Some(x)) = &Some(Some(0)) { | ^^^^^ @@ -77,7 +77,7 @@ LL + if let Some(&Some(x)) = &Some(Some(0)) { | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:158:10 + --> $DIR/pattern-errors.rs:160:10 | LL | let [&mut x] = &[&mut 0]; | ^^^^^ @@ -90,7 +90,7 @@ LL + let [&x] = &[&mut 0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:164:10 + --> $DIR/pattern-errors.rs:166:10 | LL | let [&mut &x] = &[&mut 0]; | ^^^^^ @@ -103,7 +103,7 @@ LL + let [&&x] = &[&mut 0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:170:10 + --> $DIR/pattern-errors.rs:172:10 | LL | let [&mut &ref x] = &[&mut 0]; | ^^^^^ @@ -116,7 +116,7 @@ LL + let [&&ref x] = &[&mut 0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:176:10 + --> $DIR/pattern-errors.rs:178:10 | LL | let [&mut &(mut x)] = &[&mut 0]; | ^^^^^ diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.rs index 5e677445644..70a5bde5e89 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.rs +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.rs @@ -4,6 +4,8 @@ //@[structural2021] edition: 2021 //@[classic2024] edition: 2024 //@[structural2024] edition: 2024 +//@ dont-require-annotations: NOTE + //! Test cases for poorly-typed patterns in edition 2024 which are caught by HIR typeck. These must //! be separate from cases caught by MIR borrowck or the latter errors may not be emitted. #![allow(incomplete_features)] @@ -13,88 +15,88 @@ pub fn main() { if let Some(&mut x) = &Some(&mut 0) { //[classic2024]~^ ERROR: mismatched types - //[classic2024]~| cannot match inherited `&` with `&mut` pattern + //[classic2024]~| NOTE cannot match inherited `&` with `&mut` pattern #[cfg(any(stable2021, classic2021, structural2021))] let _: u32 = x; #[cfg(structural2024)] let _: &u32 = x; } if let Some(&mut Some(&x)) = &Some(&mut Some(0)) { //[stable2021,classic2021,structural2021,classic2024]~^ ERROR: mismatched types - //[stable2021,classic2021,structural2021]~| expected integer, found `&_` - //[classic2024]~| cannot match inherited `&` with `&mut` pattern + //[stable2021,classic2021,structural2021]~| NOTE expected integer, found `&_` + //[classic2024]~| NOTE cannot match inherited `&` with `&mut` pattern #[cfg(structural2024)] let _: u32 = x; } if let Some(Some(&mut x)) = &Some(Some(&mut 0)) { //[classic2024]~^ ERROR: mismatched types - //[classic2024]~| cannot match inherited `&` with `&mut` pattern + //[classic2024]~| NOTE cannot match inherited `&` with `&mut` pattern #[cfg(any(stable2021, classic2021, structural2021))] let _: u32 = x; #[cfg(structural2024)] let _: &u32 = x; } if let Some(&mut Some(&_)) = &Some(&Some(0)) { //~^ ERROR: mismatched types - //[stable2021,classic2021,structural2021]~| types differ in mutability - //[classic2024,structural2024]~| cannot match inherited `&` with `&mut` pattern + //[stable2021,classic2021,structural2021]~| NOTE types differ in mutability + //[classic2024,structural2024]~| NOTE cannot match inherited `&` with `&mut` pattern } if let Some(&Some(&mut x)) = &Some(&mut Some(0)) { //[stable2021,classic2021,structural2021,structural2024]~^ ERROR: mismatched types - //[stable2021]~| types differ in mutability - //[classic2021,structural2021]~| expected integer, found `&mut _` - //[structural2024]~| cannot match inherited `&` with `&mut` pattern + //[stable2021]~| NOTE types differ in mutability + //[classic2021,structural2021]~| NOTE expected integer, found `&mut _` + //[structural2024]~| NOTE cannot match inherited `&` with `&mut` pattern #[cfg(classic2024)] let _: u32 = x; } if let Some(&Some(&mut _)) = &mut Some(&Some(0)) { //~^ ERROR: mismatched types - //[stable2021,classic2021,structural2021]~| expected integer, found `&mut _` - //[classic2024,structural2024]~| cannot match inherited `&` with `&mut` pattern + //[stable2021,classic2021,structural2021]~| NOTE expected integer, found `&mut _` + //[classic2024,structural2024]~| NOTE cannot match inherited `&` with `&mut` pattern } if let Some(&Some(Some(&mut x))) = &Some(Some(&mut Some(0))) { //[stable2021,structural2021,structural2024]~^ ERROR: mismatched types - //[stable2021]~| expected `Option<&mut Option<{integer}>>`, found `&_` - //[structural2021,structural2024]~| cannot match inherited `&` with `&mut` pattern + //[stable2021]~| NOTE expected `Option<&mut Option<{integer}>>`, found `&_` + //[structural2021,structural2024]~| NOTE cannot match inherited `&` with `&mut` pattern #[cfg(any(classic2021, classic2024))] let _: u32 = x; } if let Some(&mut Some(x)) = &Some(Some(0)) { //~^ ERROR: mismatched types - //[stable2021]~| expected `Option<{integer}>`, found `&mut _` - //[classic2021,structural2021,classic2024,structural2024]~| cannot match inherited `&` with `&mut` pattern + //[stable2021]~| NOTE expected `Option<{integer}>`, found `&mut _` + //[classic2021,structural2021,classic2024,structural2024]~| NOTE cannot match inherited `&` with `&mut` pattern } } fn structural_errors_0() { let &[&mut x] = &&mut [0]; //[stable2021,structural2021,structural2024]~^ ERROR: mismatched types - //[stable2021]~| expected integer, found `&mut _` - //[structural2021,structural2024]~| cannot match inherited `&` with `&mut` pattern + //[stable2021]~| NOTE expected integer, found `&mut _` + //[structural2021,structural2024]~| NOTE cannot match inherited `&` with `&mut` pattern #[cfg(any(classic2021, classic2024))] let _: u32 = x; let &[&mut x] = &mut &mut [0]; //[stable2021,structural2021,structural2024]~^ ERROR: mismatched types - //[stable2021]~| types differ in mutability - //[structural2021,structural2024]~| cannot match inherited `&` with `&mut` pattern + //[stable2021]~| NOTE types differ in mutability + //[structural2021,structural2024]~| NOTE cannot match inherited `&` with `&mut` pattern #[cfg(any(classic2021, classic2024))] let _: u32 = x; let &[&mut ref x] = &&mut [0]; //[stable2021,structural2021,structural2024]~^ ERROR: mismatched types - //[stable2021]~| expected integer, found `&mut _` - //[structural2021,structural2024]~| cannot match inherited `&` with `&mut` pattern + //[stable2021]~| NOTE expected integer, found `&mut _` + //[structural2021,structural2024]~| NOTE cannot match inherited `&` with `&mut` pattern #[cfg(any(classic2021, classic2024))] let _: &u32 = x; let &[&mut ref x] = &mut &mut [0]; //[stable2021,structural2021,structural2024]~^ ERROR: mismatched types - //[stable2021]~| types differ in mutability - //[structural2021,structural2024]~| cannot match inherited `&` with `&mut` pattern + //[stable2021]~| NOTE types differ in mutability + //[structural2021,structural2024]~| NOTE cannot match inherited `&` with `&mut` pattern #[cfg(any(classic2021, classic2024))] let _: &u32 = x; let &[&mut mut x] = &&mut [0]; //[stable2021,structural2021,structural2024]~^ ERROR: mismatched types - //[stable2021]~| expected integer, found `&mut _` - //[structural2021,structural2024]~| cannot match inherited `&` with `&mut` pattern + //[stable2021]~| NOTE expected integer, found `&mut _` + //[structural2021,structural2024]~| NOTE cannot match inherited `&` with `&mut` pattern #[cfg(any(classic2021, classic2024))] let _: u32 = x; let &[&mut mut x] = &mut &mut [0]; //[stable2021,structural2021,structural2024]~^ ERROR: mismatched types - //[stable2021]~| types differ in mutability - //[structural2021,structural2024]~| cannot match inherited `&` with `&mut` pattern + //[stable2021]~| NOTE types differ in mutability + //[structural2021,structural2024]~| NOTE cannot match inherited `&` with `&mut` pattern #[cfg(any(classic2021, classic2024))] let _: u32 = x; } @@ -113,69 +115,69 @@ fn structural_errors_1() { fn structural_errors_2() { let [&&mut x] = &[&mut 0]; //[stable2021,classic2021,structural2021,structural2024]~^ ERROR: mismatched types - //[stable2021]~| types differ in mutability - //[classic2021,structural2021] expected integer, found `&mut _` - //[structural2024]~| cannot match inherited `&` with `&mut` pattern + //[stable2021]~| NOTE types differ in mutability + //[classic2021,structural2021] NOTE expected integer, found `&mut _` + //[structural2024]~| NOTE cannot match inherited `&` with `&mut` pattern #[cfg(classic2024)] let _: u32 = x; let [&&mut x] = &mut [&mut 0]; //[stable2021,classic2021,structural2021,structural2024]~^ ERROR: mismatched types - //[stable2021]~| types differ in mutability - //[classic2021,structural2021] expected integer, found `&mut _` - //[structural2024]~| cannot match inherited `&` with `&mut` pattern + //[stable2021]~| NOTE types differ in mutability + //[classic2021,structural2021] NOTE expected integer, found `&mut _` + //[structural2024]~| NOTE cannot match inherited `&` with `&mut` pattern #[cfg(classic2024)] let _: u32 = x; let [&&mut ref x] = &[&mut 0]; //[stable2021,classic2021,structural2021,structural2024]~^ ERROR: mismatched types - //[stable2021]~| types differ in mutability - //[classic2021,structural2021] expected integer, found `&mut _` - //[structural2024]~| cannot match inherited `&` with `&mut` pattern + //[stable2021]~| NOTE types differ in mutability + //[classic2021,structural2021] NOTE expected integer, found `&mut _` + //[structural2024]~| NOTE cannot match inherited `&` with `&mut` pattern #[cfg(classic2024)] let _: &u32 = x; let [&&mut ref x] = &mut [&mut 0]; //[stable2021,classic2021,structural2021,structural2024]~^ ERROR: mismatched types - //[stable2021]~| types differ in mutability - //[classic2021,structural2021] expected integer, found `&mut _` - //[structural2024]~| cannot match inherited `&` with `&mut` pattern + //[stable2021]~| NOTE types differ in mutability + //[classic2021,structural2021] NOTE expected integer, found `&mut _` + //[structural2024]~| NOTE cannot match inherited `&` with `&mut` pattern #[cfg(classic2024)] let _: &u32 = x; let [&&mut mut x] = &[&mut 0]; //[stable2021,classic2021,structural2021,structural2024]~^ ERROR: mismatched types - //[stable2021]~| types differ in mutability - //[classic2021,structural2021] expected integer, found `&mut _` - //[structural2024]~| cannot match inherited `&` with `&mut` pattern + //[stable2021]~| NOTE types differ in mutability + //[classic2021,structural2021] NOTE expected integer, found `&mut _` + //[structural2024]~| NOTE cannot match inherited `&` with `&mut` pattern #[cfg(classic2024)] let _: u32 = x; let [&&mut mut x] = &mut [&mut 0]; //[stable2021,classic2021,structural2021,structural2024]~^ ERROR: mismatched types - //[stable2021]~| types differ in mutability - //[classic2021,structural2021] expected integer, found `&mut _` - //[structural2024]~| cannot match inherited `&` with `&mut` pattern + //[stable2021]~| NOTE types differ in mutability + //[classic2021,structural2021] NOTE expected integer, found `&mut _` + //[structural2024]~| NOTE cannot match inherited `&` with `&mut` pattern #[cfg(classic2024)] let _: u32 = x; } fn classic_errors_0() { let [&mut x] = &[&mut 0]; //[classic2024]~^ ERROR: mismatched types - //[classic2024]~| cannot match inherited `&` with `&mut` pattern + //[classic2024]~| NOTE cannot match inherited `&` with `&mut` pattern #[cfg(any(stable2021, classic2021, structural2021))] let _: u32 = x; #[cfg(structural2024)] let _: &u32 = x; let [&mut &x] = &[&mut 0]; //[stable2021,classic2021,structural2021,classic2024]~^ ERROR: mismatched types - //[stable2021]~| expected integer, found `&_` - //[classic2024]~| cannot match inherited `&` with `&mut` pattern + //[stable2021]~| NOTE expected integer, found `&_` + //[classic2024]~| NOTE cannot match inherited `&` with `&mut` pattern #[cfg(structural2024)] let _: u32 = x; let [&mut &ref x] = &[&mut 0]; //[stable2021,classic2021,structural2021,classic2024]~^ ERROR: mismatched types - //[stable2021]~| expected integer, found `&_` - //[classic2024]~| cannot match inherited `&` with `&mut` pattern + //[stable2021]~| NOTE expected integer, found `&_` + //[classic2024]~| NOTE cannot match inherited `&` with `&mut` pattern #[cfg(structural2024)] let _: &u32 = x; let [&mut &(mut x)] = &[&mut 0]; //[stable2021,classic2021,structural2021,classic2024]~^ ERROR: mismatched types - //[stable2021]~| expected integer, found `&_` - //[classic2024]~| cannot match inherited `&` with `&mut` pattern + //[stable2021]~| NOTE expected integer, found `&_` + //[classic2024]~| NOTE cannot match inherited `&` with `&mut` pattern #[cfg(structural2024)] let _: u32 = x; } diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.stable2021.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.stable2021.stderr index 76e6d2f562a..8b32e4f7c02 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.stable2021.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.stable2021.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:20:27 + --> $DIR/pattern-errors.rs:22:27 | LL | if let Some(&mut Some(&x)) = &Some(&mut Some(0)) { | ^^ ------------------- this expression has type `&Option<&mut Option<{integer}>>` @@ -15,7 +15,7 @@ LL + if let Some(&mut Some(x)) = &Some(&mut Some(0)) { | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:33:17 + --> $DIR/pattern-errors.rs:35:17 | LL | if let Some(&mut Some(&_)) = &Some(&Some(0)) { | ^^^^^^^^^^^^^ --------------- this expression has type `&Option<&Option<{integer}>>` @@ -26,7 +26,7 @@ LL | if let Some(&mut Some(&_)) = &Some(&Some(0)) { found mutable reference `&mut _` error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:38:17 + --> $DIR/pattern-errors.rs:40:17 | LL | if let Some(&Some(&mut x)) = &Some(&mut Some(0)) { | ^^^^^^^^^^^^^ ------------------- this expression has type `&Option<&mut Option<{integer}>>` @@ -37,7 +37,7 @@ LL | if let Some(&Some(&mut x)) = &Some(&mut Some(0)) { found reference `&_` error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:45:23 + --> $DIR/pattern-errors.rs:47:23 | LL | if let Some(&Some(&mut _)) = &mut Some(&Some(0)) { | ^^^^^^ ------------------- this expression has type `&mut Option<&Option<{integer}>>` @@ -48,7 +48,7 @@ LL | if let Some(&Some(&mut _)) = &mut Some(&Some(0)) { found mutable reference `&mut _` error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:50:17 + --> $DIR/pattern-errors.rs:52:17 | LL | if let Some(&Some(Some(&mut x))) = &Some(Some(&mut Some(0))) { | ^^^^^^^^^^^^^^^^^^^ ------------------------- this expression has type `&Option>>` @@ -59,7 +59,7 @@ LL | if let Some(&Some(Some(&mut x))) = &Some(Some(&mut Some(0))) { found reference `&_` error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:56:17 + --> $DIR/pattern-errors.rs:58:17 | LL | if let Some(&mut Some(x)) = &Some(Some(0)) { | ^^^^^^^^^^^^ -------------- this expression has type `&Option>` @@ -70,7 +70,7 @@ LL | if let Some(&mut Some(x)) = &Some(Some(0)) { found mutable reference `&mut _` error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:64:11 + --> $DIR/pattern-errors.rs:66:11 | LL | let &[&mut x] = &&mut [0]; | ^^^^^^ --------- this expression has type `&&mut [{integer}; 1]` @@ -80,7 +80,7 @@ LL | let &[&mut x] = &&mut [0]; = note: expected type `{integer}` found mutable reference `&mut _` note: to declare a mutable binding use: `mut x` - --> $DIR/pattern-errors.rs:64:11 + --> $DIR/pattern-errors.rs:66:11 | LL | let &[&mut x] = &&mut [0]; | ^^^^^^ @@ -91,7 +91,7 @@ LL + let &[x] = &&mut [0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:70:9 + --> $DIR/pattern-errors.rs:72:9 | LL | let &[&mut x] = &mut &mut [0]; | ^^^^^^^^^ ------------- this expression has type `&mut &mut [{integer}; 1]` @@ -102,7 +102,7 @@ LL | let &[&mut x] = &mut &mut [0]; found reference `&_` error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:76:11 + --> $DIR/pattern-errors.rs:78:11 | LL | let &[&mut ref x] = &&mut [0]; | ^^^^^^^^^^ --------- this expression has type `&&mut [{integer}; 1]` @@ -112,7 +112,7 @@ LL | let &[&mut ref x] = &&mut [0]; = note: expected type `{integer}` found mutable reference `&mut _` note: to declare a mutable binding use: `mut x` - --> $DIR/pattern-errors.rs:76:11 + --> $DIR/pattern-errors.rs:78:11 | LL | let &[&mut ref x] = &&mut [0]; | ^^^^^^^^^^ @@ -123,7 +123,7 @@ LL + let &[ref x] = &&mut [0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:82:9 + --> $DIR/pattern-errors.rs:84:9 | LL | let &[&mut ref x] = &mut &mut [0]; | ^^^^^^^^^^^^^ ------------- this expression has type `&mut &mut [{integer}; 1]` @@ -134,7 +134,7 @@ LL | let &[&mut ref x] = &mut &mut [0]; found reference `&_` error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:88:11 + --> $DIR/pattern-errors.rs:90:11 | LL | let &[&mut mut x] = &&mut [0]; | ^^^^^^^^^^ --------- this expression has type `&&mut [{integer}; 1]` @@ -144,7 +144,7 @@ LL | let &[&mut mut x] = &&mut [0]; = note: expected type `{integer}` found mutable reference `&mut _` note: to declare a mutable binding use: `mut x` - --> $DIR/pattern-errors.rs:88:11 + --> $DIR/pattern-errors.rs:90:11 | LL | let &[&mut mut x] = &&mut [0]; | ^^^^^^^^^^ @@ -155,7 +155,7 @@ LL + let &[mut x] = &&mut [0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:94:9 + --> $DIR/pattern-errors.rs:96:9 | LL | let &[&mut mut x] = &mut &mut [0]; | ^^^^^^^^^^^^^ ------------- this expression has type `&mut &mut [{integer}; 1]` @@ -166,7 +166,7 @@ LL | let &[&mut mut x] = &mut &mut [0]; found reference `&_` error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:114:10 + --> $DIR/pattern-errors.rs:116:10 | LL | let [&&mut x] = &[&mut 0]; | ^^^^^^^ --------- this expression has type `&[&mut {integer}; 1]` @@ -177,7 +177,7 @@ LL | let [&&mut x] = &[&mut 0]; found reference `&_` error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:121:10 + --> $DIR/pattern-errors.rs:123:10 | LL | let [&&mut x] = &mut [&mut 0]; | ^^^^^^^ ------------- this expression has type `&mut [&mut {integer}; 1]` @@ -188,7 +188,7 @@ LL | let [&&mut x] = &mut [&mut 0]; found reference `&_` error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:128:10 + --> $DIR/pattern-errors.rs:130:10 | LL | let [&&mut ref x] = &[&mut 0]; | ^^^^^^^^^^^ --------- this expression has type `&[&mut {integer}; 1]` @@ -199,7 +199,7 @@ LL | let [&&mut ref x] = &[&mut 0]; found reference `&_` error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:135:10 + --> $DIR/pattern-errors.rs:137:10 | LL | let [&&mut ref x] = &mut [&mut 0]; | ^^^^^^^^^^^ ------------- this expression has type `&mut [&mut {integer}; 1]` @@ -210,7 +210,7 @@ LL | let [&&mut ref x] = &mut [&mut 0]; found reference `&_` error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:142:10 + --> $DIR/pattern-errors.rs:144:10 | LL | let [&&mut mut x] = &[&mut 0]; | ^^^^^^^^^^^ --------- this expression has type `&[&mut {integer}; 1]` @@ -221,7 +221,7 @@ LL | let [&&mut mut x] = &[&mut 0]; found reference `&_` error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:149:10 + --> $DIR/pattern-errors.rs:151:10 | LL | let [&&mut mut x] = &mut [&mut 0]; | ^^^^^^^^^^^ ------------- this expression has type `&mut [&mut {integer}; 1]` @@ -232,7 +232,7 @@ LL | let [&&mut mut x] = &mut [&mut 0]; found reference `&_` error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:164:15 + --> $DIR/pattern-errors.rs:166:15 | LL | let [&mut &x] = &[&mut 0]; | ^^ --------- this expression has type `&[&mut {integer}; 1]` @@ -248,7 +248,7 @@ LL + let [&mut x] = &[&mut 0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:170:15 + --> $DIR/pattern-errors.rs:172:15 | LL | let [&mut &ref x] = &[&mut 0]; | ^^^^^^ --------- this expression has type `&[&mut {integer}; 1]` @@ -264,7 +264,7 @@ LL + let [&mut ref x] = &[&mut 0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:176:15 + --> $DIR/pattern-errors.rs:178:15 | LL | let [&mut &(mut x)] = &[&mut 0]; | ^^^^^^^^ --------- this expression has type `&[&mut {integer}; 1]` diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.structural2021.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.structural2021.stderr index 1ca6bff3f38..09cff1f8e92 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.structural2021.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.structural2021.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:20:27 + --> $DIR/pattern-errors.rs:22:27 | LL | if let Some(&mut Some(&x)) = &Some(&mut Some(0)) { | ^^ ------------------- this expression has type `&Option<&mut Option<{integer}>>` @@ -15,7 +15,7 @@ LL + if let Some(&mut Some(x)) = &Some(&mut Some(0)) { | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:33:17 + --> $DIR/pattern-errors.rs:35:17 | LL | if let Some(&mut Some(&_)) = &Some(&Some(0)) { | ^^^^^^^^^^^^^ --------------- this expression has type `&Option<&Option<{integer}>>` @@ -26,7 +26,7 @@ LL | if let Some(&mut Some(&_)) = &Some(&Some(0)) { found mutable reference `&mut _` error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:38:23 + --> $DIR/pattern-errors.rs:40:23 | LL | if let Some(&Some(&mut x)) = &Some(&mut Some(0)) { | ^^^^^^ ------------------- this expression has type `&Option<&mut Option<{integer}>>` @@ -36,7 +36,7 @@ LL | if let Some(&Some(&mut x)) = &Some(&mut Some(0)) { = note: expected type `{integer}` found mutable reference `&mut _` note: to declare a mutable binding use: `mut x` - --> $DIR/pattern-errors.rs:38:23 + --> $DIR/pattern-errors.rs:40:23 | LL | if let Some(&Some(&mut x)) = &Some(&mut Some(0)) { | ^^^^^^ @@ -47,7 +47,7 @@ LL + if let Some(&Some(x)) = &Some(&mut Some(0)) { | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:45:23 + --> $DIR/pattern-errors.rs:47:23 | LL | if let Some(&Some(&mut _)) = &mut Some(&Some(0)) { | ^^^^^^ ------------------- this expression has type `&mut Option<&Option<{integer}>>` @@ -58,7 +58,7 @@ LL | if let Some(&Some(&mut _)) = &mut Some(&Some(0)) { found mutable reference `&mut _` error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:50:28 + --> $DIR/pattern-errors.rs:52:28 | LL | if let Some(&Some(Some(&mut x))) = &Some(Some(&mut Some(0))) { | ^^^^^ @@ -71,7 +71,7 @@ LL + if let Some(&Some(Some(&x))) = &Some(Some(&mut Some(0))) { | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:56:17 + --> $DIR/pattern-errors.rs:58:17 | LL | if let Some(&mut Some(x)) = &Some(Some(0)) { | ^^^^^ @@ -84,7 +84,7 @@ LL + if let Some(&Some(x)) = &Some(Some(0)) { | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:64:11 + --> $DIR/pattern-errors.rs:66:11 | LL | let &[&mut x] = &&mut [0]; | ^^^^^ @@ -97,7 +97,7 @@ LL + let &[&x] = &&mut [0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:70:11 + --> $DIR/pattern-errors.rs:72:11 | LL | let &[&mut x] = &mut &mut [0]; | ^^^^^ @@ -110,7 +110,7 @@ LL + let &[&x] = &mut &mut [0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:76:11 + --> $DIR/pattern-errors.rs:78:11 | LL | let &[&mut ref x] = &&mut [0]; | ^^^^^ @@ -123,7 +123,7 @@ LL + let &[&ref x] = &&mut [0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:82:11 + --> $DIR/pattern-errors.rs:84:11 | LL | let &[&mut ref x] = &mut &mut [0]; | ^^^^^ @@ -136,7 +136,7 @@ LL + let &[&ref x] = &mut &mut [0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:88:11 + --> $DIR/pattern-errors.rs:90:11 | LL | let &[&mut mut x] = &&mut [0]; | ^^^^^ @@ -149,7 +149,7 @@ LL + let &[&mut x] = &&mut [0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:94:11 + --> $DIR/pattern-errors.rs:96:11 | LL | let &[&mut mut x] = &mut &mut [0]; | ^^^^^ @@ -162,7 +162,7 @@ LL + let &[&mut x] = &mut &mut [0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:114:11 + --> $DIR/pattern-errors.rs:116:11 | LL | let [&&mut x] = &[&mut 0]; | ^^^^^^ --------- this expression has type `&[&mut {integer}; 1]` @@ -178,7 +178,7 @@ LL + let [&x] = &[&mut 0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:121:11 + --> $DIR/pattern-errors.rs:123:11 | LL | let [&&mut x] = &mut [&mut 0]; | ^^^^^^ ------------- this expression has type `&mut [&mut {integer}; 1]` @@ -194,7 +194,7 @@ LL + let [&x] = &mut [&mut 0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:128:11 + --> $DIR/pattern-errors.rs:130:11 | LL | let [&&mut ref x] = &[&mut 0]; | ^^^^^^^^^^ --------- this expression has type `&[&mut {integer}; 1]` @@ -210,7 +210,7 @@ LL + let [&ref x] = &[&mut 0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:135:11 + --> $DIR/pattern-errors.rs:137:11 | LL | let [&&mut ref x] = &mut [&mut 0]; | ^^^^^^^^^^ ------------- this expression has type `&mut [&mut {integer}; 1]` @@ -226,7 +226,7 @@ LL + let [&ref x] = &mut [&mut 0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:142:11 + --> $DIR/pattern-errors.rs:144:11 | LL | let [&&mut mut x] = &[&mut 0]; | ^^^^^^^^^^ --------- this expression has type `&[&mut {integer}; 1]` @@ -242,7 +242,7 @@ LL + let [&mut x] = &[&mut 0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:149:11 + --> $DIR/pattern-errors.rs:151:11 | LL | let [&&mut mut x] = &mut [&mut 0]; | ^^^^^^^^^^ ------------- this expression has type `&mut [&mut {integer}; 1]` @@ -258,7 +258,7 @@ LL + let [&mut x] = &mut [&mut 0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:164:15 + --> $DIR/pattern-errors.rs:166:15 | LL | let [&mut &x] = &[&mut 0]; | ^^ --------- this expression has type `&[&mut {integer}; 1]` @@ -274,7 +274,7 @@ LL + let [&mut x] = &[&mut 0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:170:15 + --> $DIR/pattern-errors.rs:172:15 | LL | let [&mut &ref x] = &[&mut 0]; | ^^^^^^ --------- this expression has type `&[&mut {integer}; 1]` @@ -290,7 +290,7 @@ LL + let [&mut ref x] = &[&mut 0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:176:15 + --> $DIR/pattern-errors.rs:178:15 | LL | let [&mut &(mut x)] = &[&mut 0]; | ^^^^^^^^ --------- this expression has type `&[&mut {integer}; 1]` diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.structural2024.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.structural2024.stderr index 3658893df9c..d3d2c47c29c 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.structural2024.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.structural2024.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:33:17 + --> $DIR/pattern-errors.rs:35:17 | LL | if let Some(&mut Some(&_)) = &Some(&Some(0)) { | ^^^^^ @@ -12,7 +12,7 @@ LL + if let Some(&Some(&_)) = &Some(&Some(0)) { | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:38:23 + --> $DIR/pattern-errors.rs:40:23 | LL | if let Some(&Some(&mut x)) = &Some(&mut Some(0)) { | ^^^^^ @@ -25,7 +25,7 @@ LL + if let Some(&Some(&x)) = &Some(&mut Some(0)) { | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:45:23 + --> $DIR/pattern-errors.rs:47:23 | LL | if let Some(&Some(&mut _)) = &mut Some(&Some(0)) { | ^^^^^ @@ -38,7 +38,7 @@ LL + if let Some(&Some(&_)) = &mut Some(&Some(0)) { | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:50:28 + --> $DIR/pattern-errors.rs:52:28 | LL | if let Some(&Some(Some(&mut x))) = &Some(Some(&mut Some(0))) { | ^^^^^ @@ -51,7 +51,7 @@ LL + if let Some(&Some(Some(&x))) = &Some(Some(&mut Some(0))) { | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:56:17 + --> $DIR/pattern-errors.rs:58:17 | LL | if let Some(&mut Some(x)) = &Some(Some(0)) { | ^^^^^ @@ -64,7 +64,7 @@ LL + if let Some(&Some(x)) = &Some(Some(0)) { | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:64:11 + --> $DIR/pattern-errors.rs:66:11 | LL | let &[&mut x] = &&mut [0]; | ^^^^^ @@ -77,7 +77,7 @@ LL + let &[&x] = &&mut [0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:70:11 + --> $DIR/pattern-errors.rs:72:11 | LL | let &[&mut x] = &mut &mut [0]; | ^^^^^ @@ -90,7 +90,7 @@ LL + let &[&x] = &mut &mut [0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:76:11 + --> $DIR/pattern-errors.rs:78:11 | LL | let &[&mut ref x] = &&mut [0]; | ^^^^^ @@ -103,7 +103,7 @@ LL + let &[&ref x] = &&mut [0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:82:11 + --> $DIR/pattern-errors.rs:84:11 | LL | let &[&mut ref x] = &mut &mut [0]; | ^^^^^ @@ -116,7 +116,7 @@ LL + let &[&ref x] = &mut &mut [0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:88:11 + --> $DIR/pattern-errors.rs:90:11 | LL | let &[&mut mut x] = &&mut [0]; | ^^^^^ @@ -129,7 +129,7 @@ LL + let &[&mut x] = &&mut [0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:94:11 + --> $DIR/pattern-errors.rs:96:11 | LL | let &[&mut mut x] = &mut &mut [0]; | ^^^^^ @@ -142,7 +142,7 @@ LL + let &[&mut x] = &mut &mut [0]; | error[E0658]: binding cannot be both mutable and by-reference - --> $DIR/pattern-errors.rs:102:12 + --> $DIR/pattern-errors.rs:104:12 | LL | let [&(mut x)] = &[&0]; | ^^^^ @@ -152,7 +152,7 @@ LL | let [&(mut x)] = &[&0]; = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: binding cannot be both mutable and by-reference - --> $DIR/pattern-errors.rs:107:12 + --> $DIR/pattern-errors.rs:109:12 | LL | let [&(mut x)] = &mut [&0]; | ^^^^ @@ -162,7 +162,7 @@ LL | let [&(mut x)] = &mut [&0]; = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:114:11 + --> $DIR/pattern-errors.rs:116:11 | LL | let [&&mut x] = &[&mut 0]; | ^^^^^ @@ -175,7 +175,7 @@ LL + let [&&x] = &[&mut 0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:121:11 + --> $DIR/pattern-errors.rs:123:11 | LL | let [&&mut x] = &mut [&mut 0]; | ^^^^^ @@ -188,7 +188,7 @@ LL + let [&&x] = &mut [&mut 0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:128:11 + --> $DIR/pattern-errors.rs:130:11 | LL | let [&&mut ref x] = &[&mut 0]; | ^^^^^ @@ -201,7 +201,7 @@ LL + let [&&ref x] = &[&mut 0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:135:11 + --> $DIR/pattern-errors.rs:137:11 | LL | let [&&mut ref x] = &mut [&mut 0]; | ^^^^^ @@ -214,7 +214,7 @@ LL + let [&&ref x] = &mut [&mut 0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:142:11 + --> $DIR/pattern-errors.rs:144:11 | LL | let [&&mut mut x] = &[&mut 0]; | ^^^^^ @@ -227,7 +227,7 @@ LL + let [&&mut x] = &[&mut 0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:149:11 + --> $DIR/pattern-errors.rs:151:11 | LL | let [&&mut mut x] = &mut [&mut 0]; | ^^^^^ diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.classic2021.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.classic2021.stderr index 1dda2dca4a4..dbb8ae87b66 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.classic2021.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.classic2021.stderr @@ -1,5 +1,5 @@ error[E0596]: cannot borrow data in a `&` reference as mutable - --> $DIR/ref-binding-on-inh-ref-errors.rs:71:10 + --> $DIR/ref-binding-on-inh-ref-errors.rs:73:10 | LL | let [ref mut x] = &[0]; | ^^^^^^^^^ cannot borrow as mutable diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.classic2024.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.classic2024.stderr index 44cb005a748..04e53e06a22 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.classic2024.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.classic2024.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/ref-binding-on-inh-ref-errors.rs:58:10 + --> $DIR/ref-binding-on-inh-ref-errors.rs:60:10 | LL | let [&mut ref x] = &[&mut 0]; | ^^^^^ @@ -12,14 +12,14 @@ LL + let [&ref x] = &[&mut 0]; | error: binding modifiers may only be written when the default binding mode is `move` - --> $DIR/ref-binding-on-inh-ref-errors.rs:71:10 + --> $DIR/ref-binding-on-inh-ref-errors.rs:73:10 | LL | let [ref mut x] = &[0]; | ^^^^^^^ binding modifier not allowed under `ref` default binding mode | = note: for more information, see note: matching on a reference type with a non-reference pattern changes the default binding mode - --> $DIR/ref-binding-on-inh-ref-errors.rs:71:9 + --> $DIR/ref-binding-on-inh-ref-errors.rs:73:9 | LL | let [ref mut x] = &[0]; | ^^^^^^^^^^^ this matches on type `&_` @@ -29,20 +29,20 @@ LL | let &[ref mut x] = &[0]; | + error[E0596]: cannot borrow data in a `&` reference as mutable - --> $DIR/ref-binding-on-inh-ref-errors.rs:71:10 + --> $DIR/ref-binding-on-inh-ref-errors.rs:73:10 | LL | let [ref mut x] = &[0]; | ^^^^^^^^^ cannot borrow as mutable error: binding modifiers may only be written when the default binding mode is `move` - --> $DIR/ref-binding-on-inh-ref-errors.rs:79:10 + --> $DIR/ref-binding-on-inh-ref-errors.rs:81:10 | LL | let [ref x] = &[0]; | ^^^ binding modifier not allowed under `ref` default binding mode | = note: for more information, see note: matching on a reference type with a non-reference pattern changes the default binding mode - --> $DIR/ref-binding-on-inh-ref-errors.rs:79:9 + --> $DIR/ref-binding-on-inh-ref-errors.rs:81:9 | LL | let [ref x] = &[0]; | ^^^^^^^ this matches on type `&_` @@ -52,14 +52,14 @@ LL | let &[ref x] = &[0]; | + error: binding modifiers may only be written when the default binding mode is `move` - --> $DIR/ref-binding-on-inh-ref-errors.rs:83:10 + --> $DIR/ref-binding-on-inh-ref-errors.rs:85:10 | LL | let [ref x] = &mut [0]; | ^^^ binding modifier not allowed under `ref mut` default binding mode | = note: for more information, see note: matching on a reference type with a non-reference pattern changes the default binding mode - --> $DIR/ref-binding-on-inh-ref-errors.rs:83:9 + --> $DIR/ref-binding-on-inh-ref-errors.rs:85:9 | LL | let [ref x] = &mut [0]; | ^^^^^^^ this matches on type `&mut _` @@ -69,14 +69,14 @@ LL | let &mut [ref x] = &mut [0]; | ++++ error: binding modifiers may only be written when the default binding mode is `move` - --> $DIR/ref-binding-on-inh-ref-errors.rs:87:10 + --> $DIR/ref-binding-on-inh-ref-errors.rs:89:10 | LL | let [ref mut x] = &mut [0]; | ^^^^^^^ binding modifier not allowed under `ref mut` default binding mode | = note: for more information, see note: matching on a reference type with a non-reference pattern changes the default binding mode - --> $DIR/ref-binding-on-inh-ref-errors.rs:87:9 + --> $DIR/ref-binding-on-inh-ref-errors.rs:89:9 | LL | let [ref mut x] = &mut [0]; | ^^^^^^^^^^^ this matches on type `&mut _` diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.rs index ea6f028fe4b..c9e3f75cf17 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.rs +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.rs @@ -4,6 +4,8 @@ //@[structural2021] edition: 2021 //@[classic2024] edition: 2024 //@[structural2024] edition: 2024 +//@ dont-require-annotations: NOTE + //! Tests for errors from binding with `ref x` under a by-ref default binding mode in edition 2024. //! These can't be in the same body as tests for other errors, since they're emitted during THIR //! construction. The errors on stable edition 2021 Rust are unrelated. @@ -40,14 +42,14 @@ fn errors_from_eating_the_real_reference() { fn errors_from_eating_the_real_reference_caught_in_hir_typeck_on_stable() { let [&ref x] = &[&mut 0]; //[stable2021]~^ ERROR: mismatched types - //[stable2021]~| types differ in mutability + //[stable2021]~| NOTE types differ in mutability //[structural2024]~^^^ ERROR: binding modifiers may only be written when the default binding mode is `move` #[cfg(any(classic2021, structural2021))] let _: &u32 = x; #[cfg(classic2024)] let _: &&mut u32 = x; let [&ref x] = &mut [&mut 0]; //[stable2021]~^ ERROR: mismatched types - //[stable2021]~| types differ in mutability + //[stable2021]~| NOTE types differ in mutability //[structural2024]~^^^ ERROR: binding modifiers may only be written when the default binding mode is `move` #[cfg(any(classic2021, structural2021))] let _: &u32 = x; #[cfg(classic2024)] let _: &&mut u32 = x; @@ -57,7 +59,7 @@ fn errors_from_eating_the_real_reference_caught_in_hir_typeck_on_stable() { fn errors_dependent_on_eating_order_caught_in_hir_typeck_when_eating_outer() { let [&mut ref x] = &[&mut 0]; //[classic2024]~^ ERROR: mismatched types - //[classic2024]~| cannot match inherited `&` with `&mut` pattern + //[classic2024]~| NOTE cannot match inherited `&` with `&mut` pattern //[structural2024]~^^^ ERROR: binding modifiers may only be written when the default binding mode is `move` #[cfg(any(stable2021, classic2021, structural2021))] let _: &u32 = x; } diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.stable2021.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.stable2021.stderr index 2ec6650dd7d..33119c4447a 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.stable2021.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.stable2021.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/ref-binding-on-inh-ref-errors.rs:41:10 + --> $DIR/ref-binding-on-inh-ref-errors.rs:43:10 | LL | let [&ref x] = &[&mut 0]; | ^^^^^^ --------- this expression has type `&[&mut {integer}; 1]` @@ -15,7 +15,7 @@ LL + let [ref x] = &[&mut 0]; | error[E0308]: mismatched types - --> $DIR/ref-binding-on-inh-ref-errors.rs:48:10 + --> $DIR/ref-binding-on-inh-ref-errors.rs:50:10 | LL | let [&ref x] = &mut [&mut 0]; | ^^^^^^ ------------- this expression has type `&mut [&mut {integer}; 1]` @@ -31,7 +31,7 @@ LL + let [ref x] = &mut [&mut 0]; | error[E0596]: cannot borrow data in a `&` reference as mutable - --> $DIR/ref-binding-on-inh-ref-errors.rs:71:10 + --> $DIR/ref-binding-on-inh-ref-errors.rs:73:10 | LL | let [ref mut x] = &[0]; | ^^^^^^^^^ cannot borrow as mutable diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.structural2021.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.structural2021.stderr index 1dda2dca4a4..dbb8ae87b66 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.structural2021.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.structural2021.stderr @@ -1,5 +1,5 @@ error[E0596]: cannot borrow data in a `&` reference as mutable - --> $DIR/ref-binding-on-inh-ref-errors.rs:71:10 + --> $DIR/ref-binding-on-inh-ref-errors.rs:73:10 | LL | let [ref mut x] = &[0]; | ^^^^^^^^^ cannot borrow as mutable diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.structural2024.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.structural2024.stderr index 6f62ad06cc4..def6deb325a 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.structural2024.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.structural2024.stderr @@ -1,12 +1,12 @@ error: binding modifiers may only be written when the default binding mode is `move` - --> $DIR/ref-binding-on-inh-ref-errors.rs:17:11 + --> $DIR/ref-binding-on-inh-ref-errors.rs:19:11 | LL | let [&ref x] = &[&0]; | ^^^ binding modifier not allowed under `ref` default binding mode | = note: for more information, see note: matching on a reference type with a non-reference pattern changes the default binding mode - --> $DIR/ref-binding-on-inh-ref-errors.rs:17:9 + --> $DIR/ref-binding-on-inh-ref-errors.rs:19:9 | LL | let [&ref x] = &[&0]; | ^^^^^^^^ this matches on type `&_` @@ -16,14 +16,14 @@ LL | let &[&ref x] = &[&0]; | + error: binding modifiers may only be written when the default binding mode is `move` - --> $DIR/ref-binding-on-inh-ref-errors.rs:22:11 + --> $DIR/ref-binding-on-inh-ref-errors.rs:24:11 | LL | let [&ref x] = &mut [&0]; | ^^^ binding modifier not allowed under `ref` default binding mode | = note: for more information, see note: matching on a reference type with a non-reference pattern changes the default binding mode - --> $DIR/ref-binding-on-inh-ref-errors.rs:22:9 + --> $DIR/ref-binding-on-inh-ref-errors.rs:24:9 | LL | let [&ref x] = &mut [&0]; | ^^^^^^^^ this matches on type `&mut _` @@ -33,14 +33,14 @@ LL | let &mut [&ref x] = &mut [&0]; | ++++ error: binding modifiers may only be written when the default binding mode is `move` - --> $DIR/ref-binding-on-inh-ref-errors.rs:27:15 + --> $DIR/ref-binding-on-inh-ref-errors.rs:29:15 | LL | let [&mut ref x] = &mut [&mut 0]; | ^^^ binding modifier not allowed under `ref mut` default binding mode | = note: for more information, see note: matching on a reference type with a non-reference pattern changes the default binding mode - --> $DIR/ref-binding-on-inh-ref-errors.rs:27:9 + --> $DIR/ref-binding-on-inh-ref-errors.rs:29:9 | LL | let [&mut ref x] = &mut [&mut 0]; | ^^^^^^^^^^^^ this matches on type `&mut _` @@ -50,14 +50,14 @@ LL | let &mut [&mut ref x] = &mut [&mut 0]; | ++++ error: binding modifiers may only be written when the default binding mode is `move` - --> $DIR/ref-binding-on-inh-ref-errors.rs:32:15 + --> $DIR/ref-binding-on-inh-ref-errors.rs:34:15 | LL | let [&mut ref mut x] = &mut [&mut 0]; | ^^^^^^^ binding modifier not allowed under `ref mut` default binding mode | = note: for more information, see note: matching on a reference type with a non-reference pattern changes the default binding mode - --> $DIR/ref-binding-on-inh-ref-errors.rs:32:9 + --> $DIR/ref-binding-on-inh-ref-errors.rs:34:9 | LL | let [&mut ref mut x] = &mut [&mut 0]; | ^^^^^^^^^^^^^^^^ this matches on type `&mut _` @@ -67,14 +67,14 @@ LL | let &mut [&mut ref mut x] = &mut [&mut 0]; | ++++ error: binding modifiers may only be written when the default binding mode is `move` - --> $DIR/ref-binding-on-inh-ref-errors.rs:41:11 + --> $DIR/ref-binding-on-inh-ref-errors.rs:43:11 | LL | let [&ref x] = &[&mut 0]; | ^^^ binding modifier not allowed under `ref` default binding mode | = note: for more information, see note: matching on a reference type with a non-reference pattern changes the default binding mode - --> $DIR/ref-binding-on-inh-ref-errors.rs:41:9 + --> $DIR/ref-binding-on-inh-ref-errors.rs:43:9 | LL | let [&ref x] = &[&mut 0]; | ^^^^^^^^ this matches on type `&_` @@ -84,14 +84,14 @@ LL | let &[&ref x] = &[&mut 0]; | + error: binding modifiers may only be written when the default binding mode is `move` - --> $DIR/ref-binding-on-inh-ref-errors.rs:48:11 + --> $DIR/ref-binding-on-inh-ref-errors.rs:50:11 | LL | let [&ref x] = &mut [&mut 0]; | ^^^ binding modifier not allowed under `ref` default binding mode | = note: for more information, see note: matching on a reference type with a non-reference pattern changes the default binding mode - --> $DIR/ref-binding-on-inh-ref-errors.rs:48:9 + --> $DIR/ref-binding-on-inh-ref-errors.rs:50:9 | LL | let [&ref x] = &mut [&mut 0]; | ^^^^^^^^ this matches on type `&mut _` @@ -101,14 +101,14 @@ LL | let &mut [&ref x] = &mut [&mut 0]; | ++++ error: binding modifiers may only be written when the default binding mode is `move` - --> $DIR/ref-binding-on-inh-ref-errors.rs:58:15 + --> $DIR/ref-binding-on-inh-ref-errors.rs:60:15 | LL | let [&mut ref x] = &[&mut 0]; | ^^^ binding modifier not allowed under `ref` default binding mode | = note: for more information, see note: matching on a reference type with a non-reference pattern changes the default binding mode - --> $DIR/ref-binding-on-inh-ref-errors.rs:58:9 + --> $DIR/ref-binding-on-inh-ref-errors.rs:60:9 | LL | let [&mut ref x] = &[&mut 0]; | ^^^^^^^^^^^^ this matches on type `&_` @@ -118,14 +118,14 @@ LL | let &[&mut ref x] = &[&mut 0]; | + error: binding modifiers may only be written when the default binding mode is `move` - --> $DIR/ref-binding-on-inh-ref-errors.rs:71:10 + --> $DIR/ref-binding-on-inh-ref-errors.rs:73:10 | LL | let [ref mut x] = &[0]; | ^^^^^^^ binding modifier not allowed under `ref` default binding mode | = note: for more information, see note: matching on a reference type with a non-reference pattern changes the default binding mode - --> $DIR/ref-binding-on-inh-ref-errors.rs:71:9 + --> $DIR/ref-binding-on-inh-ref-errors.rs:73:9 | LL | let [ref mut x] = &[0]; | ^^^^^^^^^^^ this matches on type `&_` @@ -135,20 +135,20 @@ LL | let &[ref mut x] = &[0]; | + error[E0596]: cannot borrow data in a `&` reference as mutable - --> $DIR/ref-binding-on-inh-ref-errors.rs:71:10 + --> $DIR/ref-binding-on-inh-ref-errors.rs:73:10 | LL | let [ref mut x] = &[0]; | ^^^^^^^^^ cannot borrow as mutable error: binding modifiers may only be written when the default binding mode is `move` - --> $DIR/ref-binding-on-inh-ref-errors.rs:79:10 + --> $DIR/ref-binding-on-inh-ref-errors.rs:81:10 | LL | let [ref x] = &[0]; | ^^^ binding modifier not allowed under `ref` default binding mode | = note: for more information, see note: matching on a reference type with a non-reference pattern changes the default binding mode - --> $DIR/ref-binding-on-inh-ref-errors.rs:79:9 + --> $DIR/ref-binding-on-inh-ref-errors.rs:81:9 | LL | let [ref x] = &[0]; | ^^^^^^^ this matches on type `&_` @@ -158,14 +158,14 @@ LL | let &[ref x] = &[0]; | + error: binding modifiers may only be written when the default binding mode is `move` - --> $DIR/ref-binding-on-inh-ref-errors.rs:83:10 + --> $DIR/ref-binding-on-inh-ref-errors.rs:85:10 | LL | let [ref x] = &mut [0]; | ^^^ binding modifier not allowed under `ref mut` default binding mode | = note: for more information, see note: matching on a reference type with a non-reference pattern changes the default binding mode - --> $DIR/ref-binding-on-inh-ref-errors.rs:83:9 + --> $DIR/ref-binding-on-inh-ref-errors.rs:85:9 | LL | let [ref x] = &mut [0]; | ^^^^^^^ this matches on type `&mut _` @@ -175,14 +175,14 @@ LL | let &mut [ref x] = &mut [0]; | ++++ error: binding modifiers may only be written when the default binding mode is `move` - --> $DIR/ref-binding-on-inh-ref-errors.rs:87:10 + --> $DIR/ref-binding-on-inh-ref-errors.rs:89:10 | LL | let [ref mut x] = &mut [0]; | ^^^^^^^ binding modifier not allowed under `ref mut` default binding mode | = note: for more information, see note: matching on a reference type with a non-reference pattern changes the default binding mode - --> $DIR/ref-binding-on-inh-ref-errors.rs:87:9 + --> $DIR/ref-binding-on-inh-ref-errors.rs:89:9 | LL | let [ref mut x] = &mut [0]; | ^^^^^^^^^^^ this matches on type `&mut _` diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.classic2021.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.classic2021.stderr index f8c2bd9a921..9bf5c9544e5 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.classic2021.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.classic2021.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:32:23 + --> $DIR/well-typed-edition-2024.rs:34:23 | LL | if let Some(Some(&&x)) = &Some(Some(&0)) { | ^^ --------------- this expression has type `&Option>` @@ -15,7 +15,7 @@ LL + if let Some(Some(&x)) = &Some(Some(&0)) { | error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:63:23 + --> $DIR/well-typed-edition-2024.rs:65:23 | LL | if let Some(&Some(&x)) = &Some(&Some(0)) { | ^^ --------------- this expression has type `&Option<&Option<{integer}>>` @@ -31,7 +31,7 @@ LL + if let Some(&Some(x)) = &Some(&Some(0)) { | error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:82:23 + --> $DIR/well-typed-edition-2024.rs:84:23 | LL | if let Some(&Some(&x)) = &Some(&mut Some(0)) { | ^^ ------------------- this expression has type `&Option<&mut Option<{integer}>>` @@ -47,7 +47,7 @@ LL + if let Some(&Some(x)) = &Some(&mut Some(0)) { | error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:88:23 + --> $DIR/well-typed-edition-2024.rs:90:23 | LL | if let Some(&Some(&x)) = &mut Some(&Some(0)) { | ^^ ------------------- this expression has type `&mut Option<&Option<{integer}>>` @@ -63,7 +63,7 @@ LL + if let Some(&Some(x)) = &mut Some(&Some(0)) { | error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:123:15 + --> $DIR/well-typed-edition-2024.rs:125:15 | LL | let [&mut &x] = &mut [&0]; | ^^ --------- this expression has type `&mut [&{integer}; 1]` @@ -79,7 +79,7 @@ LL + let [&mut x] = &mut [&0]; | error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:129:15 + --> $DIR/well-typed-edition-2024.rs:131:15 | LL | let [&mut &ref x] = &mut [&0]; | ^^^^^^ --------- this expression has type `&mut [&{integer}; 1]` @@ -95,7 +95,7 @@ LL + let [&mut ref x] = &mut [&0]; | error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:135:15 + --> $DIR/well-typed-edition-2024.rs:137:15 | LL | let [&mut &(mut x)] = &mut [&0]; | ^^^^^^^^ --------- this expression has type `&mut [&{integer}; 1]` @@ -111,7 +111,7 @@ LL + let [&mut mut x)] = &mut [&0]; | error[E0596]: cannot borrow data in a `&` reference as mutable - --> $DIR/well-typed-edition-2024.rs:109:19 + --> $DIR/well-typed-edition-2024.rs:111:19 | LL | let [&mut ref mut x] = &mut [&0]; | ^^^^^^^^^ cannot borrow as mutable diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.rs index 877b10dcfd5..e2913e0f60a 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.rs +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.rs @@ -6,6 +6,8 @@ //@[structural2024] edition: 2024 //@[classic2024] run-pass //@[structural2024] run-pass +//@ dont-require-annotations: NOTE + //! Test cases for well-typed patterns in edition 2024. These are in their own file to ensure we //! pass both HIR typeck and MIR borrowck, as we may skip the latter if grouped with failing tests. #![allow(incomplete_features, unused_mut)] @@ -31,63 +33,63 @@ pub fn main() { } if let Some(Some(&&x)) = &Some(Some(&0)) { //[stable2021,classic2021,structural2021]~^ ERROR mismatched types - //[stable2021,classic2021,structural2021]~| expected integer, found `&_` + //[stable2021,classic2021,structural2021]~| NOTE expected integer, found `&_` #[cfg(any(classic2024, structural2024))] let _: u32 = x; } // Tests for eating a lone inherited reference if let Some(Some(&x)) = &Some(&Some(0)) { //[stable2021]~^ ERROR mismatched types - //[stable2021]~| expected integer, found `&_` + //[stable2021]~| NOTE expected integer, found `&_` #[cfg(any(classic2021, structural2021, classic2024, structural2024))] let _: u32 = x; } if let Some(&Some(x)) = &Some(Some(0)) { //[stable2021]~^ ERROR mismatched types - //[stable2021]~| expected `Option<{integer}>`, found `&_` + //[stable2021]~| NOTE expected `Option<{integer}>`, found `&_` #[cfg(any(classic2021, structural2021, classic2024, structural2024))] let _: u32 = x; } if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) { //[stable2021]~^ ERROR mismatched types - //[stable2021]~| expected integer, found `&mut _` + //[stable2021]~| NOTE expected integer, found `&mut _` #[cfg(any(classic2021, structural2021, classic2024, structural2024))] let _: u32 = x; } // Tests for `&` patterns matching real `&mut` reference types if let Some(&Some(&x)) = Some(&Some(&mut 0)) { //[stable2021]~^ ERROR mismatched types - //[stable2021]~| types differ in mutability + //[stable2021]~| NOTE types differ in mutability #[cfg(any(classic2021, structural2021, classic2024, structural2024))] let _: u32 = x; } // Tests for eating only one layer and also eating a lone inherited reference if let Some(&Some(&x)) = &Some(&Some(0)) { //[stable2021,classic2021,structural2021]~^ ERROR mismatched types - //[stable2021,classic2021,structural2021]~| expected integer, found `&_` + //[stable2021,classic2021,structural2021]~| NOTE expected integer, found `&_` #[cfg(any(classic2024, structural2024))] let _: u32 = x; } // Tests for `&` matching a lone inherited possibly-`&mut` reference if let Some(&Some(Some(&x))) = &Some(Some(&mut Some(0))) { //[stable2021]~^ ERROR mismatched types - //[stable2021]~| expected `Option<&mut Option<{integer}>>`, found `&_` + //[stable2021]~| NOTE expected `Option<&mut Option<{integer}>>`, found `&_` #[cfg(any(classic2021, structural2021, classic2024, structural2024))] let _: u32 = x; } if let Some(&Some(x)) = &mut Some(Some(0)) { //[stable2021]~^ ERROR mismatched types - //[stable2021]~| expected `Option<{integer}>`, found `&_` + //[stable2021]~| NOTE expected `Option<{integer}>`, found `&_` #[cfg(any(classic2021, structural2021, classic2024, structural2024))] let _: u32 = x; } // Tests eating one layer, eating a lone inherited ref, and `&` eating `&mut` (realness varies) if let Some(&Some(&x)) = &Some(&mut Some(0)) { //[stable2021,classic2021,structural2021]~^ ERROR mismatched types - //[stable2021]~| types differ in mutability - //[classic2021,structural2021]~| expected integer, found `&_` + //[stable2021]~| NOTE types differ in mutability + //[classic2021,structural2021]~| NOTE expected integer, found `&_` #[cfg(any(classic2024, structural2024))] let _: u32 = x; } if let Some(&Some(&x)) = &mut Some(&Some(0)) { //[stable2021,classic2021,structural2021]~^ ERROR mismatched types - //[stable2021,classic2021,structural2021]~| expected integer, found `&_` + //[stable2021,classic2021,structural2021]~| NOTE expected integer, found `&_` #[cfg(any(classic2024, structural2024))] let _: u32 = x; } @@ -95,20 +97,20 @@ pub fn main() { // inner reference causes a mutability mismatch. i.e. tests for "fallback-to-outer" deref rules. let [&mut x] = &mut [&0]; //[stable2021]~^ ERROR mismatched types - //[stable2021]~| types differ in mutability + //[stable2021]~| NOTE types differ in mutability #[cfg(any(classic2021, structural2021))] let _: u32 = x; #[cfg(any(classic2024, structural2024))] let _: &u32 = x; let [&mut ref x] = &mut [&0]; //[stable2021]~^ ERROR mismatched types - //[stable2021]~| types differ in mutability + //[stable2021]~| NOTE types differ in mutability #[cfg(any(classic2021, structural2021))] let _: &u32 = x; #[cfg(any(classic2024, structural2024))] let _: &&u32 = x; fn borrowck_error_on_structural2021() { let [&mut ref mut x] = &mut [&0]; //[stable2021]~^ ERROR mismatched types - //[stable2021]~| types differ in mutability + //[stable2021]~| NOTE types differ in mutability //[classic2021,structural2021]~^^^ ERROR cannot borrow data in a `&` reference as mutable #[cfg(any(classic2024, structural2024))] let _: &mut &u32 = x; } @@ -116,25 +118,25 @@ pub fn main() { let [&mut mut x] = &mut [&0]; //[stable2021]~^ ERROR mismatched types - //[stable2021]~| types differ in mutability + //[stable2021]~| NOTE types differ in mutability #[cfg(any(classic2021, structural2021))] let _: u32 = x; #[cfg(any(classic2024, structural2024))] let _: &u32 = x; let [&mut &x] = &mut [&0]; //[stable2021,classic2021,structural2021]~^ ERROR mismatched types - //[stable2021]~| types differ in mutability - //[classic2021,structural2021]~| expected integer, found `&_` + //[stable2021]~| NOTE types differ in mutability + //[classic2021,structural2021]~| NOTE expected integer, found `&_` #[cfg(any(classic2024, structural2024))] let _: u32 = x; let [&mut &ref x] = &mut [&0]; //[stable2021,classic2021,structural2021]~^ ERROR mismatched types - //[stable2021]~| types differ in mutability - //[classic2021,structural2021]~| expected integer, found `&_` + //[stable2021]~| NOTE types differ in mutability + //[classic2021,structural2021]~| NOTE expected integer, found `&_` #[cfg(any(classic2024, structural2024))] let _: &u32 = x; let [&mut &(mut x)] = &mut [&0]; //[stable2021,classic2021,structural2021]~^ ERROR mismatched types - //[stable2021]~| types differ in mutability - //[classic2021,structural2021]~| expected integer, found `&_` + //[stable2021]~| NOTE types differ in mutability + //[classic2021,structural2021]~| NOTE expected integer, found `&_` #[cfg(any(classic2024, structural2024))] let _: u32 = x; } diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.stable2021.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.stable2021.stderr index adb47172f34..4f9dfaf639c 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.stable2021.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.stable2021.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:32:23 + --> $DIR/well-typed-edition-2024.rs:34:23 | LL | if let Some(Some(&&x)) = &Some(Some(&0)) { | ^^ --------------- this expression has type `&Option>` @@ -15,7 +15,7 @@ LL + if let Some(Some(&x)) = &Some(Some(&0)) { | error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:39:22 + --> $DIR/well-typed-edition-2024.rs:41:22 | LL | if let Some(Some(&x)) = &Some(&Some(0)) { | ^^ --------------- this expression has type `&Option<&Option<{integer}>>` @@ -31,7 +31,7 @@ LL + if let Some(Some(x)) = &Some(&Some(0)) { | error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:44:17 + --> $DIR/well-typed-edition-2024.rs:46:17 | LL | if let Some(&Some(x)) = &Some(Some(0)) { | ^^^^^^^^ -------------- this expression has type `&Option>` @@ -42,7 +42,7 @@ LL | if let Some(&Some(x)) = &Some(Some(0)) { found reference `&_` error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:49:22 + --> $DIR/well-typed-edition-2024.rs:51:22 | LL | if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) { | ^^^^^^ ----------------------- this expression has type `&mut Option<&mut Option<{integer}>>` @@ -52,7 +52,7 @@ LL | if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) { = note: expected type `{integer}` found mutable reference `&mut _` note: to declare a mutable binding use: `mut x` - --> $DIR/well-typed-edition-2024.rs:49:22 + --> $DIR/well-typed-edition-2024.rs:51:22 | LL | if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) { | ^^^^^^ @@ -63,7 +63,7 @@ LL + if let Some(Some(x)) = &mut Some(&mut Some(0)) { | error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:56:23 + --> $DIR/well-typed-edition-2024.rs:58:23 | LL | if let Some(&Some(&x)) = Some(&Some(&mut 0)) { | ^^ ------------------- this expression has type `Option<&Option<&mut {integer}>>` @@ -79,7 +79,7 @@ LL + if let Some(&Some(x)) = Some(&Some(&mut 0)) { | error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:63:23 + --> $DIR/well-typed-edition-2024.rs:65:23 | LL | if let Some(&Some(&x)) = &Some(&Some(0)) { | ^^ --------------- this expression has type `&Option<&Option<{integer}>>` @@ -95,7 +95,7 @@ LL + if let Some(&Some(x)) = &Some(&Some(0)) { | error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:70:17 + --> $DIR/well-typed-edition-2024.rs:72:17 | LL | if let Some(&Some(Some(&x))) = &Some(Some(&mut Some(0))) { | ^^^^^^^^^^^^^^^ ------------------------- this expression has type `&Option>>` @@ -106,7 +106,7 @@ LL | if let Some(&Some(Some(&x))) = &Some(Some(&mut Some(0))) { found reference `&_` error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:75:17 + --> $DIR/well-typed-edition-2024.rs:77:17 | LL | if let Some(&Some(x)) = &mut Some(Some(0)) { | ^^^^^^^^ ------------------ this expression has type `&mut Option>` @@ -117,7 +117,7 @@ LL | if let Some(&Some(x)) = &mut Some(Some(0)) { found reference `&_` error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:82:17 + --> $DIR/well-typed-edition-2024.rs:84:17 | LL | if let Some(&Some(&x)) = &Some(&mut Some(0)) { | ^^^^^^^^^ ------------------- this expression has type `&Option<&mut Option<{integer}>>` @@ -128,7 +128,7 @@ LL | if let Some(&Some(&x)) = &Some(&mut Some(0)) { found reference `&_` error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:88:23 + --> $DIR/well-typed-edition-2024.rs:90:23 | LL | if let Some(&Some(&x)) = &mut Some(&Some(0)) { | ^^ ------------------- this expression has type `&mut Option<&Option<{integer}>>` @@ -144,7 +144,7 @@ LL + if let Some(&Some(x)) = &mut Some(&Some(0)) { | error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:96:10 + --> $DIR/well-typed-edition-2024.rs:98:10 | LL | let [&mut x] = &mut [&0]; | ^^^^^^ --------- this expression has type `&mut [&{integer}; 1]` @@ -154,7 +154,7 @@ LL | let [&mut x] = &mut [&0]; = note: expected reference `&{integer}` found mutable reference `&mut _` note: to declare a mutable binding use: `mut x` - --> $DIR/well-typed-edition-2024.rs:96:10 + --> $DIR/well-typed-edition-2024.rs:98:10 | LL | let [&mut x] = &mut [&0]; | ^^^^^^ @@ -165,7 +165,7 @@ LL + let [x] = &mut [&0]; | error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:102:10 + --> $DIR/well-typed-edition-2024.rs:104:10 | LL | let [&mut ref x] = &mut [&0]; | ^^^^^^^^^^ --------- this expression has type `&mut [&{integer}; 1]` @@ -175,7 +175,7 @@ LL | let [&mut ref x] = &mut [&0]; = note: expected reference `&{integer}` found mutable reference `&mut _` note: to declare a mutable binding use: `mut x` - --> $DIR/well-typed-edition-2024.rs:102:10 + --> $DIR/well-typed-edition-2024.rs:104:10 | LL | let [&mut ref x] = &mut [&0]; | ^^^^^^^^^^ @@ -186,7 +186,7 @@ LL + let [ref x] = &mut [&0]; | error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:117:10 + --> $DIR/well-typed-edition-2024.rs:119:10 | LL | let [&mut mut x] = &mut [&0]; | ^^^^^^^^^^ --------- this expression has type `&mut [&{integer}; 1]` @@ -196,7 +196,7 @@ LL | let [&mut mut x] = &mut [&0]; = note: expected reference `&{integer}` found mutable reference `&mut _` note: to declare a mutable binding use: `mut x` - --> $DIR/well-typed-edition-2024.rs:117:10 + --> $DIR/well-typed-edition-2024.rs:119:10 | LL | let [&mut mut x] = &mut [&0]; | ^^^^^^^^^^ @@ -207,7 +207,7 @@ LL + let [mut x] = &mut [&0]; | error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:123:10 + --> $DIR/well-typed-edition-2024.rs:125:10 | LL | let [&mut &x] = &mut [&0]; | ^^^^^^^ --------- this expression has type `&mut [&{integer}; 1]` @@ -218,7 +218,7 @@ LL | let [&mut &x] = &mut [&0]; found mutable reference `&mut _` error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:129:10 + --> $DIR/well-typed-edition-2024.rs:131:10 | LL | let [&mut &ref x] = &mut [&0]; | ^^^^^^^^^^^ --------- this expression has type `&mut [&{integer}; 1]` @@ -229,7 +229,7 @@ LL | let [&mut &ref x] = &mut [&0]; found mutable reference `&mut _` error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:135:10 + --> $DIR/well-typed-edition-2024.rs:137:10 | LL | let [&mut &(mut x)] = &mut [&0]; | ^^^^^^^^^^^^^ --------- this expression has type `&mut [&{integer}; 1]` @@ -240,7 +240,7 @@ LL | let [&mut &(mut x)] = &mut [&0]; found mutable reference `&mut _` error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:109:14 + --> $DIR/well-typed-edition-2024.rs:111:14 | LL | let [&mut ref mut x] = &mut [&0]; | ^^^^^^^^^^^^^^ --------- this expression has type `&mut [&{integer}; 1]` @@ -250,7 +250,7 @@ LL | let [&mut ref mut x] = &mut [&0]; = note: expected reference `&{integer}` found mutable reference `&mut _` note: to declare a mutable binding use: `mut x` - --> $DIR/well-typed-edition-2024.rs:109:14 + --> $DIR/well-typed-edition-2024.rs:111:14 | LL | let [&mut ref mut x] = &mut [&0]; | ^^^^^^^^^^^^^^ diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.structural2021.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.structural2021.stderr index f8c2bd9a921..9bf5c9544e5 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.structural2021.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.structural2021.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:32:23 + --> $DIR/well-typed-edition-2024.rs:34:23 | LL | if let Some(Some(&&x)) = &Some(Some(&0)) { | ^^ --------------- this expression has type `&Option>` @@ -15,7 +15,7 @@ LL + if let Some(Some(&x)) = &Some(Some(&0)) { | error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:63:23 + --> $DIR/well-typed-edition-2024.rs:65:23 | LL | if let Some(&Some(&x)) = &Some(&Some(0)) { | ^^ --------------- this expression has type `&Option<&Option<{integer}>>` @@ -31,7 +31,7 @@ LL + if let Some(&Some(x)) = &Some(&Some(0)) { | error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:82:23 + --> $DIR/well-typed-edition-2024.rs:84:23 | LL | if let Some(&Some(&x)) = &Some(&mut Some(0)) { | ^^ ------------------- this expression has type `&Option<&mut Option<{integer}>>` @@ -47,7 +47,7 @@ LL + if let Some(&Some(x)) = &Some(&mut Some(0)) { | error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:88:23 + --> $DIR/well-typed-edition-2024.rs:90:23 | LL | if let Some(&Some(&x)) = &mut Some(&Some(0)) { | ^^ ------------------- this expression has type `&mut Option<&Option<{integer}>>` @@ -63,7 +63,7 @@ LL + if let Some(&Some(x)) = &mut Some(&Some(0)) { | error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:123:15 + --> $DIR/well-typed-edition-2024.rs:125:15 | LL | let [&mut &x] = &mut [&0]; | ^^ --------- this expression has type `&mut [&{integer}; 1]` @@ -79,7 +79,7 @@ LL + let [&mut x] = &mut [&0]; | error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:129:15 + --> $DIR/well-typed-edition-2024.rs:131:15 | LL | let [&mut &ref x] = &mut [&0]; | ^^^^^^ --------- this expression has type `&mut [&{integer}; 1]` @@ -95,7 +95,7 @@ LL + let [&mut ref x] = &mut [&0]; | error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:135:15 + --> $DIR/well-typed-edition-2024.rs:137:15 | LL | let [&mut &(mut x)] = &mut [&0]; | ^^^^^^^^ --------- this expression has type `&mut [&{integer}; 1]` @@ -111,7 +111,7 @@ LL + let [&mut mut x)] = &mut [&0]; | error[E0596]: cannot borrow data in a `&` reference as mutable - --> $DIR/well-typed-edition-2024.rs:109:19 + --> $DIR/well-typed-edition-2024.rs:111:19 | LL | let [&mut ref mut x] = &mut [&0]; | ^^^^^^^^^ cannot borrow as mutable diff --git a/tests/ui/pattern/usefulness/issue-31561.rs b/tests/ui/pattern/usefulness/issue-31561.rs index 82414f0418b..fe1b2bb4f83 100644 --- a/tests/ui/pattern/usefulness/issue-31561.rs +++ b/tests/ui/pattern/usefulness/issue-31561.rs @@ -1,3 +1,5 @@ +//@ dont-require-annotations: NOTE + enum Thing { Foo(u8), Bar, @@ -7,5 +9,5 @@ enum Thing { fn main() { let Thing::Foo(y) = Thing::Foo(1); //~^ ERROR refutable pattern in local binding - //~| `Thing::Bar` and `Thing::Baz` not covered + //~| NOTE `Thing::Bar` and `Thing::Baz` not covered } diff --git a/tests/ui/pattern/usefulness/issue-31561.stderr b/tests/ui/pattern/usefulness/issue-31561.stderr index ba7ae3fa9a0..382b2337ffa 100644 --- a/tests/ui/pattern/usefulness/issue-31561.stderr +++ b/tests/ui/pattern/usefulness/issue-31561.stderr @@ -1,5 +1,5 @@ error[E0005]: refutable pattern in local binding - --> $DIR/issue-31561.rs:8:9 + --> $DIR/issue-31561.rs:10:9 | LL | let Thing::Foo(y) = Thing::Foo(1); | ^^^^^^^^^^^^^ patterns `Thing::Bar` and `Thing::Baz` not covered @@ -7,7 +7,7 @@ LL | let Thing::Foo(y) = Thing::Foo(1); = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html note: `Thing` defined here - --> $DIR/issue-31561.rs:1:6 + --> $DIR/issue-31561.rs:3:6 | LL | enum Thing { | ^^^^^ diff --git a/tests/ui/pattern/usefulness/issue-39362.rs b/tests/ui/pattern/usefulness/issue-39362.rs index ea3c8f88e0b..0db3980359c 100644 --- a/tests/ui/pattern/usefulness/issue-39362.rs +++ b/tests/ui/pattern/usefulness/issue-39362.rs @@ -1,3 +1,5 @@ +//@ dont-require-annotations: NOTE + enum Foo { Bar { bar: Bar, id: usize } } @@ -9,7 +11,7 @@ enum Bar { fn test(f: Foo) { match f { //~^ ERROR non-exhaustive patterns - //~| patterns + //~| NOTE patterns Foo::Bar { bar: Bar::A, .. } => (), Foo::Bar { bar: Bar::B, .. } => (), } diff --git a/tests/ui/pattern/usefulness/issue-39362.stderr b/tests/ui/pattern/usefulness/issue-39362.stderr index 9cce87a1c65..18d542cc6ad 100644 --- a/tests/ui/pattern/usefulness/issue-39362.stderr +++ b/tests/ui/pattern/usefulness/issue-39362.stderr @@ -1,11 +1,11 @@ error[E0004]: non-exhaustive patterns: `Foo::Bar { bar: Bar::C, .. }`, `Foo::Bar { bar: Bar::D, .. }`, `Foo::Bar { bar: Bar::E, .. }` and 1 more not covered - --> $DIR/issue-39362.rs:10:11 + --> $DIR/issue-39362.rs:12:11 | LL | match f { | ^ patterns `Foo::Bar { bar: Bar::C, .. }`, `Foo::Bar { bar: Bar::D, .. }`, `Foo::Bar { bar: Bar::E, .. }` and 1 more not covered | note: `Foo` defined here - --> $DIR/issue-39362.rs:1:6 + --> $DIR/issue-39362.rs:3:6 | LL | enum Foo { | ^^^ diff --git a/tests/ui/pattern/usefulness/issue-72377.rs b/tests/ui/pattern/usefulness/issue-72377.rs index b5ad3075ca7..782a9963f2e 100644 --- a/tests/ui/pattern/usefulness/issue-72377.rs +++ b/tests/ui/pattern/usefulness/issue-72377.rs @@ -7,7 +7,8 @@ fn main() { match (x, y) { //~^ ERROR non-exhaustive patterns: `(X::A, Some(X::A))`, `(X::A, Some(X::B))`, `(X::B, Some(X::B))` and 2 - //~| more not covered + //~| NOTE more not covered + //~| NOTE the matched value is of type `(X, Option)` (_, None) => false, (v, Some(w)) if v == w => true, (X::B, Some(X::C)) => false, diff --git a/tests/ui/pattern/usefulness/refutable-pattern-errors.rs b/tests/ui/pattern/usefulness/refutable-pattern-errors.rs index 7603da1bb2c..de9fc24bbd0 100644 --- a/tests/ui/pattern/usefulness/refutable-pattern-errors.rs +++ b/tests/ui/pattern/usefulness/refutable-pattern-errors.rs @@ -1,9 +1,11 @@ +//@ dont-require-annotations: NOTE + fn func((1, (Some(1), 2..=3)): (isize, (Option, isize))) {} //~^ ERROR refutable pattern in function argument -//~| `(..=0_isize, _)` and `(2_isize.., _)` not covered +//~| NOTE `(..=0_isize, _)` and `(2_isize.., _)` not covered fn main() { let (1, (Some(1), 2..=3)) = (1, (None, 2)); //~^ ERROR refutable pattern in local binding - //~| `(i32::MIN..=0_i32, _)` and `(2_i32..=i32::MAX, _)` not covered + //~| NOTE `(i32::MIN..=0_i32, _)` and `(2_i32..=i32::MAX, _)` not covered } diff --git a/tests/ui/pattern/usefulness/refutable-pattern-errors.stderr b/tests/ui/pattern/usefulness/refutable-pattern-errors.stderr index 23a5d895d6c..37d1dc3efe9 100644 --- a/tests/ui/pattern/usefulness/refutable-pattern-errors.stderr +++ b/tests/ui/pattern/usefulness/refutable-pattern-errors.stderr @@ -1,5 +1,5 @@ error[E0005]: refutable pattern in function argument - --> $DIR/refutable-pattern-errors.rs:1:9 + --> $DIR/refutable-pattern-errors.rs:3:9 | LL | fn func((1, (Some(1), 2..=3)): (isize, (Option, isize))) {} | ^^^^^^^^^^^^^^^^^^^^^ patterns `(..=0_isize, _)` and `(2_isize.., _)` not covered @@ -7,7 +7,7 @@ LL | fn func((1, (Some(1), 2..=3)): (isize, (Option, isize))) {} = note: the matched value is of type `(isize, (Option, isize))` error[E0005]: refutable pattern in local binding - --> $DIR/refutable-pattern-errors.rs:6:9 + --> $DIR/refutable-pattern-errors.rs:8:9 | LL | let (1, (Some(1), 2..=3)) = (1, (None, 2)); | ^^^^^^^^^^^^^^^^^^^^^ patterns `(i32::MIN..=0_i32, _)` and `(2_i32..=i32::MAX, _)` not covered diff --git a/tests/ui/pattern/usefulness/refutable-pattern-in-fn-arg.rs b/tests/ui/pattern/usefulness/refutable-pattern-in-fn-arg.rs index 51ff641509d..416564d94dc 100644 --- a/tests/ui/pattern/usefulness/refutable-pattern-in-fn-arg.rs +++ b/tests/ui/pattern/usefulness/refutable-pattern-in-fn-arg.rs @@ -1,6 +1,7 @@ fn main() { let f = |3: isize| println!("hello"); //~^ ERROR refutable pattern in closure argument - //~| `..=2_isize` and `4_isize..` not covered + //~| NOTE `..=2_isize` and `4_isize..` not covered + //~| NOTE the matched value is of type `isize` f(4); } diff --git a/tests/ui/pptypedef.rs b/tests/ui/pptypedef.rs index e28d323f883..d5f43df9d85 100644 --- a/tests/ui/pptypedef.rs +++ b/tests/ui/pptypedef.rs @@ -1,11 +1,13 @@ +//@ dont-require-annotations: NOTE + fn let_in(x: T, f: F) where F: FnOnce(T) {} fn main() { let_in(3u32, |i| { assert!(i == 3i32); }); //~^ ERROR mismatched types - //~| expected `u32`, found `i32` + //~| NOTE expected `u32`, found `i32` let_in(3i32, |i| { assert!(i == 3u32); }); //~^ ERROR mismatched types - //~| expected `i32`, found `u32` + //~| NOTE expected `i32`, found `u32` } diff --git a/tests/ui/pptypedef.stderr b/tests/ui/pptypedef.stderr index 96327cfcc65..a6d673e61c6 100644 --- a/tests/ui/pptypedef.stderr +++ b/tests/ui/pptypedef.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/pptypedef.rs:4:37 + --> $DIR/pptypedef.rs:6:37 | LL | let_in(3u32, |i| { assert!(i == 3i32); }); | - ^^^^ expected `u32`, found `i32` @@ -13,7 +13,7 @@ LL + let_in(3u32, |i| { assert!(i == 3u32); }); | error[E0308]: mismatched types - --> $DIR/pptypedef.rs:8:37 + --> $DIR/pptypedef.rs:10:37 | LL | let_in(3i32, |i| { assert!(i == 3u32); }); | - ^^^^ expected `i32`, found `u32` diff --git a/tests/ui/privacy/privacy2.rs b/tests/ui/privacy/privacy2.rs index c82cd442559..e44100a8059 100644 --- a/tests/ui/privacy/privacy2.rs +++ b/tests/ui/privacy/privacy2.rs @@ -1,4 +1,5 @@ //@ compile-flags: -Zdeduplicate-diagnostics=yes +//@ dont-require-annotations: NOTE #![feature(no_core)] #![no_core] // makes debugging this test *a lot* easier (during resolve) @@ -20,7 +21,7 @@ fn test1() { //~^ ERROR requires `sized` lang_item use bar::foo; //~^ ERROR unresolved import `bar::foo` [E0432] - //~| no `foo` in `bar` + //~| NOTE no `foo` in `bar` } fn test2() { diff --git a/tests/ui/privacy/privacy2.stderr b/tests/ui/privacy/privacy2.stderr index 39bab67a660..b70134965fa 100644 --- a/tests/ui/privacy/privacy2.stderr +++ b/tests/ui/privacy/privacy2.stderr @@ -1,34 +1,34 @@ error[E0432]: unresolved import `bar::foo` - --> $DIR/privacy2.rs:21:9 + --> $DIR/privacy2.rs:22:9 | LL | use bar::foo; | ^^^^^^^^ no `foo` in `bar` error[E0603]: function import `foo` is private - --> $DIR/privacy2.rs:28:20 + --> $DIR/privacy2.rs:29:20 | LL | use bar::glob::foo; | ^^^ private function import | note: the function import `foo` is defined here... - --> $DIR/privacy2.rs:12:13 + --> $DIR/privacy2.rs:13:13 | LL | use foo; | ^^^ note: ...and refers to the function `foo` which is defined here - --> $DIR/privacy2.rs:16:1 + --> $DIR/privacy2.rs:17:1 | LL | pub fn foo() {} | ^^^^^^^^^^^^ you could import this directly error: requires `sized` lang_item - --> $DIR/privacy2.rs:16:14 + --> $DIR/privacy2.rs:17:14 | LL | pub fn foo() {} | ^^ error: requires `sized` lang_item - --> $DIR/privacy2.rs:19:12 + --> $DIR/privacy2.rs:20:12 | LL | fn test1() { | ____________^ @@ -39,7 +39,7 @@ LL | | } | |_^ error: requires `sized` lang_item - --> $DIR/privacy2.rs:26:12 + --> $DIR/privacy2.rs:27:12 | LL | fn test2() { | ____________^ @@ -50,7 +50,7 @@ LL | | } | |_^ error: requires `sized` lang_item - --> $DIR/privacy2.rs:32:11 + --> $DIR/privacy2.rs:33:11 | LL | fn main() {} | ^^ diff --git a/tests/ui/ptr-coercion.rs b/tests/ui/ptr-coercion.rs index 193899034c7..2549bd6f134 100644 --- a/tests/ui/ptr-coercion.rs +++ b/tests/ui/ptr-coercion.rs @@ -1,23 +1,25 @@ // Test coercions between pointers which don't do anything fancy like unsizing. // These are testing that we don't lose mutability when converting to raw pointers. +//@ dont-require-annotations: NOTE + pub fn main() { // *const -> *mut let x: *const isize = &42; let x: *mut isize = x; //~ ERROR mismatched types - //~| expected raw pointer `*mut isize` - //~| found raw pointer `*const isize` - //~| types differ in mutability + //~| NOTE expected raw pointer `*mut isize` + //~| NOTE found raw pointer `*const isize` + //~| NOTE types differ in mutability // & -> *mut let x: *mut isize = &42; //~ ERROR mismatched types - //~| expected raw pointer `*mut isize` - //~| found reference `&isize` - //~| types differ in mutability + //~| NOTE expected raw pointer `*mut isize` + //~| NOTE found reference `&isize` + //~| NOTE types differ in mutability let x: *const isize = &42; let x: *mut isize = x; //~ ERROR mismatched types - //~| expected raw pointer `*mut isize` - //~| found raw pointer `*const isize` - //~| types differ in mutability + //~| NOTE expected raw pointer `*mut isize` + //~| NOTE found raw pointer `*const isize` + //~| NOTE types differ in mutability } diff --git a/tests/ui/ptr-coercion.stderr b/tests/ui/ptr-coercion.stderr index 29b7e5da849..8de41d2c382 100644 --- a/tests/ui/ptr-coercion.stderr +++ b/tests/ui/ptr-coercion.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/ptr-coercion.rs:7:25 + --> $DIR/ptr-coercion.rs:9:25 | LL | let x: *mut isize = x; | ---------- ^ types differ in mutability @@ -10,7 +10,7 @@ LL | let x: *mut isize = x; found raw pointer `*const isize` error[E0308]: mismatched types - --> $DIR/ptr-coercion.rs:13:25 + --> $DIR/ptr-coercion.rs:15:25 | LL | let x: *mut isize = &42; | ---------- ^^^ types differ in mutability @@ -21,7 +21,7 @@ LL | let x: *mut isize = &42; found reference `&isize` error[E0308]: mismatched types - --> $DIR/ptr-coercion.rs:19:25 + --> $DIR/ptr-coercion.rs:21:25 | LL | let x: *mut isize = x; | ---------- ^ types differ in mutability diff --git a/tests/ui/recursion_limit/empty.rs b/tests/ui/recursion_limit/empty.rs index 59dae106c00..5987fa2f881 100644 --- a/tests/ui/recursion_limit/empty.rs +++ b/tests/ui/recursion_limit/empty.rs @@ -1,8 +1,9 @@ // Test the parse error for an empty recursion_limit #![recursion_limit = ""] //~ ERROR `limit` must be a non-negative integer - //~| `limit` must be a non-negative integer + //~| NOTE `limit` must be a non-negative integer //~| ERROR `limit` must be a non-negative integer - //~| `limit` must be a non-negative integer + //~| NOTE `limit` must be a non-negative integer + //~| NOTE duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` fn main() {} diff --git a/tests/ui/recursion_limit/invalid_digit.rs b/tests/ui/recursion_limit/invalid_digit.rs index 03df3e7a927..79d8f3708ba 100644 --- a/tests/ui/recursion_limit/invalid_digit.rs +++ b/tests/ui/recursion_limit/invalid_digit.rs @@ -1,7 +1,8 @@ // Test the parse error for an invalid digit in recursion_limit #![recursion_limit = "-100"] //~ ERROR `limit` must be a non-negative integer - //~| not a valid integer + //~| NOTE not a valid integer //~| ERROR `limit` must be a non-negative integer - //~| not a valid integer + //~| NOTE not a valid integer + //~| NOTE duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` fn main() {} diff --git a/tests/ui/recursion_limit/overflow.rs b/tests/ui/recursion_limit/overflow.rs index c733ba6b93c..7cd1d572e09 100644 --- a/tests/ui/recursion_limit/overflow.rs +++ b/tests/ui/recursion_limit/overflow.rs @@ -2,8 +2,9 @@ #![recursion_limit = "999999999999999999999999"] //~^ ERROR `limit` must be a non-negative integer -//~| `limit` is too large +//~| NOTE `limit` is too large //~| ERROR `limit` must be a non-negative integer -//~| `limit` is too large +//~| NOTE `limit` is too large +//~| NOTE duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` fn main() {} diff --git a/tests/ui/repeat-expr/repeat_count.rs b/tests/ui/repeat-expr/repeat_count.rs index 18610bc5bb0..2febcdc07c2 100644 --- a/tests/ui/repeat-expr/repeat_count.rs +++ b/tests/ui/repeat-expr/repeat_count.rs @@ -1,34 +1,36 @@ // Regression test for issue #3645 +//@ dont-require-annotations: NOTE + fn main() { let n = 1; let a = [0; n]; //~^ ERROR attempt to use a non-constant value in a constant [E0435] let b = [0; ()]; //~^ ERROR mismatched types - //~| expected `usize`, found `()` + //~| NOTE expected `usize`, found `()` let c = [0; true]; //~^ ERROR mismatched types - //~| expected `usize`, found `bool` + //~| NOTE expected `usize`, found `bool` let d = [0; 0.5]; //~^ ERROR mismatched types - //~| expected `usize`, found floating-point number + //~| NOTE expected `usize`, found floating-point number let e = [0; "foo"]; //~^ ERROR mismatched types - //~| expected `usize`, found `&str` + //~| NOTE expected `usize`, found `&str` let f = [0; -4_isize]; //~^ ERROR mismatched types - //~| expected `usize`, found `isize` + //~| NOTE expected `usize`, found `isize` let f = [0_usize; -1_isize]; //~^ ERROR mismatched types - //~| expected `usize`, found `isize` + //~| NOTE expected `usize`, found `isize` let f = [0; 4u8]; //~^ ERROR mismatched types - //~| expected `usize`, found `u8` + //~| NOTE expected `usize`, found `u8` struct G { g: (), } let g = [0; G { g: () }]; //~^ ERROR mismatched types - //~| expected `usize`, found `G` + //~| NOTE expected `usize`, found `G` } diff --git a/tests/ui/repeat-expr/repeat_count.stderr b/tests/ui/repeat-expr/repeat_count.stderr index 34e29e83666..cf94ad41ee3 100644 --- a/tests/ui/repeat-expr/repeat_count.stderr +++ b/tests/ui/repeat-expr/repeat_count.stderr @@ -1,5 +1,5 @@ error[E0435]: attempt to use a non-constant value in a constant - --> $DIR/repeat_count.rs:5:17 + --> $DIR/repeat_count.rs:7:17 | LL | let a = [0; n]; | ^ non-constant value @@ -11,37 +11,37 @@ LL + const n: /* Type */ = 1; | error[E0308]: mismatched types - --> $DIR/repeat_count.rs:7:17 + --> $DIR/repeat_count.rs:9:17 | LL | let b = [0; ()]; | ^^ expected `usize`, found `()` error[E0308]: mismatched types - --> $DIR/repeat_count.rs:31:17 + --> $DIR/repeat_count.rs:33:17 | LL | let g = [0; G { g: () }]; | ^^^^^^^^^^^ expected `usize`, found `G` error[E0308]: mismatched types - --> $DIR/repeat_count.rs:10:17 + --> $DIR/repeat_count.rs:12:17 | LL | let c = [0; true]; | ^^^^ expected `usize`, found `bool` error[E0308]: mismatched types - --> $DIR/repeat_count.rs:13:17 + --> $DIR/repeat_count.rs:15:17 | LL | let d = [0; 0.5]; | ^^^ expected `usize`, found floating-point number error[E0308]: mismatched types - --> $DIR/repeat_count.rs:16:17 + --> $DIR/repeat_count.rs:18:17 | LL | let e = [0; "foo"]; | ^^^^^ expected `usize`, found `&str` error[E0308]: mismatched types - --> $DIR/repeat_count.rs:19:17 + --> $DIR/repeat_count.rs:21:17 | LL | let f = [0; -4_isize]; | ^^^^^^^^ expected `usize`, found `isize` @@ -49,7 +49,7 @@ LL | let f = [0; -4_isize]; = note: `-4_isize` cannot fit into type `usize` error[E0308]: mismatched types - --> $DIR/repeat_count.rs:22:23 + --> $DIR/repeat_count.rs:24:23 | LL | let f = [0_usize; -1_isize]; | ^^^^^^^^ expected `usize`, found `isize` @@ -57,7 +57,7 @@ LL | let f = [0_usize; -1_isize]; = note: `-1_isize` cannot fit into type `usize` error[E0308]: mismatched types - --> $DIR/repeat_count.rs:25:17 + --> $DIR/repeat_count.rs:27:17 | LL | let f = [0; 4u8]; | ^^^ expected `usize`, found `u8` diff --git a/tests/ui/resolve/issue-23716.rs b/tests/ui/resolve/issue-23716.rs index e9139c0aa14..61b42e29f10 100644 --- a/tests/ui/resolve/issue-23716.rs +++ b/tests/ui/resolve/issue-23716.rs @@ -1,8 +1,10 @@ +//@ dont-require-annotations: NOTE + static foo: i32 = 0; fn bar(foo: i32) {} //~^ ERROR function parameters cannot shadow statics -//~| cannot be named the same as a static +//~| NOTE cannot be named the same as a static mod submod { pub static answer: i32 = 42; @@ -12,6 +14,6 @@ use self::submod::answer; fn question(answer: i32) {} //~^ ERROR function parameters cannot shadow statics -//~| cannot be named the same as a static +//~| NOTE cannot be named the same as a static fn main() { } diff --git a/tests/ui/resolve/issue-23716.stderr b/tests/ui/resolve/issue-23716.stderr index 8b89c350c84..23650c48ac4 100644 --- a/tests/ui/resolve/issue-23716.stderr +++ b/tests/ui/resolve/issue-23716.stderr @@ -1,5 +1,5 @@ error[E0530]: function parameters cannot shadow statics - --> $DIR/issue-23716.rs:3:8 + --> $DIR/issue-23716.rs:5:8 | LL | static foo: i32 = 0; | -------------------- the static `foo` is defined here @@ -8,7 +8,7 @@ LL | fn bar(foo: i32) {} | ^^^ cannot be named the same as a static error[E0530]: function parameters cannot shadow statics - --> $DIR/issue-23716.rs:13:13 + --> $DIR/issue-23716.rs:15:13 | LL | use self::submod::answer; | -------------------- the static `answer` is imported here diff --git a/tests/ui/resolve/issue-5035.rs b/tests/ui/resolve/issue-5035.rs index 49fa312f9d2..82c4bc0d5ef 100644 --- a/tests/ui/resolve/issue-5035.rs +++ b/tests/ui/resolve/issue-5035.rs @@ -1,9 +1,11 @@ +//@ dont-require-annotations: NOTE + trait I {} type K = dyn I; impl K for isize {} //~ ERROR expected trait, found type alias `K` use ImportError; //~ ERROR unresolved import `ImportError` [E0432] - //~^ no `ImportError` in the root + //~^ NOTE no `ImportError` in the root impl ImportError for () {} // check that this is not an additional error (cf. issue #35142) fn main() {} diff --git a/tests/ui/resolve/issue-5035.stderr b/tests/ui/resolve/issue-5035.stderr index b249aaa4b28..f5717438fc8 100644 --- a/tests/ui/resolve/issue-5035.stderr +++ b/tests/ui/resolve/issue-5035.stderr @@ -1,11 +1,11 @@ error[E0432]: unresolved import `ImportError` - --> $DIR/issue-5035.rs:5:5 + --> $DIR/issue-5035.rs:7:5 | LL | use ImportError; | ^^^^^^^^^^^ no `ImportError` in the root error[E0404]: expected trait, found type alias `K` - --> $DIR/issue-5035.rs:3:6 + --> $DIR/issue-5035.rs:5:6 | LL | trait I {} | ------- similarly named trait `I` defined here diff --git a/tests/ui/resolve/resolve-conflict-item-vs-import.rs b/tests/ui/resolve/resolve-conflict-item-vs-import.rs index 4308c7a2750..830f02cdcbe 100644 --- a/tests/ui/resolve/resolve-conflict-item-vs-import.rs +++ b/tests/ui/resolve/resolve-conflict-item-vs-import.rs @@ -1,8 +1,8 @@ -use std::mem::transmute; +use std::mem::transmute; //~ NOTE previous import of the value `transmute` here fn transmute() {} //~^ ERROR the name `transmute` is defined multiple times -//~| `transmute` redefined here -//~| `transmute` must be defined only once in the value namespace of this module +//~| NOTE `transmute` redefined here +//~| NOTE `transmute` must be defined only once in the value namespace of this module fn main() { } diff --git a/tests/ui/rfcs/rfc-2008-non-exhaustive/enum_same_crate_empty_match.rs b/tests/ui/rfcs/rfc-2008-non-exhaustive/enum_same_crate_empty_match.rs index 69a283c3163..167f90b28d5 100644 --- a/tests/ui/rfcs/rfc-2008-non-exhaustive/enum_same_crate_empty_match.rs +++ b/tests/ui/rfcs/rfc-2008-non-exhaustive/enum_same_crate_empty_match.rs @@ -1,22 +1,24 @@ +//@ dont-require-annotations: NOTE + #![deny(unreachable_patterns)] #[non_exhaustive] pub enum NonExhaustiveEnum { Unit, - //~^ not covered + //~^ NOTE not covered Tuple(u32), - //~^ not covered + //~^ NOTE not covered Struct { field: u32 } - //~^ not covered + //~^ NOTE not covered } pub enum NormalEnum { Unit, - //~^ not covered + //~^ NOTE not covered Tuple(u32), - //~^ not covered + //~^ NOTE not covered Struct { field: u32 } - //~^ not covered + //~^ NOTE not covered } #[non_exhaustive] diff --git a/tests/ui/rfcs/rfc-2008-non-exhaustive/enum_same_crate_empty_match.stderr b/tests/ui/rfcs/rfc-2008-non-exhaustive/enum_same_crate_empty_match.stderr index 100e0a501e0..2112344fe6e 100644 --- a/tests/ui/rfcs/rfc-2008-non-exhaustive/enum_same_crate_empty_match.stderr +++ b/tests/ui/rfcs/rfc-2008-non-exhaustive/enum_same_crate_empty_match.stderr @@ -1,5 +1,5 @@ error: unreachable pattern - --> $DIR/enum_same_crate_empty_match.rs:28:9 + --> $DIR/enum_same_crate_empty_match.rs:30:9 | LL | _ => {} | ^------ @@ -9,19 +9,19 @@ LL | _ => {} | = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types note: the lint level is defined here - --> $DIR/enum_same_crate_empty_match.rs:1:9 + --> $DIR/enum_same_crate_empty_match.rs:3:9 | LL | #![deny(unreachable_patterns)] | ^^^^^^^^^^^^^^^^^^^^ error[E0004]: non-exhaustive patterns: `NonExhaustiveEnum::Unit`, `NonExhaustiveEnum::Tuple(_)` and `NonExhaustiveEnum::Struct { .. }` not covered - --> $DIR/enum_same_crate_empty_match.rs:33:11 + --> $DIR/enum_same_crate_empty_match.rs:35:11 | LL | match NonExhaustiveEnum::Unit {} | ^^^^^^^^^^^^^^^^^^^^^^^ patterns `NonExhaustiveEnum::Unit`, `NonExhaustiveEnum::Tuple(_)` and `NonExhaustiveEnum::Struct { .. }` not covered | note: `NonExhaustiveEnum` defined here - --> $DIR/enum_same_crate_empty_match.rs:4:10 + --> $DIR/enum_same_crate_empty_match.rs:6:10 | LL | pub enum NonExhaustiveEnum { | ^^^^^^^^^^^^^^^^^ @@ -42,13 +42,13 @@ LL ~ } | error[E0004]: non-exhaustive patterns: `NormalEnum::Unit`, `NormalEnum::Tuple(_)` and `NormalEnum::Struct { .. }` not covered - --> $DIR/enum_same_crate_empty_match.rs:35:11 + --> $DIR/enum_same_crate_empty_match.rs:37:11 | LL | match NormalEnum::Unit {} | ^^^^^^^^^^^^^^^^ patterns `NormalEnum::Unit`, `NormalEnum::Tuple(_)` and `NormalEnum::Struct { .. }` not covered | note: `NormalEnum` defined here - --> $DIR/enum_same_crate_empty_match.rs:13:10 + --> $DIR/enum_same_crate_empty_match.rs:15:10 | LL | pub enum NormalEnum { | ^^^^^^^^^^ diff --git a/tests/ui/rfcs/rfc-2008-non-exhaustive/omitted-patterns.rs b/tests/ui/rfcs/rfc-2008-non-exhaustive/omitted-patterns.rs index ba800e315b1..1e746fdbbea 100644 --- a/tests/ui/rfcs/rfc-2008-non-exhaustive/omitted-patterns.rs +++ b/tests/ui/rfcs/rfc-2008-non-exhaustive/omitted-patterns.rs @@ -1,5 +1,7 @@ // Test that the `non_exhaustive_omitted_patterns` lint is triggered correctly. +//@ dont-require-annotations: NOTE + #![feature(non_exhaustive_omitted_patterns_lint, unstable_test_feature)] #![deny(unreachable_patterns)] @@ -231,7 +233,7 @@ fn main() { // Check that matching on a reference results in a correct diagnostic match &non_enum { //~^ ERROR some variants are not matched explicitly - //~| pattern `&NonExhaustiveEnum::Struct { .. }` not covered + //~| NOTE pattern `&NonExhaustiveEnum::Struct { .. }` not covered NonExhaustiveEnum::Unit => {} NonExhaustiveEnum::Tuple(_) => {} _ => {} @@ -239,21 +241,21 @@ fn main() { match (true, &non_enum) { //~^ ERROR some variants are not matched explicitly - //~| patterns `(_, &NonExhaustiveEnum::Tuple(_))` and `(_, &NonExhaustiveEnum::Struct { .. })` not covered + //~| NOTE patterns `(_, &NonExhaustiveEnum::Tuple(_))` and `(_, &NonExhaustiveEnum::Struct { .. })` not covered (true, NonExhaustiveEnum::Unit) => {} _ => {} } match (&non_enum, true) { //~^ ERROR some variants are not matched explicitly - //~| patterns `(&NonExhaustiveEnum::Tuple(_), _)` and `(&NonExhaustiveEnum::Struct { .. }, _)` not covered + //~| NOTE patterns `(&NonExhaustiveEnum::Tuple(_), _)` and `(&NonExhaustiveEnum::Struct { .. }, _)` not covered (NonExhaustiveEnum::Unit, true) => {} _ => {} } match Some(&non_enum) { //~^ ERROR some variants are not matched explicitly - //~| pattern `Some(&NonExhaustiveEnum::Struct { .. })` not covered + //~| NOTE pattern `Some(&NonExhaustiveEnum::Struct { .. })` not covered Some(NonExhaustiveEnum::Unit | NonExhaustiveEnum::Tuple(_)) => {} _ => {} } diff --git a/tests/ui/rfcs/rfc-2008-non-exhaustive/omitted-patterns.stderr b/tests/ui/rfcs/rfc-2008-non-exhaustive/omitted-patterns.stderr index f89ae241f44..c2c9ac15ab2 100644 --- a/tests/ui/rfcs/rfc-2008-non-exhaustive/omitted-patterns.stderr +++ b/tests/ui/rfcs/rfc-2008-non-exhaustive/omitted-patterns.stderr @@ -1,5 +1,5 @@ error: some fields are not explicitly listed - --> $DIR/omitted-patterns.rs:139:9 + --> $DIR/omitted-patterns.rs:141:9 | LL | VariantNonExhaustive::Bar { x, .. } => {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ field `y` not listed @@ -7,13 +7,13 @@ LL | VariantNonExhaustive::Bar { x, .. } => {} = help: ensure that all fields are mentioned explicitly by adding the suggested fields = note: the pattern is of type `VariantNonExhaustive` and the `non_exhaustive_omitted_patterns` attribute was found note: the lint level is defined here - --> $DIR/omitted-patterns.rs:45:8 + --> $DIR/omitted-patterns.rs:47:8 | LL | #[deny(non_exhaustive_omitted_patterns)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: some fields are not explicitly listed - --> $DIR/omitted-patterns.rs:143:9 + --> $DIR/omitted-patterns.rs:145:9 | LL | let FunctionalRecord { first_field, second_field, .. } = FunctionalRecord::default(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ field `third_field` not listed @@ -22,7 +22,7 @@ LL | let FunctionalRecord { first_field, second_field, .. } = FunctionalReco = note: the pattern is of type `FunctionalRecord` and the `non_exhaustive_omitted_patterns` attribute was found error: some fields are not explicitly listed - --> $DIR/omitted-patterns.rs:149:29 + --> $DIR/omitted-patterns.rs:151:29 | LL | let NestedStruct { bar: NormalStruct { first_field, .. }, .. } = NestedStruct::default(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ field `second_field` not listed @@ -31,7 +31,7 @@ LL | let NestedStruct { bar: NormalStruct { first_field, .. }, .. } = Nested = note: the pattern is of type `NormalStruct` and the `non_exhaustive_omitted_patterns` attribute was found error: some fields are not explicitly listed - --> $DIR/omitted-patterns.rs:149:9 + --> $DIR/omitted-patterns.rs:151:9 | LL | let NestedStruct { bar: NormalStruct { first_field, .. }, .. } = NestedStruct::default(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ field `foo` not listed @@ -40,7 +40,7 @@ LL | let NestedStruct { bar: NormalStruct { first_field, .. }, .. } = Nested = note: the pattern is of type `NestedStruct` and the `non_exhaustive_omitted_patterns` attribute was found error: some fields are not explicitly listed - --> $DIR/omitted-patterns.rs:212:9 + --> $DIR/omitted-patterns.rs:214:9 | LL | let OnlyUnstableStruct { unstable, .. } = OnlyUnstableStruct::new(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ field `unstable2` not listed @@ -49,7 +49,7 @@ LL | let OnlyUnstableStruct { unstable, .. } = OnlyUnstableStruct::new(); = note: the pattern is of type `OnlyUnstableStruct` and the `non_exhaustive_omitted_patterns` attribute was found error: some fields are not explicitly listed - --> $DIR/omitted-patterns.rs:218:9 + --> $DIR/omitted-patterns.rs:220:9 | LL | let UnstableStruct { stable, stable2, .. } = UnstableStruct::default(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ field `unstable` not listed @@ -58,7 +58,7 @@ LL | let UnstableStruct { stable, stable2, .. } = UnstableStruct::default(); = note: the pattern is of type `UnstableStruct` and the `non_exhaustive_omitted_patterns` attribute was found error: some variants are not matched explicitly - --> $DIR/omitted-patterns.rs:65:11 + --> $DIR/omitted-patterns.rs:67:11 | LL | match non_enum { | ^^^^^^^^ pattern `NonExhaustiveEnum::Struct { .. }` not covered @@ -67,7 +67,7 @@ LL | match non_enum { = note: the matched value is of type `NonExhaustiveEnum` and the `non_exhaustive_omitted_patterns` attribute was found error: some variants are not matched explicitly - --> $DIR/omitted-patterns.rs:72:11 + --> $DIR/omitted-patterns.rs:74:11 | LL | match non_enum { | ^^^^^^^^ pattern `NonExhaustiveEnum::Tuple(_)` not covered @@ -76,7 +76,7 @@ LL | match non_enum { = note: the matched value is of type `NonExhaustiveEnum` and the `non_exhaustive_omitted_patterns` attribute was found error: some variants are not matched explicitly - --> $DIR/omitted-patterns.rs:93:11 + --> $DIR/omitted-patterns.rs:95:11 | LL | match (non_enum, true) { | ^^^^^^^^^^^^^^^^ pattern `(NonExhaustiveEnum::Struct { .. }, _)` not covered @@ -85,7 +85,7 @@ LL | match (non_enum, true) { = note: the matched value is of type `(NonExhaustiveEnum, bool)` and the `non_exhaustive_omitted_patterns` attribute was found error: some variants are not matched explicitly - --> $DIR/omitted-patterns.rs:106:11 + --> $DIR/omitted-patterns.rs:108:11 | LL | match (true, non_enum) { | ^^^^^^^^^^^^^^^^ pattern `(_, NonExhaustiveEnum::Struct { .. })` not covered @@ -94,7 +94,7 @@ LL | match (true, non_enum) { = note: the matched value is of type `(bool, NonExhaustiveEnum)` and the `non_exhaustive_omitted_patterns` attribute was found error: some variants are not matched explicitly - --> $DIR/omitted-patterns.rs:113:11 + --> $DIR/omitted-patterns.rs:115:11 | LL | match Some(non_enum) { | ^^^^^^^^^^^^^^ pattern `Some(NonExhaustiveEnum::Struct { .. })` not covered @@ -103,7 +103,7 @@ LL | match Some(non_enum) { = note: the matched value is of type `Option` and the `non_exhaustive_omitted_patterns` attribute was found error: some variants are not matched explicitly - --> $DIR/omitted-patterns.rs:129:11 + --> $DIR/omitted-patterns.rs:131:11 | LL | match NestedNonExhaustive::B { | ^^^^^^^^^^^^^^^^^^^^^^ patterns `NestedNonExhaustive::C`, `NestedNonExhaustive::A(NonExhaustiveEnum::Tuple(_))` and `NestedNonExhaustive::A(NonExhaustiveEnum::Struct { .. })` not covered @@ -112,7 +112,7 @@ LL | match NestedNonExhaustive::B { = note: the matched value is of type `NestedNonExhaustive` and the `non_exhaustive_omitted_patterns` attribute was found error: some variants are not matched explicitly - --> $DIR/omitted-patterns.rs:184:11 + --> $DIR/omitted-patterns.rs:186:11 | LL | match UnstableEnum::Stable { | ^^^^^^^^^^^^^^^^^^^^ pattern `UnstableEnum::Unstable` not covered @@ -121,7 +121,7 @@ LL | match UnstableEnum::Stable { = note: the matched value is of type `UnstableEnum` and the `non_exhaustive_omitted_patterns` attribute was found error: some variants are not matched explicitly - --> $DIR/omitted-patterns.rs:206:11 + --> $DIR/omitted-patterns.rs:208:11 | LL | match OnlyUnstableEnum::Unstable { | ^^^^^^^^^^^^^^^^^^^^^^^^^^ pattern `OnlyUnstableEnum::Unstable2` not covered @@ -130,7 +130,7 @@ LL | match OnlyUnstableEnum::Unstable { = note: the matched value is of type `OnlyUnstableEnum` and the `non_exhaustive_omitted_patterns` attribute was found error[E0005]: refutable pattern in local binding - --> $DIR/omitted-patterns.rs:228:9 + --> $DIR/omitted-patterns.rs:230:9 | LL | let local_refutable @ NonExhaustiveEnum::Unit = NonExhaustiveEnum::Unit; | ^^^^^^^^^^^^^^^ pattern `_` not covered @@ -144,7 +144,7 @@ LL | let local_refutable @ NonExhaustiveEnum::Unit = NonExhaustiveEnum::Unit | ++++++++++++++++ error: some variants are not matched explicitly - --> $DIR/omitted-patterns.rs:232:11 + --> $DIR/omitted-patterns.rs:234:11 | LL | match &non_enum { | ^^^^^^^^^ pattern `&NonExhaustiveEnum::Struct { .. }` not covered @@ -153,7 +153,7 @@ LL | match &non_enum { = note: the matched value is of type `&NonExhaustiveEnum` and the `non_exhaustive_omitted_patterns` attribute was found error: some variants are not matched explicitly - --> $DIR/omitted-patterns.rs:240:11 + --> $DIR/omitted-patterns.rs:242:11 | LL | match (true, &non_enum) { | ^^^^^^^^^^^^^^^^^ patterns `(_, &NonExhaustiveEnum::Tuple(_))` and `(_, &NonExhaustiveEnum::Struct { .. })` not covered @@ -162,7 +162,7 @@ LL | match (true, &non_enum) { = note: the matched value is of type `(bool, &NonExhaustiveEnum)` and the `non_exhaustive_omitted_patterns` attribute was found error: some variants are not matched explicitly - --> $DIR/omitted-patterns.rs:247:11 + --> $DIR/omitted-patterns.rs:249:11 | LL | match (&non_enum, true) { | ^^^^^^^^^^^^^^^^^ patterns `(&NonExhaustiveEnum::Tuple(_), _)` and `(&NonExhaustiveEnum::Struct { .. }, _)` not covered @@ -171,7 +171,7 @@ LL | match (&non_enum, true) { = note: the matched value is of type `(&NonExhaustiveEnum, bool)` and the `non_exhaustive_omitted_patterns` attribute was found error: some variants are not matched explicitly - --> $DIR/omitted-patterns.rs:254:11 + --> $DIR/omitted-patterns.rs:256:11 | LL | match Some(&non_enum) { | ^^^^^^^^^^^^^^^ pattern `Some(&NonExhaustiveEnum::Struct { .. })` not covered diff --git a/tests/ui/simd/const-err-trumps-simd-err.rs b/tests/ui/simd/const-err-trumps-simd-err.rs index fb87fe1cbca..05a224d037a 100644 --- a/tests/ui/simd/const-err-trumps-simd-err.rs +++ b/tests/ui/simd/const-err-trumps-simd-err.rs @@ -1,4 +1,6 @@ //@build-fail +//@ dont-require-annotations: NOTE + //! Make sure that monomorphization-time const errors from `static_assert` take priority over the //! error from simd_extract. Basically this checks that if a const fails to evaluate in some //! function, we don't bother codegen'ing the function. @@ -15,7 +17,7 @@ struct int8x4_t([u8; 4]); fn get_elem(a: int8x4_t) -> u8 { const { assert!(LANE < 4); } // the error should be here... //~^ ERROR failed - //~| assertion failed + //~| NOTE assertion failed unsafe { simd_extract(a, LANE) } // ...not here } diff --git a/tests/ui/simd/const-err-trumps-simd-err.stderr b/tests/ui/simd/const-err-trumps-simd-err.stderr index a0f1c664a4f..389f75492c6 100644 --- a/tests/ui/simd/const-err-trumps-simd-err.stderr +++ b/tests/ui/simd/const-err-trumps-simd-err.stderr @@ -1,17 +1,17 @@ error[E0080]: evaluation of `get_elem::<4>::{constant#0}` failed - --> $DIR/const-err-trumps-simd-err.rs:16:13 + --> $DIR/const-err-trumps-simd-err.rs:18:13 | LL | const { assert!(LANE < 4); } // the error should be here... | ^^^^^^^^^^^^^^^^^ evaluation panicked: assertion failed: LANE < 4 note: erroneous constant encountered - --> $DIR/const-err-trumps-simd-err.rs:16:5 + --> $DIR/const-err-trumps-simd-err.rs:18:5 | LL | const { assert!(LANE < 4); } // the error should be here... | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: the above error was encountered while instantiating `fn get_elem::<4>` - --> $DIR/const-err-trumps-simd-err.rs:23:5 + --> $DIR/const-err-trumps-simd-err.rs:25:5 | LL | get_elem::<4>(int8x4_t([0, 0, 0, 0])); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/structs/default-field-values/failures.rs b/tests/ui/structs/default-field-values/failures.rs index 4461302e841..dee6566bd0e 100644 --- a/tests/ui/structs/default-field-values/failures.rs +++ b/tests/ui/structs/default-field-values/failures.rs @@ -1,4 +1,6 @@ - #![feature(default_field_values)] +//@ dont-require-annotations: HELP + +#![feature(default_field_values)] #[derive(Debug)] pub struct S; @@ -56,10 +58,10 @@ fn main () { let _ = Bar { bar: S, .. }; // ok let _ = Qux::<4> { .. }; let _ = Rak(..); //~ ERROR E0308 - //~^ you might have meant to use `..` to skip providing + //~^ HELP you might have meant to use `..` to skip providing let _ = Rak(0, ..); //~ ERROR E0061 - //~^ you might have meant to use `..` to skip providing + //~^ HELP you might have meant to use `..` to skip providing let _ = Rak(.., 0); //~ ERROR E0061 - //~^ you might have meant to use `..` to skip providing + //~^ HELP you might have meant to use `..` to skip providing let _ = Rak { .. }; // ok } diff --git a/tests/ui/structs/default-field-values/failures.stderr b/tests/ui/structs/default-field-values/failures.stderr index 21c9bfb44b4..aaa75fd3180 100644 --- a/tests/ui/structs/default-field-values/failures.stderr +++ b/tests/ui/structs/default-field-values/failures.stderr @@ -1,5 +1,5 @@ error: the `#[default]` attribute may only be used on unit enum variants or variants where every field has a default value - --> $DIR/failures.rs:47:5 + --> $DIR/failures.rs:49:5 | LL | Variant {} | ^^^^^^^ @@ -7,13 +7,13 @@ LL | Variant {} = help: consider a manual implementation of `Default` error: default fields are not supported in tuple structs - --> $DIR/failures.rs:26:22 + --> $DIR/failures.rs:28:22 | LL | pub struct Rak(i32 = 42); | ^^ default fields are only supported on structs error[E0277]: the trait bound `S: Default` is not satisfied - --> $DIR/failures.rs:14:5 + --> $DIR/failures.rs:16:5 | LL | #[derive(Debug, Default)] | ------- in this derive macro expansion @@ -28,19 +28,19 @@ LL | pub struct S; | error: missing field `bar` in initializer - --> $DIR/failures.rs:53:19 + --> $DIR/failures.rs:55:19 | LL | let _ = Bar { .. }; | ^ fields that do not have a defaulted value must be provided explicitly error: missing field `bar` in initializer - --> $DIR/failures.rs:54:27 + --> $DIR/failures.rs:56:27 | LL | let _ = Bar { baz: 0, .. }; | ^ fields that do not have a defaulted value must be provided explicitly error[E0308]: mismatched types - --> $DIR/failures.rs:58:17 + --> $DIR/failures.rs:60:17 | LL | let _ = Rak(..); | --- ^^ expected `i32`, found `RangeFull` @@ -48,29 +48,29 @@ LL | let _ = Rak(..); | arguments to this struct are incorrect | note: tuple struct defined here - --> $DIR/failures.rs:26:12 + --> $DIR/failures.rs:28:12 | LL | pub struct Rak(i32 = 42); | ^^^ help: you might have meant to use `..` to skip providing a value for expected fields, but this is only supported on non-tuple struct literals; it is instead interpreted as a `std::ops::RangeFull` literal - --> $DIR/failures.rs:58:17 + --> $DIR/failures.rs:60:17 | LL | let _ = Rak(..); | ^^ error[E0061]: this struct takes 1 argument but 2 arguments were supplied - --> $DIR/failures.rs:60:13 + --> $DIR/failures.rs:62:13 | LL | let _ = Rak(0, ..); | ^^^ -- unexpected argument #2 of type `RangeFull` | help: you might have meant to use `..` to skip providing a value for expected fields, but this is only supported on non-tuple struct literals; it is instead interpreted as a `std::ops::RangeFull` literal - --> $DIR/failures.rs:60:20 + --> $DIR/failures.rs:62:20 | LL | let _ = Rak(0, ..); | ^^ note: tuple struct defined here - --> $DIR/failures.rs:26:12 + --> $DIR/failures.rs:28:12 | LL | pub struct Rak(i32 = 42); | ^^^ @@ -81,18 +81,18 @@ LL + let _ = Rak(0); | error[E0061]: this struct takes 1 argument but 2 arguments were supplied - --> $DIR/failures.rs:62:13 + --> $DIR/failures.rs:64:13 | LL | let _ = Rak(.., 0); | ^^^ -- unexpected argument #1 of type `RangeFull` | help: you might have meant to use `..` to skip providing a value for expected fields, but this is only supported on non-tuple struct literals; it is instead interpreted as a `std::ops::RangeFull` literal - --> $DIR/failures.rs:62:17 + --> $DIR/failures.rs:64:17 | LL | let _ = Rak(.., 0); | ^^ note: tuple struct defined here - --> $DIR/failures.rs:26:12 + --> $DIR/failures.rs:28:12 | LL | pub struct Rak(i32 = 42); | ^^^ diff --git a/tests/ui/structs/structure-constructor-type-mismatch.rs b/tests/ui/structs/structure-constructor-type-mismatch.rs index 21cd9d08b21..495deb01ea9 100644 --- a/tests/ui/structs/structure-constructor-type-mismatch.rs +++ b/tests/ui/structs/structure-constructor-type-mismatch.rs @@ -1,3 +1,5 @@ +//@ dont-require-annotations: NOTE + struct Point { x: T, y: T, @@ -16,32 +18,32 @@ fn main() { let pt = PointF { x: 1, //~^ ERROR mismatched types - //~| expected `f32`, found integer + //~| NOTE expected `f32`, found integer y: 2, //~^ ERROR mismatched types - //~| expected `f32`, found integer + //~| NOTE expected `f32`, found integer }; let pt2 = Point:: { x: 3, //~^ ERROR mismatched types - //~| expected `f32`, found integer + //~| NOTE expected `f32`, found integer y: 4, //~^ ERROR mismatched types - //~| expected `f32`, found integer + //~| NOTE expected `f32`, found integer }; let pair = PairF { x: 5, //~^ ERROR mismatched types - //~| expected `f32`, found integer + //~| NOTE expected `f32`, found integer y: 6, }; let pair2 = PairF:: { x: 7, //~^ ERROR mismatched types - //~| expected `f32`, found integer + //~| NOTE expected `f32`, found integer y: 8, }; diff --git a/tests/ui/structs/structure-constructor-type-mismatch.stderr b/tests/ui/structs/structure-constructor-type-mismatch.stderr index 819b65ffb71..70518919daa 100644 --- a/tests/ui/structs/structure-constructor-type-mismatch.stderr +++ b/tests/ui/structs/structure-constructor-type-mismatch.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/structure-constructor-type-mismatch.rs:17:12 + --> $DIR/structure-constructor-type-mismatch.rs:19:12 | LL | x: 1, | ^ expected `f32`, found integer @@ -10,7 +10,7 @@ LL | x: 1.0, | ++ error[E0308]: mismatched types - --> $DIR/structure-constructor-type-mismatch.rs:20:12 + --> $DIR/structure-constructor-type-mismatch.rs:22:12 | LL | y: 2, | ^ expected `f32`, found integer @@ -21,7 +21,7 @@ LL | y: 2.0, | ++ error[E0308]: mismatched types - --> $DIR/structure-constructor-type-mismatch.rs:26:12 + --> $DIR/structure-constructor-type-mismatch.rs:28:12 | LL | x: 3, | ^ expected `f32`, found integer @@ -32,7 +32,7 @@ LL | x: 3.0, | ++ error[E0308]: mismatched types - --> $DIR/structure-constructor-type-mismatch.rs:29:12 + --> $DIR/structure-constructor-type-mismatch.rs:31:12 | LL | y: 4, | ^ expected `f32`, found integer @@ -43,7 +43,7 @@ LL | y: 4.0, | ++ error[E0308]: mismatched types - --> $DIR/structure-constructor-type-mismatch.rs:35:12 + --> $DIR/structure-constructor-type-mismatch.rs:37:12 | LL | x: 5, | ^ expected `f32`, found integer @@ -54,7 +54,7 @@ LL | x: 5.0, | ++ error[E0308]: mismatched types - --> $DIR/structure-constructor-type-mismatch.rs:42:12 + --> $DIR/structure-constructor-type-mismatch.rs:44:12 | LL | x: 7, | ^ expected `f32`, found integer @@ -65,7 +65,7 @@ LL | x: 7.0, | ++ error[E0107]: type alias takes 0 generic arguments but 1 generic argument was supplied - --> $DIR/structure-constructor-type-mismatch.rs:48:15 + --> $DIR/structure-constructor-type-mismatch.rs:50:15 | LL | let pt3 = PointF:: { | ^^^^^^------- help: remove the unnecessary generics @@ -73,13 +73,13 @@ LL | let pt3 = PointF:: { | expected 0 generic arguments | note: type alias defined here, with 0 generic parameters - --> $DIR/structure-constructor-type-mismatch.rs:6:6 + --> $DIR/structure-constructor-type-mismatch.rs:8:6 | LL | type PointF = Point; | ^^^^^^ error[E0308]: mismatched types - --> $DIR/structure-constructor-type-mismatch.rs:49:12 + --> $DIR/structure-constructor-type-mismatch.rs:51:12 | LL | x: 9, | ^ expected `f32`, found integer @@ -90,7 +90,7 @@ LL | x: 9.0, | ++ error[E0308]: mismatched types - --> $DIR/structure-constructor-type-mismatch.rs:50:12 + --> $DIR/structure-constructor-type-mismatch.rs:52:12 | LL | y: 10, | ^^ expected `f32`, found integer @@ -101,7 +101,7 @@ LL | y: 10.0, | ++ error[E0107]: type alias takes 0 generic arguments but 1 generic argument was supplied - --> $DIR/structure-constructor-type-mismatch.rs:54:9 + --> $DIR/structure-constructor-type-mismatch.rs:56:9 | LL | PointF:: { .. } => {} | ^^^^^^------- help: remove the unnecessary generics @@ -109,13 +109,13 @@ LL | PointF:: { .. } => {} | expected 0 generic arguments | note: type alias defined here, with 0 generic parameters - --> $DIR/structure-constructor-type-mismatch.rs:6:6 + --> $DIR/structure-constructor-type-mismatch.rs:8:6 | LL | type PointF = Point; | ^^^^^^ error[E0308]: mismatched types - --> $DIR/structure-constructor-type-mismatch.rs:54:9 + --> $DIR/structure-constructor-type-mismatch.rs:56:9 | LL | match (Point { x: 1, y: 2 }) { | ---------------------- this expression has type `Point<{integer}>` @@ -126,7 +126,7 @@ LL | PointF:: { .. } => {} found struct `Point` error[E0308]: mismatched types - --> $DIR/structure-constructor-type-mismatch.rs:59:9 + --> $DIR/structure-constructor-type-mismatch.rs:61:9 | LL | match (Point { x: 1, y: 2 }) { | ---------------------- this expression has type `Point<{integer}>` @@ -137,7 +137,7 @@ LL | PointF { .. } => {} found struct `Point` error[E0308]: mismatched types - --> $DIR/structure-constructor-type-mismatch.rs:67:9 + --> $DIR/structure-constructor-type-mismatch.rs:69:9 | LL | match (Pair { x: 1, y: 2 }) { | --------------------- this expression has type `Pair<{integer}, {integer}>` diff --git a/tests/ui/suggestions/const-pat-non-exaustive-let-new-var.rs b/tests/ui/suggestions/const-pat-non-exaustive-let-new-var.rs index 1a440a90cd7..ebe71170807 100644 --- a/tests/ui/suggestions/const-pat-non-exaustive-let-new-var.rs +++ b/tests/ui/suggestions/const-pat-non-exaustive-let-new-var.rs @@ -1,10 +1,12 @@ +//@ dont-require-annotations: NOTE + fn main() { let A = 3; //~^ ERROR refutable pattern in local binding - //~| patterns `i32::MIN..=1_i32` and `3_i32..=i32::MAX` not covered + //~| NOTE patterns `i32::MIN..=1_i32` and `3_i32..=i32::MAX` not covered //~| HELP introduce a variable instead //~| SUGGESTION A_var const A: i32 = 2; - //~^ missing patterns are not covered because `A` is interpreted as a constant pattern, not a new variable + //~^ NOTE missing patterns are not covered because `A` is interpreted as a constant pattern, not a new variable } diff --git a/tests/ui/suggestions/const-pat-non-exaustive-let-new-var.stderr b/tests/ui/suggestions/const-pat-non-exaustive-let-new-var.stderr index 0dc17f2c25c..e670bac2b33 100644 --- a/tests/ui/suggestions/const-pat-non-exaustive-let-new-var.stderr +++ b/tests/ui/suggestions/const-pat-non-exaustive-let-new-var.stderr @@ -1,5 +1,5 @@ error[E0005]: refutable pattern in local binding - --> $DIR/const-pat-non-exaustive-let-new-var.rs:2:9 + --> $DIR/const-pat-non-exaustive-let-new-var.rs:4:9 | LL | let A = 3; | ^ patterns `i32::MIN..=1_i32` and `3_i32..=i32::MAX` not covered diff --git a/tests/ui/traits/bound/same-crate-name.rs b/tests/ui/traits/bound/same-crate-name.rs index 06d79a0c8b8..395b963031a 100644 --- a/tests/ui/traits/bound/same-crate-name.rs +++ b/tests/ui/traits/bound/same-crate-name.rs @@ -1,5 +1,7 @@ //@ aux-build:crate_a1.rs //@ aux-build:crate_a2.rs +//@ dont-require-annotations: HELP +//@ dont-require-annotations: NOTE // Issue 22750 // This tests the extra help message reported when a trait bound @@ -30,8 +32,8 @@ fn main() { extern crate crate_a1 as a; a::try_foo(foo); //~^ ERROR E0277 - //~| trait impl with same name found - //~| perhaps two different versions of crate `crate_a2` + //~| HELP trait impl with same name found + //~| NOTE perhaps two different versions of crate `crate_a2` // We don't want to see the "version mismatch" help message here // because `implements_no_traits` has no impl for `Foo` @@ -50,6 +52,6 @@ fn main() { // impls for the correct trait where the path is not misleading. a::try_foo(other_variant_implements_correct_trait); //~^ ERROR E0277 - //~| the trait `main::a::Bar` is implemented for `ImplementsTraitForUsize` + //~| HELP the trait `main::a::Bar` is implemented for `ImplementsTraitForUsize` } } diff --git a/tests/ui/traits/bound/same-crate-name.stderr b/tests/ui/traits/bound/same-crate-name.stderr index f66cad77fcd..71a8159fd89 100644 --- a/tests/ui/traits/bound/same-crate-name.stderr +++ b/tests/ui/traits/bound/same-crate-name.stderr @@ -1,5 +1,5 @@ error[E0277]: the trait bound `Foo: main::a::Bar` is not satisfied - --> $DIR/same-crate-name.rs:31:20 + --> $DIR/same-crate-name.rs:33:20 | LL | a::try_foo(foo); | ---------- ^^^ the trait `main::a::Bar` is not implemented for `Foo` @@ -20,7 +20,7 @@ LL | pub fn try_foo(x: impl Bar) {} | ^^^ required by this bound in `try_foo` error[E0277]: the trait bound `DoesNotImplementTrait: main::a::Bar` is not satisfied - --> $DIR/same-crate-name.rs:38:20 + --> $DIR/same-crate-name.rs:40:20 | LL | a::try_foo(implements_no_traits); | ---------- ^^^^^^^^^^^^^^^^^^^^ the trait `main::a::Bar` is not implemented for `DoesNotImplementTrait` @@ -35,7 +35,7 @@ LL | pub fn try_foo(x: impl Bar) {} | ^^^ required by this bound in `try_foo` error[E0277]: the trait bound `ImplementsWrongTraitConditionally: main::a::Bar` is not satisfied - --> $DIR/same-crate-name.rs:45:20 + --> $DIR/same-crate-name.rs:47:20 | LL | a::try_foo(other_variant_implements_mismatched_trait); | ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `main::a::Bar` is not implemented for `ImplementsWrongTraitConditionally` @@ -56,7 +56,7 @@ LL | pub fn try_foo(x: impl Bar) {} | ^^^ required by this bound in `try_foo` error[E0277]: the trait bound `ImplementsTraitForUsize: main::a::Bar` is not satisfied - --> $DIR/same-crate-name.rs:51:20 + --> $DIR/same-crate-name.rs:53:20 | LL | a::try_foo(other_variant_implements_correct_trait); | ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `main::a::Bar` is not implemented for `ImplementsTraitForUsize` diff --git a/tests/ui/traits/impl-method-mismatch.rs b/tests/ui/traits/impl-method-mismatch.rs index 62580755c81..a7de5e38113 100644 --- a/tests/ui/traits/impl-method-mismatch.rs +++ b/tests/ui/traits/impl-method-mismatch.rs @@ -1,3 +1,5 @@ +//@ dont-require-annotations: NOTE + trait Mumbo { fn jumbo(&self, x: &usize) -> usize; } @@ -6,8 +8,8 @@ impl Mumbo for usize { // Cannot have a larger effect than the trait: unsafe fn jumbo(&self, x: &usize) { *self + *x; } //~^ ERROR method `jumbo` has an incompatible type for trait - //~| expected signature `fn - //~| found signature `unsafe fn + //~| NOTE expected signature `fn + //~| NOTE found signature `unsafe fn } fn main() {} diff --git a/tests/ui/traits/impl-method-mismatch.stderr b/tests/ui/traits/impl-method-mismatch.stderr index db457b77a23..ca8b35e06c7 100644 --- a/tests/ui/traits/impl-method-mismatch.stderr +++ b/tests/ui/traits/impl-method-mismatch.stderr @@ -1,11 +1,11 @@ error[E0053]: method `jumbo` has an incompatible type for trait - --> $DIR/impl-method-mismatch.rs:7:5 + --> $DIR/impl-method-mismatch.rs:9:5 | LL | unsafe fn jumbo(&self, x: &usize) { *self + *x; } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected safe fn, found unsafe fn | note: type in trait - --> $DIR/impl-method-mismatch.rs:2:5 + --> $DIR/impl-method-mismatch.rs:4:5 | LL | fn jumbo(&self, x: &usize) -> usize; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/tuple/tuple-arity-mismatch.rs b/tests/ui/tuple/tuple-arity-mismatch.rs index f1e525c93e1..0b7c9deec9f 100644 --- a/tests/ui/tuple/tuple-arity-mismatch.rs +++ b/tests/ui/tuple/tuple-arity-mismatch.rs @@ -1,17 +1,19 @@ // Issue #6155 +//@ dont-require-annotations: NOTE + fn first((value, _): (isize, f64)) -> isize { value } fn main() { let y = first ((1,2.0,3)); //~^ ERROR mismatched types - //~| expected tuple `(isize, f64)` - //~| found tuple `(isize, f64, {integer})` - //~| expected a tuple with 2 elements, found one with 3 elements + //~| NOTE expected tuple `(isize, f64)` + //~| NOTE found tuple `(isize, f64, {integer})` + //~| NOTE expected a tuple with 2 elements, found one with 3 elements let y = first ((1,)); //~^ ERROR mismatched types - //~| expected tuple `(isize, f64)` - //~| found tuple `(isize,)` - //~| expected a tuple with 2 elements, found one with 1 element + //~| NOTE expected tuple `(isize, f64)` + //~| NOTE found tuple `(isize,)` + //~| NOTE expected a tuple with 2 elements, found one with 1 element } diff --git a/tests/ui/tuple/tuple-arity-mismatch.stderr b/tests/ui/tuple/tuple-arity-mismatch.stderr index fff7be987f2..49dd98b6e73 100644 --- a/tests/ui/tuple/tuple-arity-mismatch.stderr +++ b/tests/ui/tuple/tuple-arity-mismatch.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/tuple-arity-mismatch.rs:6:20 + --> $DIR/tuple-arity-mismatch.rs:8:20 | LL | let y = first ((1,2.0,3)); | ----- ^^^^^^^^^ expected a tuple with 2 elements, found one with 3 elements @@ -9,13 +9,13 @@ LL | let y = first ((1,2.0,3)); = note: expected tuple `(isize, f64)` found tuple `(isize, f64, {integer})` note: function defined here - --> $DIR/tuple-arity-mismatch.rs:3:4 + --> $DIR/tuple-arity-mismatch.rs:5:4 | LL | fn first((value, _): (isize, f64)) -> isize { value } | ^^^^^ ------------------------ error[E0308]: mismatched types - --> $DIR/tuple-arity-mismatch.rs:12:20 + --> $DIR/tuple-arity-mismatch.rs:14:20 | LL | let y = first ((1,)); | ----- ^^^^ expected a tuple with 2 elements, found one with 1 element @@ -25,7 +25,7 @@ LL | let y = first ((1,)); = note: expected tuple `(isize, f64)` found tuple `(isize,)` note: function defined here - --> $DIR/tuple-arity-mismatch.rs:3:4 + --> $DIR/tuple-arity-mismatch.rs:5:4 | LL | fn first((value, _): (isize, f64)) -> isize { value } | ^^^^^ ------------------------ diff --git a/tests/ui/type/type-mismatch-multiple.rs b/tests/ui/type/type-mismatch-multiple.rs index 55d6ceef1de..faae52cad23 100644 --- a/tests/ui/type/type-mismatch-multiple.rs +++ b/tests/ui/type/type-mismatch-multiple.rs @@ -1,7 +1,9 @@ // Checking that the compiler reports multiple type errors at once +//@ dont-require-annotations: NOTE + fn main() { let a: bool = 1; let b: i32 = true; } //~^ ERROR mismatched types -//~| expected `bool`, found integer +//~| NOTE expected `bool`, found integer //~| ERROR mismatched types -//~| expected `i32`, found `bool` +//~| NOTE expected `i32`, found `bool` diff --git a/tests/ui/type/type-mismatch-multiple.stderr b/tests/ui/type/type-mismatch-multiple.stderr index 2e8654d3196..50078e5b03a 100644 --- a/tests/ui/type/type-mismatch-multiple.stderr +++ b/tests/ui/type/type-mismatch-multiple.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/type-mismatch-multiple.rs:3:27 + --> $DIR/type-mismatch-multiple.rs:5:27 | LL | fn main() { let a: bool = 1; let b: i32 = true; } | ---- ^ expected `bool`, found integer @@ -7,7 +7,7 @@ LL | fn main() { let a: bool = 1; let b: i32 = true; } | expected due to this error[E0308]: mismatched types - --> $DIR/type-mismatch-multiple.rs:3:43 + --> $DIR/type-mismatch-multiple.rs:5:43 | LL | fn main() { let a: bool = 1; let b: i32 = true; } | --- ^^^^ expected `i32`, found `bool` diff --git a/tests/ui/type/type-parameter-names.rs b/tests/ui/type/type-parameter-names.rs index b54a3fae0c1..fbd1885f543 100644 --- a/tests/ui/type/type-parameter-names.rs +++ b/tests/ui/type/type-parameter-names.rs @@ -1,12 +1,14 @@ // Test that we print out the names of type parameters correctly in // our error messages. +//@ dont-require-annotations: NOTE + fn foo(x: Foo) -> Bar { x //~^ ERROR mismatched types -//~| expected type parameter `Bar`, found type parameter `Foo` -//~| expected type parameter `Bar` -//~| found type parameter `Foo` +//~| NOTE expected type parameter `Bar`, found type parameter `Foo` +//~| NOTE expected type parameter `Bar` +//~| NOTE found type parameter `Foo` } fn main() {} diff --git a/tests/ui/type/type-parameter-names.stderr b/tests/ui/type/type-parameter-names.stderr index be9000a99e4..795a260688c 100644 --- a/tests/ui/type/type-parameter-names.stderr +++ b/tests/ui/type/type-parameter-names.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/type-parameter-names.rs:5:5 + --> $DIR/type-parameter-names.rs:7:5 | LL | fn foo(x: Foo) -> Bar { | --- --- --- expected `Bar` because of return type diff --git a/tests/ui/type/type-params-in-different-spaces-1.rs b/tests/ui/type/type-params-in-different-spaces-1.rs index 6efd14d3785..2cde1de1c0d 100644 --- a/tests/ui/type/type-params-in-different-spaces-1.rs +++ b/tests/ui/type/type-params-in-different-spaces-1.rs @@ -1,11 +1,13 @@ +//@ dont-require-annotations: NOTE + use std::ops::Add; trait BrokenAdd: Copy + Add { fn broken_add(&self, rhs: T) -> Self { *self + rhs //~ ERROR mismatched types - //~| expected type parameter `Self`, found type parameter `T` - //~| expected type parameter `Self` - //~| found type parameter `T` + //~| NOTE expected type parameter `Self`, found type parameter `T` + //~| NOTE expected type parameter `Self` + //~| NOTE found type parameter `T` } } diff --git a/tests/ui/type/type-params-in-different-spaces-1.stderr b/tests/ui/type/type-params-in-different-spaces-1.stderr index 1d0e097fdc3..e9480b0e58f 100644 --- a/tests/ui/type/type-params-in-different-spaces-1.stderr +++ b/tests/ui/type/type-params-in-different-spaces-1.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/type-params-in-different-spaces-1.rs:5:17 + --> $DIR/type-params-in-different-spaces-1.rs:7:17 | LL | trait BrokenAdd: Copy + Add { | ---------------------------------------- expected type parameter diff --git a/tests/ui/typeck/issue-16338.rs b/tests/ui/typeck/issue-16338.rs index 321b3576cd6..6c02eb93890 100644 --- a/tests/ui/typeck/issue-16338.rs +++ b/tests/ui/typeck/issue-16338.rs @@ -1,3 +1,5 @@ +//@ dont-require-annotations: NOTE + struct Slice { data: *const T, len: usize, @@ -6,5 +8,5 @@ struct Slice { fn main() { let Slice { data: data, len: len } = "foo"; //~^ ERROR mismatched types - //~| found struct `Slice<_>` + //~| NOTE found struct `Slice<_>` } diff --git a/tests/ui/typeck/issue-16338.stderr b/tests/ui/typeck/issue-16338.stderr index e24b9bfa3c0..8c5c6ad7b8c 100644 --- a/tests/ui/typeck/issue-16338.stderr +++ b/tests/ui/typeck/issue-16338.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/issue-16338.rs:7:9 + --> $DIR/issue-16338.rs:9:9 | LL | let Slice { data: data, len: len } = "foo"; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ----- this expression has type `&str` diff --git a/tests/ui/typeck/suppressed-error.rs b/tests/ui/typeck/suppressed-error.rs index 1e39be46080..b7e5b22e9db 100644 --- a/tests/ui/typeck/suppressed-error.rs +++ b/tests/ui/typeck/suppressed-error.rs @@ -1,8 +1,9 @@ fn main() { let (x, y) = (); //~^ ERROR mismatched types -//~| expected unit type `()` -//~| found tuple `(_, _)` -//~| expected `()`, found +//~| NOTE expected unit type `()` +//~| NOTE found tuple `(_, _)` +//~| NOTE expected `()`, found +//~| NOTE this expression has type `()` return x; } diff --git a/tests/ui/typeck/tag-that-dare-not-speak-its-name.rs b/tests/ui/typeck/tag-that-dare-not-speak-its-name.rs index 0e76ec246d7..79aa1f27a78 100644 --- a/tests/ui/typeck/tag-that-dare-not-speak-its-name.rs +++ b/tests/ui/typeck/tag-that-dare-not-speak-its-name.rs @@ -10,7 +10,8 @@ fn main() { let y; let x : char = last(y); //~^ ERROR mismatched types - //~| expected type `char` - //~| found enum `Option<_>` - //~| expected `char`, found `Option<_>` + //~| NOTE expected type `char` + //~| NOTE found enum `Option<_>` + //~| NOTE expected `char`, found `Option<_>` + //~| NOTE expected due to this } diff --git a/tests/ui/typeck/terr-in-field.rs b/tests/ui/typeck/terr-in-field.rs index cfe350ef86d..1b8f76f40cb 100644 --- a/tests/ui/typeck/terr-in-field.rs +++ b/tests/ui/typeck/terr-in-field.rs @@ -1,3 +1,5 @@ +//@ dont-require-annotations: NOTE + struct Foo { a: isize, b: isize, @@ -11,7 +13,7 @@ struct Bar { fn want_foo(f: Foo) {} fn have_bar(b: Bar) { want_foo(b); //~ ERROR mismatched types - //~| expected `Foo`, found `Bar` + //~| NOTE expected `Foo`, found `Bar` } fn main() {} diff --git a/tests/ui/typeck/terr-in-field.stderr b/tests/ui/typeck/terr-in-field.stderr index adc336db501..37e55af84f7 100644 --- a/tests/ui/typeck/terr-in-field.stderr +++ b/tests/ui/typeck/terr-in-field.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/terr-in-field.rs:13:14 + --> $DIR/terr-in-field.rs:15:14 | LL | want_foo(b); | -------- ^ expected `Foo`, found `Bar` @@ -7,7 +7,7 @@ LL | want_foo(b); | arguments to this function are incorrect | note: function defined here - --> $DIR/terr-in-field.rs:11:4 + --> $DIR/terr-in-field.rs:13:4 | LL | fn want_foo(f: Foo) {} | ^^^^^^^^ ------ diff --git a/tests/ui/typeck/terr-sorts.rs b/tests/ui/typeck/terr-sorts.rs index c1e2f7daee5..439d27162f8 100644 --- a/tests/ui/typeck/terr-sorts.rs +++ b/tests/ui/typeck/terr-sorts.rs @@ -1,3 +1,5 @@ +//@ dont-require-annotations: NOTE + struct Foo { a: isize, b: isize, @@ -8,8 +10,8 @@ type Bar = Box; fn want_foo(f: Foo) {} fn have_bar(b: Bar) { want_foo(b); //~ ERROR mismatched types - //~| expected struct `Foo` - //~| found struct `Box` + //~| NOTE expected struct `Foo` + //~| NOTE found struct `Box` } fn main() {} diff --git a/tests/ui/typeck/terr-sorts.stderr b/tests/ui/typeck/terr-sorts.stderr index 59d9392c236..0f649f2f035 100644 --- a/tests/ui/typeck/terr-sorts.stderr +++ b/tests/ui/typeck/terr-sorts.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/terr-sorts.rs:10:14 + --> $DIR/terr-sorts.rs:12:14 | LL | want_foo(b); | -------- ^ expected `Foo`, found `Box` @@ -9,7 +9,7 @@ LL | want_foo(b); = note: expected struct `Foo` found struct `Box` note: function defined here - --> $DIR/terr-sorts.rs:8:4 + --> $DIR/terr-sorts.rs:10:4 | LL | fn want_foo(f: Foo) {} | ^^^^^^^^ ------ diff --git a/tests/ui/typeck/typeck_type_placeholder_mismatch.rs b/tests/ui/typeck/typeck_type_placeholder_mismatch.rs index 718b6deed1b..cedda4a636e 100644 --- a/tests/ui/typeck/typeck_type_placeholder_mismatch.rs +++ b/tests/ui/typeck/typeck_type_placeholder_mismatch.rs @@ -1,6 +1,8 @@ // This test checks that genuine type errors with partial // type hints are understandable. +//@ dont-require-annotations: NOTE + use std::marker::PhantomData; struct Foo(PhantomData); @@ -12,16 +14,16 @@ pub fn main() { fn test1() { let x: Foo<_> = Bar::(PhantomData); //~^ ERROR mismatched types - //~| expected struct `Foo<_>` - //~| found struct `Bar` - //~| expected `Foo<_>`, found `Bar` + //~| NOTE expected struct `Foo<_>` + //~| NOTE found struct `Bar` + //~| NOTE expected `Foo<_>`, found `Bar` let y: Foo = x; } fn test2() { let x: Foo<_> = Bar::(PhantomData); //~^ ERROR mismatched types - //~| expected struct `Foo<_>` - //~| found struct `Bar` - //~| expected `Foo<_>`, found `Bar` + //~| NOTE expected struct `Foo<_>` + //~| NOTE found struct `Bar` + //~| NOTE expected `Foo<_>`, found `Bar` } diff --git a/tests/ui/typeck/typeck_type_placeholder_mismatch.stderr b/tests/ui/typeck/typeck_type_placeholder_mismatch.stderr index bf8e0bbb519..c6e42ececd2 100644 --- a/tests/ui/typeck/typeck_type_placeholder_mismatch.stderr +++ b/tests/ui/typeck/typeck_type_placeholder_mismatch.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/typeck_type_placeholder_mismatch.rs:13:21 + --> $DIR/typeck_type_placeholder_mismatch.rs:15:21 | LL | let x: Foo<_> = Bar::(PhantomData); | ------ ^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Foo<_>`, found `Bar` @@ -10,7 +10,7 @@ LL | let x: Foo<_> = Bar::(PhantomData); found struct `Bar` error[E0308]: mismatched types - --> $DIR/typeck_type_placeholder_mismatch.rs:22:21 + --> $DIR/typeck_type_placeholder_mismatch.rs:24:21 | LL | let x: Foo<_> = Bar::(PhantomData); | ------ ^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Foo<_>`, found `Bar` diff --git a/tests/ui/typeof/type_mismatch.rs b/tests/ui/typeof/type_mismatch.rs index 3f8339fa5be..a3444d6c207 100644 --- a/tests/ui/typeof/type_mismatch.rs +++ b/tests/ui/typeof/type_mismatch.rs @@ -1,9 +1,12 @@ // Test that using typeof results in the correct type mismatch errors instead of always assuming // `usize`, in addition to the pre-existing "typeof is reserved and unimplemented" error + +//@ dont-require-annotations: NOTE + fn main() { const a: u8 = 1; let b: typeof(a) = 1i8; //~^ ERROR `typeof` is a reserved keyword but unimplemented //~| ERROR mismatched types - //~| expected `u8`, found `i8` + //~| NOTE expected `u8`, found `i8` } diff --git a/tests/ui/typeof/type_mismatch.stderr b/tests/ui/typeof/type_mismatch.stderr index d5494922b16..6a414c11f38 100644 --- a/tests/ui/typeof/type_mismatch.stderr +++ b/tests/ui/typeof/type_mismatch.stderr @@ -1,5 +1,5 @@ error[E0516]: `typeof` is a reserved keyword but unimplemented - --> $DIR/type_mismatch.rs:5:12 + --> $DIR/type_mismatch.rs:8:12 | LL | let b: typeof(a) = 1i8; | ^^^^^^^^^ reserved keyword @@ -11,7 +11,7 @@ LL + let b: u8 = 1i8; | error[E0308]: mismatched types - --> $DIR/type_mismatch.rs:5:24 + --> $DIR/type_mismatch.rs:8:24 | LL | let b: typeof(a) = 1i8; | --------- ^^^ expected `u8`, found `i8` diff --git a/tests/ui/ufcs/ufcs-explicit-self-bad.rs b/tests/ui/ufcs/ufcs-explicit-self-bad.rs index 29586dccfc9..7039ab30428 100644 --- a/tests/ui/ufcs/ufcs-explicit-self-bad.rs +++ b/tests/ui/ufcs/ufcs-explicit-self-bad.rs @@ -1,13 +1,13 @@ +//@ dont-require-annotations: NOTE + struct Foo { f: isize, } - - impl Foo { fn foo(self: isize, x: isize) -> isize { //~^ ERROR invalid `self` parameter type - self.f + x //~ ERROR: doesn't have fields + self.f + x //~ ERROR doesn't have fields } } @@ -39,13 +39,13 @@ impl<'a, T> SomeTrait for &'a Bar { //~| ERROR has an incompatible type for trait fn dummy3(self: &&Bar) {} //~^ ERROR mismatched `self` parameter type - //~| expected reference `&'a Bar<_>` - //~| found reference `&Bar<_>` - //~| lifetime mismatch + //~| NOTE expected reference `&'a Bar<_>` + //~| NOTE found reference `&Bar<_>` + //~| NOTE lifetime mismatch //~| ERROR mismatched `self` parameter type - //~| expected reference `&'a Bar<_>` - //~| found reference `&Bar<_>` - //~| lifetime mismatch + //~| NOTE expected reference `&'a Bar<_>` + //~| NOTE found reference `&Bar<_>` + //~| NOTE lifetime mismatch } fn main() { diff --git a/tests/ui/unsafe/unsafe-trait-impl.rs b/tests/ui/unsafe/unsafe-trait-impl.rs index 9fd9ff65288..dc7e119ed7a 100644 --- a/tests/ui/unsafe/unsafe-trait-impl.rs +++ b/tests/ui/unsafe/unsafe-trait-impl.rs @@ -1,5 +1,7 @@ // Check that safe fns are not a subtype of unsafe fns. +//@ dont-require-annotations: NOTE + trait Foo { unsafe fn len(&self) -> u32; } @@ -7,8 +9,8 @@ trait Foo { impl Foo for u32 { fn len(&self) -> u32 { *self } //~^ ERROR method `len` has an incompatible type for trait - //~| expected signature `unsafe fn(&_) -> _` - //~| found signature `fn(&_) -> _` + //~| NOTE expected signature `unsafe fn(&_) -> _` + //~| NOTE found signature `fn(&_) -> _` } fn main() { } diff --git a/tests/ui/unsafe/unsafe-trait-impl.stderr b/tests/ui/unsafe/unsafe-trait-impl.stderr index b9f2e1cc869..8febbb73663 100644 --- a/tests/ui/unsafe/unsafe-trait-impl.stderr +++ b/tests/ui/unsafe/unsafe-trait-impl.stderr @@ -1,11 +1,11 @@ error[E0053]: method `len` has an incompatible type for trait - --> $DIR/unsafe-trait-impl.rs:8:5 + --> $DIR/unsafe-trait-impl.rs:10:5 | LL | fn len(&self) -> u32 { *self } | ^^^^^^^^^^^^^^^^^^^^ expected unsafe fn, found safe fn | note: type in trait - --> $DIR/unsafe-trait-impl.rs:4:5 + --> $DIR/unsafe-trait-impl.rs:6:5 | LL | unsafe fn len(&self) -> u32; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/wf/range-expr-root-of-constant-issue-40749.rs b/tests/ui/wf/range-expr-root-of-constant-issue-40749.rs index 0a847853b12..7871612dc8b 100644 --- a/tests/ui/wf/range-expr-root-of-constant-issue-40749.rs +++ b/tests/ui/wf/range-expr-root-of-constant-issue-40749.rs @@ -1,6 +1,7 @@ fn main() { [0; ..10]; //~^ ERROR mismatched types - //~| expected type `usize` - //~| found struct `RangeTo<{integer}>` + //~| NOTE expected type `usize` + //~| NOTE found struct `RangeTo<{integer}>` + //~| NOTE expected `usize`, found `RangeTo<{integer}> } -- cgit 1.4.1-3-g733a5 From 408232fb51b89cf543f1fe85c250b764656c8ca0 Mon Sep 17 00:00:00 2001 From: Laurențiu Nicola Date: Thu, 1 May 2025 10:21:46 +0300 Subject: Update lockfile --- src/tools/rust-analyzer/Cargo.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src/tools') diff --git a/src/tools/rust-analyzer/Cargo.lock b/src/tools/rust-analyzer/Cargo.lock index d257988a57a..8d6c8284e44 100644 --- a/src/tools/rust-analyzer/Cargo.lock +++ b/src/tools/rust-analyzer/Cargo.lock @@ -2039,9 +2039,9 @@ checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" [[package]] name = "salsa" -version = "0.21.0" +version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4deeb38b4c80ac90a8d4796f83da941b0d76c23783550d15d37eb43ccddcb5bc" +checksum = "6f80d5cf3c3fcab2cef898012f242a670477a1baa609267376af9cb4409026c5" dependencies = [ "boxcar", "crossbeam-queue", @@ -2062,15 +2062,15 @@ dependencies = [ [[package]] name = "salsa-macro-rules" -version = "0.21.0" +version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4e6166fa2802d86a77dbcae1bfe75f0ac46fdf952660c233ed64855a53dd603" +checksum = "05303d72606fbf2b9c9523cda2039bb8ecb00304027a3cd7e52b02a65c7d9185" [[package]] name = "salsa-macros" -version = "0.21.0" +version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf358e645a835d9901ee4d812d9812266e046ee92a28d2e37a73b7169a6503b7" +checksum = "eb2f0e2a30c65cb3cd63440c491dde68d9af7e1be2b77832ac7057141107db50" dependencies = [ "heck", "proc-macro2", -- cgit 1.4.1-3-g733a5 From b01b98f9f0b350badf8390e7950759d78484622d Mon Sep 17 00:00:00 2001 From: Laurențiu Nicola Date: Thu, 1 May 2025 10:21:52 +0300 Subject: Preparing for merge from rust-lang/rust --- src/tools/rust-analyzer/rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/tools') diff --git a/src/tools/rust-analyzer/rust-version b/src/tools/rust-analyzer/rust-version index 09c127f6bcd..90e4d65bf96 100644 --- a/src/tools/rust-analyzer/rust-version +++ b/src/tools/rust-analyzer/rust-version @@ -1 +1 @@ -21079f53a359d9fc82668d4175d49dafdb600563 +6e23095adf9209614a45f7f75fea36dad7b92afb -- cgit 1.4.1-3-g733a5