From e37b92ffd8b0fa490566416fbf6d0479734a8b83 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Sun, 7 Jul 2024 23:29:18 +1000 Subject: [PATCH 01/17] Use an iterator to find `expand_until` This makes it easier to see that the split point is always the index after the found item, or the whole list if no stopping point was found. --- .../rustc_mir_build/src/build/matches/mod.rs | 33 +++++++++++-------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs index 841ef2719c99d..7ad453be36591 100644 --- a/compiler/rustc_mir_build/src/build/matches/mod.rs +++ b/compiler/rustc_mir_build/src/build/matches/mod.rs @@ -1536,10 +1536,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { start_block: BasicBlock, candidates: &'b mut [&'c mut Candidate<'pat, 'tcx>], ) -> BlockAnd<&'b mut [&'c mut Candidate<'pat, 'tcx>]> { - // We can't expand or-patterns freely. The rule is: if the candidate has an - // or-pattern as its only remaining match pair, we can expand it freely. If it has - // other match pairs, we can expand it but we can't process more candidates after - // it. + // We can't expand or-patterns freely. The rule is: + // - If a candidate doesn't start with an or-pattern, we include it in + // the expansion list as-is (i.e. it "expands" to itself). + // - If a candidate has an or-pattern as its only remaining match pair, + // we can expand it. + // - If it starts with an or-pattern but also has other match pairs, + // we can expand it, but we can't process more candidates after it. // // If we didn't stop, the `otherwise` cases could get mixed up. E.g. in the // following, or-pattern simplification (in `merge_trivial_subcandidates`) makes it @@ -1556,17 +1559,17 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // } // ``` // - // We therefore split the `candidates` slice in two, expand or-patterns in the first half, + // We therefore split the `candidates` slice in two, expand or-patterns in the first part, // and process the rest separately. - let mut expand_until = 0; - for (i, candidate) in candidates.iter().enumerate() { - expand_until = i + 1; - if candidate.match_pairs.len() > 1 && candidate.starts_with_or_pattern() { - // The candidate has an or-pattern as well as more match pairs: we must - // split the candidates list here. - break; - } - } + let expand_until = candidates + .iter() + .position(|candidate| { + // If a candidate starts with an or-pattern and has more match pairs, + // we can expand it, but we must stop expanding _after_ it. + candidate.match_pairs.len() > 1 && candidate.starts_with_or_pattern() + }) + .map(|pos| pos + 1) // Stop _after_ the found candidate + .unwrap_or(candidates.len()); // Otherwise, include all candidates let (candidates_to_expand, remaining_candidates) = candidates.split_at_mut(expand_until); // Expand one level of or-patterns for each candidate in `candidates_to_expand`. @@ -1581,6 +1584,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { expanded_candidates.push(subcandidate); } } else { + // A candidate that doesn't start with an or-pattern has nothing to + // expand, so it is included in the post-expansion list as-is. expanded_candidates.push(candidate); } } From 00811621fec122f1355d81ab694ecfb32aec49a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=A2=81=E6=B5=A9----=E5=A4=A9=E5=91=BD=E5=89=91=E4=B8=BB?= Date: Tue, 16 Jul 2024 11:05:18 +0800 Subject: [PATCH 02/17] delete #![allow(unsafe_op_in_unsafe_fn)] this is redundant, so we can just delete it. --- library/std/src/sys/pal/teeos/mod.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/library/std/src/sys/pal/teeos/mod.rs b/library/std/src/sys/pal/teeos/mod.rs index 2a789e72722bd..4c0620f270a97 100644 --- a/library/std/src/sys/pal/teeos/mod.rs +++ b/library/std/src/sys/pal/teeos/mod.rs @@ -2,7 +2,6 @@ //! //! This module contains the facade (aka platform-specific) implementations of //! OS level functionality for Teeos. -#![allow(unsafe_op_in_unsafe_fn)] #![allow(unused_variables)] #![allow(dead_code)] From 060a40de63f68c44d38710ebc6dc185ccd156053 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=A2=81=E6=B5=A9----=E5=A4=A9=E5=91=BD=E5=89=91=E4=B8=BB?= Date: Tue, 16 Jul 2024 11:18:51 +0800 Subject: [PATCH 03/17] clean unsafe op in unsafe fn --- library/std/src/sys/pal/teeos/alloc.rs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/library/std/src/sys/pal/teeos/alloc.rs b/library/std/src/sys/pal/teeos/alloc.rs index e236819aa2388..b280d1dd76f7a 100644 --- a/library/std/src/sys/pal/teeos/alloc.rs +++ b/library/std/src/sys/pal/teeos/alloc.rs @@ -11,9 +11,9 @@ unsafe impl GlobalAlloc for System { // Also see and // . if layout.align() <= MIN_ALIGN && layout.align() <= layout.size() { - libc::malloc(layout.size()) as *mut u8 + unsafe { libc::malloc(layout.size()) as *mut u8 } } else { - aligned_malloc(&layout) + unsafe { aligned_malloc(&layout) } } } @@ -21,11 +21,11 @@ unsafe impl GlobalAlloc for System { unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 { // See the comment above in `alloc` for why this check looks the way it does. if layout.align() <= MIN_ALIGN && layout.align() <= layout.size() { - libc::calloc(layout.size(), 1) as *mut u8 + unsafe { libc::calloc(layout.size(), 1) as *mut u8 } } else { - let ptr = self.alloc(layout); + let ptr = unsafe { self.alloc(layout) }; if !ptr.is_null() { - ptr::write_bytes(ptr, 0, layout.size()); + unsafe { ptr::write_bytes(ptr, 0, layout.size()) }; } ptr } @@ -33,15 +33,15 @@ unsafe impl GlobalAlloc for System { #[inline] unsafe fn dealloc(&self, ptr: *mut u8, _layout: Layout) { - libc::free(ptr as *mut libc::c_void) + unsafe { libc::free(ptr as *mut libc::c_void) } } #[inline] unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 { if layout.align() <= MIN_ALIGN && layout.align() <= new_size { - libc::realloc(ptr as *mut libc::c_void, new_size) as *mut u8 + unsafe { libc::realloc(ptr as *mut libc::c_void, new_size) as *mut u8 } } else { - realloc_fallback(self, ptr, layout, new_size) + unsafe { realloc_fallback(self, ptr, layout, new_size) } } } } @@ -52,6 +52,6 @@ unsafe fn aligned_malloc(layout: &Layout) -> *mut u8 { // posix_memalign requires that the alignment be a multiple of `sizeof(void*)`. // Since these are all powers of 2, we can just use max. let align = layout.align().max(crate::mem::size_of::()); - let ret = libc::posix_memalign(&mut out, align, layout.size()); + let ret = unsafe { libc::posix_memalign(&mut out, align, layout.size()) }; if ret != 0 { ptr::null_mut() } else { out as *mut u8 } } From 00fff8ac648d486b777c4345ba589be1f5643c59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=A2=81=E6=B5=A9----=E5=A4=A9=E5=91=BD=E5=89=91=E4=B8=BB?= Date: Tue, 16 Jul 2024 11:34:23 +0800 Subject: [PATCH 04/17] clean unsafe op in unsafe fn --- library/std/src/sys/sync/condvar/teeos.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/library/std/src/sys/sync/condvar/teeos.rs b/library/std/src/sys/sync/condvar/teeos.rs index 0a931f407d2fa..6457da91c2a5d 100644 --- a/library/std/src/sys/sync/condvar/teeos.rs +++ b/library/std/src/sys/sync/condvar/teeos.rs @@ -76,16 +76,16 @@ impl Condvar { #[inline] pub unsafe fn wait(&self, mutex: &Mutex) { - let mutex = mutex::raw(mutex); + let mutex = unsafe { mutex::raw(mutex) }; self.verify(mutex); - let r = libc::pthread_cond_wait(raw(self), mutex); + let r = unsafe { libc::pthread_cond_wait(raw(self), mutex) }; debug_assert_eq!(r, 0); } pub unsafe fn wait_timeout(&self, mutex: &Mutex, dur: Duration) -> bool { use crate::sys::time::Timespec; - let mutex = mutex::raw(mutex); + let mutex = unsafe { mutex::raw(mutex) }; self.verify(mutex); let timeout = Timespec::now(libc::CLOCK_MONOTONIC) @@ -93,7 +93,7 @@ impl Condvar { .and_then(|t| t.to_timespec()) .unwrap_or(TIMESPEC_MAX); - let r = pthread_cond_timedwait(raw(self), mutex, &timeout); + let r = unsafe { pthread_cond_timedwait(raw(self), mutex, &timeout) }; assert!(r == libc::ETIMEDOUT || r == 0); r == 0 } From af5c90d33fc8063224cb6871619b65f0d8f71f6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=A2=81=E6=B5=A9----=E5=A4=A9=E5=91=BD=E5=89=91=E4=B8=BB?= Date: Tue, 16 Jul 2024 11:46:16 +0800 Subject: [PATCH 05/17] clean unsafe op in unsafe fn --- library/std/src/sys/pal/teeos/thread.rs | 28 +++++++++++++------------ 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/library/std/src/sys/pal/teeos/thread.rs b/library/std/src/sys/pal/teeos/thread.rs index f4723b2ea46bf..7a27d749f1c9c 100644 --- a/library/std/src/sys/pal/teeos/thread.rs +++ b/library/std/src/sys/pal/teeos/thread.rs @@ -28,22 +28,24 @@ impl Thread { // unsafe: see thread::Builder::spawn_unchecked for safety requirements pub unsafe fn new(stack: usize, p: Box) -> io::Result { let p = Box::into_raw(Box::new(p)); - let mut native: libc::pthread_t = mem::zeroed(); - let mut attr: libc::pthread_attr_t = mem::zeroed(); - assert_eq!(libc::pthread_attr_init(&mut attr), 0); + let mut native: libc::pthread_t = unsafe { mem::zeroed() }; + let mut attr: libc::pthread_attr_t = unsafe { mem::zeroed() }; + assert_eq!(unsafe { libc::pthread_attr_init(&mut attr) }, 0); assert_eq!( - libc::pthread_attr_settee( - &mut attr, - libc::TEESMP_THREAD_ATTR_CA_INHERIT, - libc::TEESMP_THREAD_ATTR_TASK_ID_INHERIT, - libc::TEESMP_THREAD_ATTR_HAS_SHADOW, - ), + unsafe { + libc::pthread_attr_settee( + &mut attr, + libc::TEESMP_THREAD_ATTR_CA_INHERIT, + libc::TEESMP_THREAD_ATTR_TASK_ID_INHERIT, + libc::TEESMP_THREAD_ATTR_HAS_SHADOW, + ) + }, 0, ); let stack_size = cmp::max(stack, min_stack_size(&attr)); - match libc::pthread_attr_setstacksize(&mut attr, stack_size) { + match unsafe { libc::pthread_attr_setstacksize(&mut attr, stack_size) } { 0 => {} n => { assert_eq!(n, libc::EINVAL); @@ -54,7 +56,7 @@ impl Thread { let page_size = os::page_size(); let stack_size = (stack_size + page_size - 1) & (-(page_size as isize - 1) as usize - 1); - assert_eq!(libc::pthread_attr_setstacksize(&mut attr, stack_size), 0); + assert_eq!(unsafe { libc::pthread_attr_setstacksize(&mut attr, stack_size) }, 0); } }; @@ -62,12 +64,12 @@ impl Thread { // Note: if the thread creation fails and this assert fails, then p will // be leaked. However, an alternative design could cause double-free // which is clearly worse. - assert_eq!(libc::pthread_attr_destroy(&mut attr), 0); + assert_eq!(unsafe { libc::pthread_attr_destroy(&mut attr) }, 0); return if ret != 0 { // The thread failed to start and as a result p was not consumed. Therefore, it is // safe to reconstruct the box so that it gets deallocated. - drop(Box::from_raw(p)); + drop(unsafe { Box::from_raw(p) }); Err(io::Error::from_raw_os_error(ret)) } else { // The new thread will start running earliest after the next yield. From 9183af25e5ab0c9a39a5a45270e1439ebd22eb24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=A2=81=E6=B5=A9----=E5=A4=A9=E5=91=BD=E5=89=91=E4=B8=BB?= Date: Tue, 16 Jul 2024 11:47:22 +0800 Subject: [PATCH 06/17] deny unsafe_op_in_unsafe_fn for teeos --- library/std/src/sys/pal/teeos/mod.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/library/std/src/sys/pal/teeos/mod.rs b/library/std/src/sys/pal/teeos/mod.rs index 4c0620f270a97..adefd1bb42c8d 100644 --- a/library/std/src/sys/pal/teeos/mod.rs +++ b/library/std/src/sys/pal/teeos/mod.rs @@ -2,6 +2,7 @@ //! //! This module contains the facade (aka platform-specific) implementations of //! OS level functionality for Teeos. +#![deny(unsafe_op_in_unsafe_fn)] #![allow(unused_variables)] #![allow(dead_code)] From 71eb49c318c3e7c25a6306414298d78accd164df Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 14 Jul 2024 13:25:06 -0400 Subject: [PATCH 07/17] fmt --- .../rustc_span/src/analyze_source_file.rs | 91 ++++++++++--------- 1 file changed, 49 insertions(+), 42 deletions(-) diff --git a/compiler/rustc_span/src/analyze_source_file.rs b/compiler/rustc_span/src/analyze_source_file.rs index 7da7dc610ecf1..80c5c3bf1b5a7 100644 --- a/compiler/rustc_span/src/analyze_source_file.rs +++ b/compiler/rustc_span/src/analyze_source_file.rs @@ -35,25 +35,25 @@ pub fn analyze_source_file( cfg_match! { cfg(any(target_arch = "x86", target_arch = "x86_64")) => { - fn analyze_source_file_dispatch(src: &str, - lines: &mut Vec, - multi_byte_chars: &mut Vec, - non_narrow_chars: &mut Vec) { + fn analyze_source_file_dispatch( + src: &str, + lines: &mut Vec, + multi_byte_chars: &mut Vec, + non_narrow_chars: &mut Vec, + ) { if is_x86_feature_detected!("sse2") { unsafe { - analyze_source_file_sse2(src, - lines, - multi_byte_chars, - non_narrow_chars); + analyze_source_file_sse2(src, lines, multi_byte_chars, non_narrow_chars); } } else { - analyze_source_file_generic(src, - src.len(), - RelativeBytePos::from_u32(0), - lines, - multi_byte_chars, - non_narrow_chars); - + analyze_source_file_generic( + src, + src.len(), + RelativeBytePos::from_u32(0), + lines, + multi_byte_chars, + non_narrow_chars, + ); } } @@ -62,10 +62,12 @@ cfg_match! { /// function falls back to the generic implementation. Otherwise it uses /// SSE2 intrinsics to quickly find all newlines. #[target_feature(enable = "sse2")] - unsafe fn analyze_source_file_sse2(src: &str, - lines: &mut Vec, - multi_byte_chars: &mut Vec, - non_narrow_chars: &mut Vec) { + unsafe fn analyze_source_file_sse2( + src: &str, + lines: &mut Vec, + multi_byte_chars: &mut Vec, + non_narrow_chars: &mut Vec, + ) { #[cfg(target_arch = "x86")] use std::arch::x86::*; #[cfg(target_arch = "x86_64")] @@ -83,7 +85,7 @@ cfg_match! { // handled it. let mut intra_chunk_offset = 0; - for chunk_index in 0 .. chunk_count { + for chunk_index in 0..chunk_count { let ptr = src_bytes.as_ptr() as *const __m128i; // We don't know if the pointer is aligned to 16 bytes, so we // use `loadu`, which supports unaligned loading. @@ -126,7 +128,7 @@ cfg_match! { if index >= CHUNK_SIZE as u32 { // We have arrived at the end of the chunk. - break + break; } lines.push(RelativeBytePos(index) + output_offset); @@ -137,14 +139,14 @@ cfg_match! { // We are done for this chunk. All control characters were // newlines and we took care of those. - continue + continue; } else { // Some of the control characters are not newlines, // fall through to the slow path below. } } else { // No control characters, nothing to record for this chunk - continue + continue; } } @@ -152,43 +154,48 @@ cfg_match! { // There are control chars in here, fallback to generic decoding. let scan_start = chunk_index * CHUNK_SIZE + intra_chunk_offset; intra_chunk_offset = analyze_source_file_generic( - &src[scan_start .. ], + &src[scan_start..], CHUNK_SIZE - intra_chunk_offset, RelativeBytePos::from_usize(scan_start), lines, multi_byte_chars, - non_narrow_chars + non_narrow_chars, ); } // There might still be a tail left to analyze let tail_start = chunk_count * CHUNK_SIZE + intra_chunk_offset; if tail_start < src.len() { - analyze_source_file_generic(&src[tail_start ..], - src.len() - tail_start, - RelativeBytePos::from_usize(tail_start), - lines, - multi_byte_chars, - non_narrow_chars); + analyze_source_file_generic( + &src[tail_start..], + src.len() - tail_start, + RelativeBytePos::from_usize(tail_start), + lines, + multi_byte_chars, + non_narrow_chars, + ); } } } _ => { // The target (or compiler version) does not support SSE2 ... - fn analyze_source_file_dispatch(src: &str, - lines: &mut Vec, - multi_byte_chars: &mut Vec, - non_narrow_chars: &mut Vec) { - analyze_source_file_generic(src, - src.len(), - RelativeBytePos::from_u32(0), - lines, - multi_byte_chars, - non_narrow_chars); + fn analyze_source_file_dispatch( + src: &str, + lines: &mut Vec, + multi_byte_chars: &mut Vec, + non_narrow_chars: &mut Vec, + ) { + analyze_source_file_generic( + src, + src.len(), + RelativeBytePos::from_u32(0), + lines, + multi_byte_chars, + non_narrow_chars, + ); } } } - // `scan_len` determines the number of bytes in `src` to scan. Note that the // function can read past `scan_len` if a multi-byte character start within the // range but extends past it. The overflow is returned by the function. From 28503d69ac204ff208d115aea30dc09d6fca8728 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 14 Jul 2024 14:27:57 -0400 Subject: [PATCH 08/17] Fix unsafe_op_in_unsafe_fn in compiler --- compiler/rustc_abi/src/lib.rs | 4 +- compiler/rustc_codegen_llvm/src/allocator.rs | 50 ++-- compiler/rustc_codegen_llvm/src/back/lto.rs | 16 +- .../rustc_codegen_llvm/src/back/profiling.rs | 12 +- compiler/rustc_codegen_llvm/src/back/write.rs | 224 ++++++++------- compiler/rustc_codegen_llvm/src/context.rs | 259 ++++++++++-------- compiler/rustc_codegen_llvm/src/lib.rs | 6 +- .../rustc_codegen_llvm/src/llvm/diagnostic.rs | 71 ++--- compiler/rustc_codegen_llvm/src/llvm_util.rs | 16 +- compiler/rustc_codegen_llvm/src/mono_item.rs | 8 +- compiler/rustc_codegen_ssa/src/back/lto.rs | 2 +- compiler/rustc_llvm/src/lib.rs | 2 +- compiler/rustc_middle/src/ty/context/tls.rs | 2 +- .../rustc_span/src/analyze_source_file.rs | 18 +- src/bootstrap/src/core/builder.rs | 1 + 15 files changed, 383 insertions(+), 308 deletions(-) diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs index 78332d66f0366..52ec41f643c0d 100644 --- a/compiler/rustc_abi/src/lib.rs +++ b/compiler/rustc_abi/src/lib.rs @@ -627,7 +627,7 @@ impl Step for Size { #[inline] unsafe fn forward_unchecked(start: Self, count: usize) -> Self { - Self::from_bytes(u64::forward_unchecked(start.bytes(), count)) + Self::from_bytes(unsafe { u64::forward_unchecked(start.bytes(), count) }) } #[inline] @@ -642,7 +642,7 @@ impl Step for Size { #[inline] unsafe fn backward_unchecked(start: Self, count: usize) -> Self { - Self::from_bytes(u64::backward_unchecked(start.bytes(), count)) + Self::from_bytes(unsafe { u64::backward_unchecked(start.bytes(), count) }) } } diff --git a/compiler/rustc_codegen_llvm/src/allocator.rs b/compiler/rustc_codegen_llvm/src/allocator.rs index ca37602973540..5969d9b914403 100644 --- a/compiler/rustc_codegen_llvm/src/allocator.rs +++ b/compiler/rustc_codegen_llvm/src/allocator.rs @@ -21,14 +21,16 @@ pub(crate) unsafe fn codegen( ) { let llcx = &*module_llvm.llcx; let llmod = module_llvm.llmod(); - let usize = match tcx.sess.target.pointer_width { - 16 => llvm::LLVMInt16TypeInContext(llcx), - 32 => llvm::LLVMInt32TypeInContext(llcx), - 64 => llvm::LLVMInt64TypeInContext(llcx), - tws => bug!("Unsupported target word size for int: {}", tws), + let usize = unsafe { + match tcx.sess.target.pointer_width { + 16 => llvm::LLVMInt16TypeInContext(llcx), + 32 => llvm::LLVMInt32TypeInContext(llcx), + 64 => llvm::LLVMInt64TypeInContext(llcx), + tws => bug!("Unsupported target word size for int: {}", tws), + } }; - let i8 = llvm::LLVMInt8TypeInContext(llcx); - let i8p = llvm::LLVMPointerTypeInContext(llcx, 0); + let i8 = unsafe { llvm::LLVMInt8TypeInContext(llcx) }; + let i8p = unsafe { llvm::LLVMPointerTypeInContext(llcx, 0) }; if kind == AllocatorKind::Default { for method in ALLOCATOR_METHODS { @@ -73,23 +75,25 @@ pub(crate) unsafe fn codegen( true, ); - // __rust_alloc_error_handler_should_panic - let name = OomStrategy::SYMBOL; - let ll_g = llvm::LLVMRustGetOrInsertGlobal(llmod, name.as_ptr().cast(), name.len(), i8); - if tcx.sess.default_hidden_visibility() { - llvm::LLVMRustSetVisibility(ll_g, llvm::Visibility::Hidden); - } - let val = tcx.sess.opts.unstable_opts.oom.should_panic(); - let llval = llvm::LLVMConstInt(i8, val as u64, False); - llvm::LLVMSetInitializer(ll_g, llval); - - let name = NO_ALLOC_SHIM_IS_UNSTABLE; - let ll_g = llvm::LLVMRustGetOrInsertGlobal(llmod, name.as_ptr().cast(), name.len(), i8); - if tcx.sess.default_hidden_visibility() { - llvm::LLVMRustSetVisibility(ll_g, llvm::Visibility::Hidden); + unsafe { + // __rust_alloc_error_handler_should_panic + let name = OomStrategy::SYMBOL; + let ll_g = llvm::LLVMRustGetOrInsertGlobal(llmod, name.as_ptr().cast(), name.len(), i8); + if tcx.sess.default_hidden_visibility() { + llvm::LLVMRustSetVisibility(ll_g, llvm::Visibility::Hidden); + } + let val = tcx.sess.opts.unstable_opts.oom.should_panic(); + let llval = llvm::LLVMConstInt(i8, val as u64, False); + llvm::LLVMSetInitializer(ll_g, llval); + + let name = NO_ALLOC_SHIM_IS_UNSTABLE; + let ll_g = llvm::LLVMRustGetOrInsertGlobal(llmod, name.as_ptr().cast(), name.len(), i8); + if tcx.sess.default_hidden_visibility() { + llvm::LLVMRustSetVisibility(ll_g, llvm::Visibility::Hidden); + } + let llval = llvm::LLVMConstInt(i8, 0, False); + llvm::LLVMSetInitializer(ll_g, llval); } - let llval = llvm::LLVMConstInt(i8, 0, False); - llvm::LLVMSetInitializer(ll_g, llval); if tcx.sess.opts.debuginfo != DebugInfo::None { let dbg_cx = debuginfo::CodegenUnitDebugContext::new(llmod); diff --git a/compiler/rustc_codegen_llvm/src/back/lto.rs b/compiler/rustc_codegen_llvm/src/back/lto.rs index aff3e3d707608..aef672631c813 100644 --- a/compiler/rustc_codegen_llvm/src/back/lto.rs +++ b/compiler/rustc_codegen_llvm/src/back/lto.rs @@ -727,7 +727,7 @@ pub unsafe fn optimize_thin_module( // into that context. One day, however, we may do this for upstream // crates but for locally codegened modules we may be able to reuse // that LLVM Context and Module. - let llcx = llvm::LLVMRustContextCreate(cgcx.fewer_names); + let llcx = unsafe { llvm::LLVMRustContextCreate(cgcx.fewer_names) }; let llmod_raw = parse_module(llcx, module_name, thin_module.data(), dcx)? as *const _; let mut module = ModuleCodegen { module_llvm: ModuleLlvm { llmod_raw, llcx, tm: ManuallyDrop::new(tm) }, @@ -750,7 +750,9 @@ pub unsafe fn optimize_thin_module( { let _timer = cgcx.prof.generic_activity_with_arg("LLVM_thin_lto_rename", thin_module.name()); - if !llvm::LLVMRustPrepareThinLTORename(thin_module.shared.data.0, llmod, target) { + if unsafe { + !llvm::LLVMRustPrepareThinLTORename(thin_module.shared.data.0, llmod, target) + } { return Err(write::llvm_err(dcx, LlvmError::PrepareThinLtoModule)); } save_temp_bitcode(cgcx, &module, "thin-lto-after-rename"); @@ -760,7 +762,8 @@ pub unsafe fn optimize_thin_module( let _timer = cgcx .prof .generic_activity_with_arg("LLVM_thin_lto_resolve_weak", thin_module.name()); - if !llvm::LLVMRustPrepareThinLTOResolveWeak(thin_module.shared.data.0, llmod) { + if unsafe { !llvm::LLVMRustPrepareThinLTOResolveWeak(thin_module.shared.data.0, llmod) } + { return Err(write::llvm_err(dcx, LlvmError::PrepareThinLtoModule)); } save_temp_bitcode(cgcx, &module, "thin-lto-after-resolve"); @@ -770,7 +773,8 @@ pub unsafe fn optimize_thin_module( let _timer = cgcx .prof .generic_activity_with_arg("LLVM_thin_lto_internalize", thin_module.name()); - if !llvm::LLVMRustPrepareThinLTOInternalize(thin_module.shared.data.0, llmod) { + if unsafe { !llvm::LLVMRustPrepareThinLTOInternalize(thin_module.shared.data.0, llmod) } + { return Err(write::llvm_err(dcx, LlvmError::PrepareThinLtoModule)); } save_temp_bitcode(cgcx, &module, "thin-lto-after-internalize"); @@ -779,7 +783,9 @@ pub unsafe fn optimize_thin_module( { let _timer = cgcx.prof.generic_activity_with_arg("LLVM_thin_lto_import", thin_module.name()); - if !llvm::LLVMRustPrepareThinLTOImport(thin_module.shared.data.0, llmod, target) { + if unsafe { + !llvm::LLVMRustPrepareThinLTOImport(thin_module.shared.data.0, llmod, target) + } { return Err(write::llvm_err(dcx, LlvmError::PrepareThinLtoModule)); } save_temp_bitcode(cgcx, &module, "thin-lto-after-import"); diff --git a/compiler/rustc_codegen_llvm/src/back/profiling.rs b/compiler/rustc_codegen_llvm/src/back/profiling.rs index 2741f7d848e79..2eee9f8c5a3ec 100644 --- a/compiler/rustc_codegen_llvm/src/back/profiling.rs +++ b/compiler/rustc_codegen_llvm/src/back/profiling.rs @@ -46,13 +46,15 @@ pub unsafe extern "C" fn selfprofile_before_pass_callback( pass_name: *const c_char, ir_name: *const c_char, ) { - let llvm_self_profiler = &mut *(llvm_self_profiler as *mut LlvmSelfProfiler<'_>); - let pass_name = CStr::from_ptr(pass_name).to_str().expect("valid UTF-8"); - let ir_name = CStr::from_ptr(ir_name).to_str().expect("valid UTF-8"); - llvm_self_profiler.before_pass_callback(pass_name, ir_name); + unsafe { + let llvm_self_profiler = &mut *(llvm_self_profiler as *mut LlvmSelfProfiler<'_>); + let pass_name = CStr::from_ptr(pass_name).to_str().expect("valid UTF-8"); + let ir_name = CStr::from_ptr(ir_name).to_str().expect("valid UTF-8"); + llvm_self_profiler.before_pass_callback(pass_name, ir_name); + } } pub unsafe extern "C" fn selfprofile_after_pass_callback(llvm_self_profiler: *mut c_void) { - let llvm_self_profiler = &mut *(llvm_self_profiler as *mut LlvmSelfProfiler<'_>); + let llvm_self_profiler = unsafe { &mut *(llvm_self_profiler as *mut LlvmSelfProfiler<'_>) }; llvm_self_profiler.after_pass_callback(); } diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs index 2fda19bf0c914..ddd52e80edff1 100644 --- a/compiler/rustc_codegen_llvm/src/back/write.rs +++ b/compiler/rustc_codegen_llvm/src/back/write.rs @@ -428,9 +428,10 @@ unsafe extern "C" fn diagnostic_handler(info: &DiagnosticInfo, user: *mut c_void if user.is_null() { return; } - let (cgcx, dcx) = *(user as *const (&CodegenContext, DiagCtxtHandle<'_>)); + let (cgcx, dcx) = + unsafe { *(user as *const (&CodegenContext, DiagCtxtHandle<'_>)) }; - match llvm::diagnostic::Diagnostic::unpack(info) { + match unsafe { llvm::diagnostic::Diagnostic::unpack(info) } { llvm::diagnostic::InlineAsm(inline) => { report_inline_asm(cgcx, inline.message, inline.level, inline.cookie, inline.source); } @@ -454,14 +455,14 @@ unsafe extern "C" fn diagnostic_handler(info: &DiagnosticInfo, user: *mut c_void }); } llvm::diagnostic::PGO(diagnostic_ref) | llvm::diagnostic::Linker(diagnostic_ref) => { - let message = llvm::build_string(|s| { + let message = llvm::build_string(|s| unsafe { llvm::LLVMRustWriteDiagnosticInfoToString(diagnostic_ref, s) }) .expect("non-UTF8 diagnostic"); dcx.emit_warn(FromLlvmDiag { message }); } llvm::diagnostic::Unsupported(diagnostic_ref) => { - let message = llvm::build_string(|s| { + let message = llvm::build_string(|s| unsafe { llvm::LLVMRustWriteDiagnosticInfoToString(diagnostic_ref, s) }) .expect("non-UTF8 diagnostic"); @@ -564,37 +565,39 @@ pub(crate) unsafe fn llvm_optimize( let llvm_plugins = config.llvm_plugins.join(","); - let result = llvm::LLVMRustOptimize( - module.module_llvm.llmod(), - &*module.module_llvm.tm, - to_pass_builder_opt_level(opt_level), - opt_stage, - cgcx.opts.cg.linker_plugin_lto.enabled(), - config.no_prepopulate_passes, - config.verify_llvm_ir, - using_thin_buffers, - config.merge_functions, - unroll_loops, - config.vectorize_slp, - config.vectorize_loop, - config.no_builtins, - config.emit_lifetime_markers, - sanitizer_options.as_ref(), - pgo_gen_path.as_ref().map_or(std::ptr::null(), |s| s.as_ptr()), - pgo_use_path.as_ref().map_or(std::ptr::null(), |s| s.as_ptr()), - config.instrument_coverage, - instr_profile_output_path.as_ref().map_or(std::ptr::null(), |s| s.as_ptr()), - config.instrument_gcov, - pgo_sample_use_path.as_ref().map_or(std::ptr::null(), |s| s.as_ptr()), - config.debug_info_for_profiling, - llvm_selfprofiler, - selfprofile_before_pass_callback, - selfprofile_after_pass_callback, - extra_passes.as_ptr().cast(), - extra_passes.len(), - llvm_plugins.as_ptr().cast(), - llvm_plugins.len(), - ); + let result = unsafe { + llvm::LLVMRustOptimize( + module.module_llvm.llmod(), + &*module.module_llvm.tm, + to_pass_builder_opt_level(opt_level), + opt_stage, + cgcx.opts.cg.linker_plugin_lto.enabled(), + config.no_prepopulate_passes, + config.verify_llvm_ir, + using_thin_buffers, + config.merge_functions, + unroll_loops, + config.vectorize_slp, + config.vectorize_loop, + config.no_builtins, + config.emit_lifetime_markers, + sanitizer_options.as_ref(), + pgo_gen_path.as_ref().map_or(std::ptr::null(), |s| s.as_ptr()), + pgo_use_path.as_ref().map_or(std::ptr::null(), |s| s.as_ptr()), + config.instrument_coverage, + instr_profile_output_path.as_ref().map_or(std::ptr::null(), |s| s.as_ptr()), + config.instrument_gcov, + pgo_sample_use_path.as_ref().map_or(std::ptr::null(), |s| s.as_ptr()), + config.debug_info_for_profiling, + llvm_selfprofiler, + selfprofile_before_pass_callback, + selfprofile_after_pass_callback, + extra_passes.as_ptr().cast(), + extra_passes.len(), + llvm_plugins.as_ptr().cast(), + llvm_plugins.len(), + ) + }; result.into_result().map_err(|()| llvm_err(dcx, LlvmError::RunLlvmPasses)) } @@ -617,7 +620,7 @@ pub(crate) unsafe fn optimize( if config.emit_no_opt_bc { let out = cgcx.output_filenames.temp_path_ext("no-opt.bc", module_name); let out = path_to_c_string(&out); - llvm::LLVMWriteBitcodeToFile(llmod, out.as_ptr()); + unsafe { llvm::LLVMWriteBitcodeToFile(llmod, out.as_ptr()) }; } if let Some(opt_level) = config.opt_level { @@ -627,7 +630,7 @@ pub(crate) unsafe fn optimize( _ if cgcx.opts.cg.linker_plugin_lto.enabled() => llvm::OptStage::PreLinkThinLTO, _ => llvm::OptStage::PreLinkNoLTO, }; - return llvm_optimize(cgcx, dcx, module, config, opt_level, opt_stage); + return unsafe { llvm_optimize(cgcx, dcx, module, config, opt_level, opt_stage) }; } Ok(()) } @@ -692,10 +695,12 @@ pub(crate) unsafe fn codegen( where F: FnOnce(&'ll mut PassManager<'ll>) -> R, { - let cpm = llvm::LLVMCreatePassManager(); - llvm::LLVMAddAnalysisPasses(tm, cpm); - llvm::LLVMRustAddLibraryInfo(cpm, llmod, no_builtins); - f(cpm) + unsafe { + let cpm = llvm::LLVMCreatePassManager(); + llvm::LLVMAddAnalysisPasses(tm, cpm); + llvm::LLVMRustAddLibraryInfo(cpm, llmod, no_builtins); + f(cpm) + } } // Two things to note: @@ -757,7 +762,9 @@ pub(crate) unsafe fn codegen( let _timer = cgcx .prof .generic_activity_with_arg("LLVM_module_codegen_embed_bitcode", &*module.name); - embed_bitcode(cgcx, llcx, llmod, &config.bc_cmdline, data); + unsafe { + embed_bitcode(cgcx, llcx, llmod, &config.bc_cmdline, data); + } } } @@ -793,7 +800,8 @@ pub(crate) unsafe fn codegen( cursor.position() as size_t } - let result = llvm::LLVMRustPrintModule(llmod, out_c.as_ptr(), demangle_callback); + let result = + unsafe { llvm::LLVMRustPrintModule(llmod, out_c.as_ptr(), demangle_callback) }; if result == llvm::LLVMRustResult::Success { record_artifact_size(&cgcx.prof, "llvm_ir", &out); @@ -812,22 +820,24 @@ pub(crate) unsafe fn codegen( // binaries. So we must clone the module to produce the asm output // if we are also producing object code. let llmod = if let EmitObj::ObjectCode(_) = config.emit_obj { - llvm::LLVMCloneModule(llmod) + unsafe { llvm::LLVMCloneModule(llmod) } } else { llmod }; - with_codegen(tm, llmod, config.no_builtins, |cpm| { - write_output_file( - dcx, - tm, - cpm, - llmod, - &path, - None, - llvm::FileType::AssemblyFile, - &cgcx.prof, - ) - })?; + unsafe { + with_codegen(tm, llmod, config.no_builtins, |cpm| { + write_output_file( + dcx, + tm, + cpm, + llmod, + &path, + None, + llvm::FileType::AssemblyFile, + &cgcx.prof, + ) + })?; + } } match config.emit_obj { @@ -851,18 +861,20 @@ pub(crate) unsafe fn codegen( (_, SplitDwarfKind::Split) => Some(dwo_out.as_path()), }; - with_codegen(tm, llmod, config.no_builtins, |cpm| { - write_output_file( - dcx, - tm, - cpm, - llmod, - &obj_out, - dwo_out, - llvm::FileType::ObjectFile, - &cgcx.prof, - ) - })?; + unsafe { + with_codegen(tm, llmod, config.no_builtins, |cpm| { + write_output_file( + dcx, + tm, + cpm, + llmod, + &obj_out, + dwo_out, + llvm::FileType::ObjectFile, + &cgcx.prof, + ) + })?; + } } EmitObj::Bitcode => { @@ -1013,44 +1025,46 @@ unsafe fn embed_bitcode( // reason (see issue #90326 for historical background). let is_aix = target_is_aix(cgcx); let is_apple = target_is_apple(cgcx); - if is_apple || is_aix || cgcx.opts.target_triple.triple().starts_with("wasm") { - // We don't need custom section flags, create LLVM globals. - let llconst = common::bytes_in_context(llcx, bitcode); - let llglobal = llvm::LLVMAddGlobal( - llmod, - common::val_ty(llconst), - c"rustc.embedded.module".as_ptr().cast(), - ); - llvm::LLVMSetInitializer(llglobal, llconst); - - let section = bitcode_section_name(cgcx); - llvm::LLVMSetSection(llglobal, section.as_ptr().cast()); - llvm::LLVMRustSetLinkage(llglobal, llvm::Linkage::PrivateLinkage); - llvm::LLVMSetGlobalConstant(llglobal, llvm::True); - - let llconst = common::bytes_in_context(llcx, cmdline.as_bytes()); - let llglobal = llvm::LLVMAddGlobal( - llmod, - common::val_ty(llconst), - c"rustc.embedded.cmdline".as_ptr().cast(), - ); - llvm::LLVMSetInitializer(llglobal, llconst); - let section = if is_apple { - c"__LLVM,__cmdline" - } else if is_aix { - c".info" + unsafe { + if is_apple || is_aix || cgcx.opts.target_triple.triple().starts_with("wasm") { + // We don't need custom section flags, create LLVM globals. + let llconst = common::bytes_in_context(llcx, bitcode); + let llglobal = llvm::LLVMAddGlobal( + llmod, + common::val_ty(llconst), + c"rustc.embedded.module".as_ptr().cast(), + ); + llvm::LLVMSetInitializer(llglobal, llconst); + + let section = bitcode_section_name(cgcx); + llvm::LLVMSetSection(llglobal, section.as_ptr().cast()); + llvm::LLVMRustSetLinkage(llglobal, llvm::Linkage::PrivateLinkage); + llvm::LLVMSetGlobalConstant(llglobal, llvm::True); + + let llconst = common::bytes_in_context(llcx, cmdline.as_bytes()); + let llglobal = llvm::LLVMAddGlobal( + llmod, + common::val_ty(llconst), + c"rustc.embedded.cmdline".as_ptr().cast(), + ); + llvm::LLVMSetInitializer(llglobal, llconst); + let section = if is_apple { + c"__LLVM,__cmdline" + } else if is_aix { + c".info" + } else { + c".llvmcmd" + }; + llvm::LLVMSetSection(llglobal, section.as_ptr().cast()); + llvm::LLVMRustSetLinkage(llglobal, llvm::Linkage::PrivateLinkage); } else { - c".llvmcmd" - }; - llvm::LLVMSetSection(llglobal, section.as_ptr().cast()); - llvm::LLVMRustSetLinkage(llglobal, llvm::Linkage::PrivateLinkage); - } else { - // We need custom section flags, so emit module-level inline assembly. - let section_flags = if cgcx.is_pe_coff { "n" } else { "e" }; - let asm = create_section_with_flags_asm(".llvmbc", section_flags, bitcode); - llvm::LLVMAppendModuleInlineAsm(llmod, asm.as_ptr().cast(), asm.len()); - let asm = create_section_with_flags_asm(".llvmcmd", section_flags, cmdline.as_bytes()); - llvm::LLVMAppendModuleInlineAsm(llmod, asm.as_ptr().cast(), asm.len()); + // We need custom section flags, so emit module-level inline assembly. + let section_flags = if cgcx.is_pe_coff { "n" } else { "e" }; + let asm = create_section_with_flags_asm(".llvmbc", section_flags, bitcode); + llvm::LLVMAppendModuleInlineAsm(llmod, asm.as_ptr().cast(), asm.len()); + let asm = create_section_with_flags_asm(".llvmcmd", section_flags, cmdline.as_bytes()); + llvm::LLVMAppendModuleInlineAsm(llmod, asm.as_ptr().cast(), asm.len()); + } } } diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs index 77beb9a6bb386..49677dcf12f73 100644 --- a/compiler/rustc_codegen_llvm/src/context.rs +++ b/compiler/rustc_codegen_llvm/src/context.rs @@ -120,7 +120,7 @@ pub unsafe fn create_module<'ll>( ) -> &'ll llvm::Module { let sess = tcx.sess; let mod_name = SmallCStr::new(mod_name); - let llmod = llvm::LLVMModuleCreateWithNameInContext(mod_name.as_ptr(), llcx); + let llmod = unsafe { llvm::LLVMModuleCreateWithNameInContext(mod_name.as_ptr(), llcx) }; let mut target_data_layout = sess.target.data_layout.to_string(); let llvm_version = llvm_util::get_version(); @@ -153,11 +153,14 @@ pub unsafe fn create_module<'ll>( // Ensure the data-layout values hardcoded remain the defaults. { let tm = crate::back::write::create_informational_target_machine(tcx.sess); - llvm::LLVMRustSetDataLayoutFromTargetMachine(llmod, &tm); + unsafe { + llvm::LLVMRustSetDataLayoutFromTargetMachine(llmod, &tm); + } - let llvm_data_layout = llvm::LLVMGetDataLayoutStr(llmod); - let llvm_data_layout = str::from_utf8(CStr::from_ptr(llvm_data_layout).to_bytes()) - .expect("got a non-UTF8 data-layout from LLVM"); + let llvm_data_layout = unsafe { llvm::LLVMGetDataLayoutStr(llmod) }; + let llvm_data_layout = + str::from_utf8(unsafe { CStr::from_ptr(llvm_data_layout) }.to_bytes()) + .expect("got a non-UTF8 data-layout from LLVM"); if target_data_layout != llvm_data_layout { tcx.dcx().emit_err(crate::errors::MismatchedDataLayout { @@ -170,20 +173,28 @@ pub unsafe fn create_module<'ll>( } let data_layout = SmallCStr::new(&target_data_layout); - llvm::LLVMSetDataLayout(llmod, data_layout.as_ptr()); + unsafe { + llvm::LLVMSetDataLayout(llmod, data_layout.as_ptr()); + } let llvm_target = SmallCStr::new(&sess.target.llvm_target); - llvm::LLVMRustSetNormalizedTarget(llmod, llvm_target.as_ptr()); + unsafe { + llvm::LLVMRustSetNormalizedTarget(llmod, llvm_target.as_ptr()); + } let reloc_model = sess.relocation_model(); if matches!(reloc_model, RelocModel::Pic | RelocModel::Pie) { - llvm::LLVMRustSetModulePICLevel(llmod); + unsafe { + llvm::LLVMRustSetModulePICLevel(llmod); + } // PIE is potentially more effective than PIC, but can only be used in executables. // If all our outputs are executables, then we can relax PIC to PIE. if reloc_model == RelocModel::Pie || tcx.crate_types().iter().all(|ty| *ty == CrateType::Executable) { - llvm::LLVMRustSetModulePIELevel(llmod); + unsafe { + llvm::LLVMRustSetModulePIELevel(llmod); + } } } @@ -192,95 +203,109 @@ pub unsafe fn create_module<'ll>( // longer jumps) if a larger code model is used with a smaller one. // // See https://reviews.llvm.org/D52322 and https://reviews.llvm.org/D52323. - llvm::LLVMRustSetModuleCodeModel(llmod, to_llvm_code_model(sess.code_model())); + unsafe { + llvm::LLVMRustSetModuleCodeModel(llmod, to_llvm_code_model(sess.code_model())); + } // If skipping the PLT is enabled, we need to add some module metadata // to ensure intrinsic calls don't use it. if !sess.needs_plt() { let avoid_plt = c"RtLibUseGOT".as_ptr().cast(); - llvm::LLVMRustAddModuleFlagU32(llmod, llvm::LLVMModFlagBehavior::Warning, avoid_plt, 1); + unsafe { + llvm::LLVMRustAddModuleFlagU32(llmod, llvm::LLVMModFlagBehavior::Warning, avoid_plt, 1); + } } // Enable canonical jump tables if CFI is enabled. (See https://reviews.llvm.org/D65629.) if sess.is_sanitizer_cfi_canonical_jump_tables_enabled() && sess.is_sanitizer_cfi_enabled() { let canonical_jump_tables = c"CFI Canonical Jump Tables".as_ptr().cast(); - llvm::LLVMRustAddModuleFlagU32( - llmod, - llvm::LLVMModFlagBehavior::Override, - canonical_jump_tables, - 1, - ); + unsafe { + llvm::LLVMRustAddModuleFlagU32( + llmod, + llvm::LLVMModFlagBehavior::Override, + canonical_jump_tables, + 1, + ); + } } // Enable LTO unit splitting if specified or if CFI is enabled. (See https://reviews.llvm.org/D53891.) if sess.is_split_lto_unit_enabled() || sess.is_sanitizer_cfi_enabled() { let enable_split_lto_unit = c"EnableSplitLTOUnit".as_ptr().cast(); - llvm::LLVMRustAddModuleFlagU32( - llmod, - llvm::LLVMModFlagBehavior::Override, - enable_split_lto_unit, - 1, - ); + unsafe { + llvm::LLVMRustAddModuleFlagU32( + llmod, + llvm::LLVMModFlagBehavior::Override, + enable_split_lto_unit, + 1, + ); + } } // Add "kcfi" module flag if KCFI is enabled. (See https://reviews.llvm.org/D119296.) if sess.is_sanitizer_kcfi_enabled() { let kcfi = c"kcfi".as_ptr().cast(); - llvm::LLVMRustAddModuleFlagU32(llmod, llvm::LLVMModFlagBehavior::Override, kcfi, 1); + unsafe { + llvm::LLVMRustAddModuleFlagU32(llmod, llvm::LLVMModFlagBehavior::Override, kcfi, 1); + } } // Control Flow Guard is currently only supported by the MSVC linker on Windows. if sess.target.is_like_msvc { - match sess.opts.cg.control_flow_guard { - CFGuard::Disabled => {} - CFGuard::NoChecks => { - // Set `cfguard=1` module flag to emit metadata only. - llvm::LLVMRustAddModuleFlagU32( - llmod, - llvm::LLVMModFlagBehavior::Warning, - c"cfguard".as_ptr() as *const _, - 1, - ) - } - CFGuard::Checks => { - // Set `cfguard=2` module flag to emit metadata and checks. - llvm::LLVMRustAddModuleFlagU32( - llmod, - llvm::LLVMModFlagBehavior::Warning, - c"cfguard".as_ptr() as *const _, - 2, - ) + unsafe { + match sess.opts.cg.control_flow_guard { + CFGuard::Disabled => {} + CFGuard::NoChecks => { + // Set `cfguard=1` module flag to emit metadata only. + llvm::LLVMRustAddModuleFlagU32( + llmod, + llvm::LLVMModFlagBehavior::Warning, + c"cfguard".as_ptr() as *const _, + 1, + ) + } + CFGuard::Checks => { + // Set `cfguard=2` module flag to emit metadata and checks. + llvm::LLVMRustAddModuleFlagU32( + llmod, + llvm::LLVMModFlagBehavior::Warning, + c"cfguard".as_ptr() as *const _, + 2, + ) + } } } } if let Some(BranchProtection { bti, pac_ret }) = sess.opts.unstable_opts.branch_protection { if sess.target.arch == "aarch64" { - llvm::LLVMRustAddModuleFlagU32( - llmod, - llvm::LLVMModFlagBehavior::Min, - c"branch-target-enforcement".as_ptr().cast(), - bti.into(), - ); - llvm::LLVMRustAddModuleFlagU32( - llmod, - llvm::LLVMModFlagBehavior::Min, - c"sign-return-address".as_ptr().cast(), - pac_ret.is_some().into(), - ); - let pac_opts = pac_ret.unwrap_or(PacRet { leaf: false, key: PAuthKey::A }); - llvm::LLVMRustAddModuleFlagU32( - llmod, - llvm::LLVMModFlagBehavior::Min, - c"sign-return-address-all".as_ptr().cast(), - pac_opts.leaf.into(), - ); - llvm::LLVMRustAddModuleFlagU32( - llmod, - llvm::LLVMModFlagBehavior::Min, - c"sign-return-address-with-bkey".as_ptr().cast(), - u32::from(pac_opts.key == PAuthKey::B), - ); + unsafe { + llvm::LLVMRustAddModuleFlagU32( + llmod, + llvm::LLVMModFlagBehavior::Min, + c"branch-target-enforcement".as_ptr().cast(), + bti.into(), + ); + llvm::LLVMRustAddModuleFlagU32( + llmod, + llvm::LLVMModFlagBehavior::Min, + c"sign-return-address".as_ptr().cast(), + pac_ret.is_some().into(), + ); + let pac_opts = pac_ret.unwrap_or(PacRet { leaf: false, key: PAuthKey::A }); + llvm::LLVMRustAddModuleFlagU32( + llmod, + llvm::LLVMModFlagBehavior::Min, + c"sign-return-address-all".as_ptr().cast(), + pac_opts.leaf.into(), + ); + llvm::LLVMRustAddModuleFlagU32( + llmod, + llvm::LLVMModFlagBehavior::Min, + c"sign-return-address-with-bkey".as_ptr().cast(), + u32::from(pac_opts.key == PAuthKey::B), + ); + } } else { bug!( "branch-protection used on non-AArch64 target; \ @@ -291,39 +316,47 @@ pub unsafe fn create_module<'ll>( // Pass on the control-flow protection flags to LLVM (equivalent to `-fcf-protection` in Clang). if let CFProtection::Branch | CFProtection::Full = sess.opts.unstable_opts.cf_protection { - llvm::LLVMRustAddModuleFlagU32( - llmod, - llvm::LLVMModFlagBehavior::Override, - c"cf-protection-branch".as_ptr().cast(), - 1, - ) + unsafe { + llvm::LLVMRustAddModuleFlagU32( + llmod, + llvm::LLVMModFlagBehavior::Override, + c"cf-protection-branch".as_ptr().cast(), + 1, + ); + } } if let CFProtection::Return | CFProtection::Full = sess.opts.unstable_opts.cf_protection { - llvm::LLVMRustAddModuleFlagU32( - llmod, - llvm::LLVMModFlagBehavior::Override, - c"cf-protection-return".as_ptr().cast(), - 1, - ) + unsafe { + llvm::LLVMRustAddModuleFlagU32( + llmod, + llvm::LLVMModFlagBehavior::Override, + c"cf-protection-return".as_ptr().cast(), + 1, + ); + } } if sess.opts.unstable_opts.virtual_function_elimination { - llvm::LLVMRustAddModuleFlagU32( - llmod, - llvm::LLVMModFlagBehavior::Error, - c"Virtual Function Elim".as_ptr().cast(), - 1, - ); + unsafe { + llvm::LLVMRustAddModuleFlagU32( + llmod, + llvm::LLVMModFlagBehavior::Error, + c"Virtual Function Elim".as_ptr().cast(), + 1, + ); + } } // Set module flag to enable Windows EHCont Guard (/guard:ehcont). if sess.opts.unstable_opts.ehcont_guard { - llvm::LLVMRustAddModuleFlagU32( - llmod, - llvm::LLVMModFlagBehavior::Warning, - c"ehcontguard".as_ptr() as *const _, - 1, - ) + unsafe { + llvm::LLVMRustAddModuleFlagU32( + llmod, + llvm::LLVMModFlagBehavior::Warning, + c"ehcontguard".as_ptr() as *const _, + 1, + ) + } } // Insert `llvm.ident` metadata. @@ -333,16 +366,20 @@ pub unsafe fn create_module<'ll>( #[allow(clippy::option_env_unwrap)] let rustc_producer = format!("rustc version {}", option_env!("CFG_VERSION").expect("CFG_VERSION")); - let name_metadata = llvm::LLVMMDStringInContext( - llcx, - rustc_producer.as_ptr().cast(), - rustc_producer.as_bytes().len() as c_uint, - ); - llvm::LLVMAddNamedMetadataOperand( - llmod, - c"llvm.ident".as_ptr(), - llvm::LLVMMDNodeInContext(llcx, &name_metadata, 1), - ); + let name_metadata = unsafe { + llvm::LLVMMDStringInContext( + llcx, + rustc_producer.as_ptr().cast(), + rustc_producer.as_bytes().len() as c_uint, + ) + }; + unsafe { + llvm::LLVMAddNamedMetadataOperand( + llmod, + c"llvm.ident".as_ptr(), + llvm::LLVMMDNodeInContext(llcx, &name_metadata, 1), + ); + } // Emit RISC-V specific target-abi metadata // to workaround lld as the LTO plugin not @@ -351,13 +388,15 @@ pub unsafe fn create_module<'ll>( // If llvm_abiname is empty, emit nothing. let llvm_abiname = &sess.target.options.llvm_abiname; if matches!(sess.target.arch.as_ref(), "riscv32" | "riscv64") && !llvm_abiname.is_empty() { - llvm::LLVMRustAddModuleFlagString( - llmod, - llvm::LLVMModFlagBehavior::Error, - c"target-abi".as_ptr(), - llvm_abiname.as_ptr().cast(), - llvm_abiname.len(), - ); + unsafe { + llvm::LLVMRustAddModuleFlagString( + llmod, + llvm::LLVMModFlagBehavior::Error, + c"target-abi".as_ptr(), + llvm_abiname.as_ptr().cast(), + llvm_abiname.len(), + ); + } } // Add module flags specified via -Z llvm_module_flag @@ -375,7 +414,7 @@ pub unsafe fn create_module<'ll>( // We already checked this during option parsing _ => unreachable!(), }; - llvm::LLVMRustAddModuleFlagU32(llmod, behavior, key.as_ptr().cast(), *value) + unsafe { llvm::LLVMRustAddModuleFlagU32(llmod, behavior, key.as_ptr().cast(), *value) } } llmod diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index ed0989a0ba413..a96993b9aba74 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -216,7 +216,7 @@ impl WriteBackendMethods for LlvmCodegenBackend { module: &ModuleCodegen, config: &ModuleConfig, ) -> Result<(), FatalError> { - back::write::optimize(cgcx, dcx, module, config) + unsafe { back::write::optimize(cgcx, dcx, module, config) } } fn optimize_fat( cgcx: &CodegenContext, @@ -230,7 +230,7 @@ impl WriteBackendMethods for LlvmCodegenBackend { cgcx: &CodegenContext, thin: ThinModule, ) -> Result, FatalError> { - back::lto::optimize_thin_module(thin, cgcx) + unsafe { back::lto::optimize_thin_module(thin, cgcx) } } unsafe fn codegen( cgcx: &CodegenContext, @@ -238,7 +238,7 @@ impl WriteBackendMethods for LlvmCodegenBackend { module: ModuleCodegen, config: &ModuleConfig, ) -> Result { - back::write::codegen(cgcx, dcx, module, config) + unsafe { back::write::codegen(cgcx, dcx, module, config) } } fn prepare_thin( module: ModuleCodegen, diff --git a/compiler/rustc_codegen_llvm/src/llvm/diagnostic.rs b/compiler/rustc_codegen_llvm/src/llvm/diagnostic.rs index f9b28178ddb97..73e1b08a3d77a 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/diagnostic.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/diagnostic.rs @@ -40,7 +40,7 @@ impl<'ll> OptimizationDiagnostic<'ll> { let mut filename = None; let pass_name = super::build_string(|pass_name| { message = super::build_string(|message| { - filename = super::build_string(|filename| { + filename = super::build_string(|filename| unsafe { super::LLVMRustUnpackOptimizationDiagnostic( di, pass_name, @@ -91,7 +91,7 @@ impl SrcMgrDiagnostic { let mut ranges = [0; 8]; let mut num_ranges = ranges.len() / 2; let message = super::build_string(|message| { - buffer = super::build_string(|buffer| { + buffer = super::build_string(|buffer| unsafe { have_source = super::LLVMRustUnpackSMDiagnostic( diag, message, @@ -134,7 +134,9 @@ impl InlineAsmDiagnostic { let mut message = None; let mut level = super::DiagnosticLevel::Error; - super::LLVMRustUnpackInlineAsmDiagnostic(di, &mut level, &mut cookie, &mut message); + unsafe { + super::LLVMRustUnpackInlineAsmDiagnostic(di, &mut level, &mut cookie, &mut message); + } InlineAsmDiagnostic { level, @@ -146,7 +148,8 @@ impl InlineAsmDiagnostic { unsafe fn unpackSrcMgr(di: &DiagnosticInfo) -> Self { let mut cookie = 0; - let smdiag = SrcMgrDiagnostic::unpack(super::LLVMRustGetSMDiagnostic(di, &mut cookie)); + let smdiag = + unsafe { SrcMgrDiagnostic::unpack(super::LLVMRustGetSMDiagnostic(di, &mut cookie)) }; InlineAsmDiagnostic { level: smdiag.level, cookie: cookie.into(), @@ -170,44 +173,46 @@ pub enum Diagnostic<'ll> { impl<'ll> Diagnostic<'ll> { pub unsafe fn unpack(di: &'ll DiagnosticInfo) -> Self { use super::DiagnosticKind as Dk; - let kind = super::LLVMRustGetDiagInfoKind(di); - match kind { - Dk::InlineAsm => InlineAsm(InlineAsmDiagnostic::unpackInlineAsm(di)), + unsafe { + let kind = super::LLVMRustGetDiagInfoKind(di); + match kind { + Dk::InlineAsm => InlineAsm(InlineAsmDiagnostic::unpackInlineAsm(di)), - Dk::OptimizationRemark => { - Optimization(OptimizationDiagnostic::unpack(OptimizationRemark, di)) - } - Dk::OptimizationRemarkOther => { - Optimization(OptimizationDiagnostic::unpack(OptimizationRemarkOther, di)) - } - Dk::OptimizationRemarkMissed => { - Optimization(OptimizationDiagnostic::unpack(OptimizationMissed, di)) - } + Dk::OptimizationRemark => { + Optimization(OptimizationDiagnostic::unpack(OptimizationRemark, di)) + } + Dk::OptimizationRemarkOther => { + Optimization(OptimizationDiagnostic::unpack(OptimizationRemarkOther, di)) + } + Dk::OptimizationRemarkMissed => { + Optimization(OptimizationDiagnostic::unpack(OptimizationMissed, di)) + } - Dk::OptimizationRemarkAnalysis => { - Optimization(OptimizationDiagnostic::unpack(OptimizationAnalysis, di)) - } + Dk::OptimizationRemarkAnalysis => { + Optimization(OptimizationDiagnostic::unpack(OptimizationAnalysis, di)) + } - Dk::OptimizationRemarkAnalysisFPCommute => { - Optimization(OptimizationDiagnostic::unpack(OptimizationAnalysisFPCommute, di)) - } + Dk::OptimizationRemarkAnalysisFPCommute => { + Optimization(OptimizationDiagnostic::unpack(OptimizationAnalysisFPCommute, di)) + } - Dk::OptimizationRemarkAnalysisAliasing => { - Optimization(OptimizationDiagnostic::unpack(OptimizationAnalysisAliasing, di)) - } + Dk::OptimizationRemarkAnalysisAliasing => { + Optimization(OptimizationDiagnostic::unpack(OptimizationAnalysisAliasing, di)) + } - Dk::OptimizationFailure => { - Optimization(OptimizationDiagnostic::unpack(OptimizationFailure, di)) - } + Dk::OptimizationFailure => { + Optimization(OptimizationDiagnostic::unpack(OptimizationFailure, di)) + } - Dk::PGOProfile => PGO(di), - Dk::Linker => Linker(di), - Dk::Unsupported => Unsupported(di), + Dk::PGOProfile => PGO(di), + Dk::Linker => Linker(di), + Dk::Unsupported => Unsupported(di), - Dk::SrcMgr => InlineAsm(InlineAsmDiagnostic::unpackSrcMgr(di)), + Dk::SrcMgr => InlineAsm(InlineAsmDiagnostic::unpackSrcMgr(di)), - _ => UnknownDiagnostic(di), + _ => UnknownDiagnostic(di), + } } } } diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs index 0e89e66be49a0..98dc8ac86d2b3 100644 --- a/compiler/rustc_codegen_llvm/src/llvm_util.rs +++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs @@ -49,12 +49,16 @@ unsafe fn configure_llvm(sess: &Session) { let mut llvm_c_strs = Vec::with_capacity(n_args + 1); let mut llvm_args = Vec::with_capacity(n_args + 1); - llvm::LLVMRustInstallErrorHandlers(); + unsafe { + llvm::LLVMRustInstallErrorHandlers(); + } // On Windows, an LLVM assertion will open an Abort/Retry/Ignore dialog // box for the purpose of launching a debugger. However, on CI this will // cause it to hang until it times out, which can take several hours. if std::env::var_os("CI").is_some() { - llvm::LLVMRustDisableSystemDialogsOnCrash(); + unsafe { + llvm::LLVMRustDisableSystemDialogsOnCrash(); + } } fn llvm_arg_to_arg_name(full_arg: &str) -> &str { @@ -124,12 +128,12 @@ unsafe fn configure_llvm(sess: &Session) { } if sess.opts.unstable_opts.llvm_time_trace { - llvm::LLVMRustTimeTraceProfilerInitialize(); + unsafe { llvm::LLVMRustTimeTraceProfilerInitialize() }; } rustc_llvm::initialize_available_targets(); - llvm::LLVMRustSetLLVMOptions(llvm_args.len() as c_int, llvm_args.as_ptr()); + unsafe { llvm::LLVMRustSetLLVMOptions(llvm_args.len() as c_int, llvm_args.as_ptr()) }; } pub fn time_trace_profiler_finish(file_name: &Path) { @@ -442,8 +446,8 @@ pub(crate) fn print(req: &PrintRequest, mut out: &mut String, sess: &Session) { let cpu_cstring = CString::new(handle_native(sess.target.cpu.as_ref())) .unwrap_or_else(|e| bug!("failed to convert to cstring: {}", e)); unsafe extern "C" fn callback(out: *mut c_void, string: *const c_char, len: usize) { - let out = &mut *(out as *mut &mut String); - let bytes = slice::from_raw_parts(string as *const u8, len); + let out = unsafe { &mut *(out as *mut &mut String) }; + let bytes = unsafe { slice::from_raw_parts(string as *const u8, len) }; write!(out, "{}", String::from_utf8_lossy(bytes)).unwrap(); } unsafe { diff --git a/compiler/rustc_codegen_llvm/src/mono_item.rs b/compiler/rustc_codegen_llvm/src/mono_item.rs index a7df08421a31e..282a186be99ac 100644 --- a/compiler/rustc_codegen_llvm/src/mono_item.rs +++ b/compiler/rustc_codegen_llvm/src/mono_item.rs @@ -108,8 +108,8 @@ impl CodegenCx<'_, '_> { llval: &llvm::Value, is_declaration: bool, ) -> bool { - let linkage = llvm::LLVMRustGetLinkage(llval); - let visibility = llvm::LLVMRustGetVisibility(llval); + let linkage = unsafe { llvm::LLVMRustGetLinkage(llval) }; + let visibility = unsafe { llvm::LLVMRustGetVisibility(llval) }; if matches!(linkage, llvm::Linkage::InternalLinkage | llvm::Linkage::PrivateLinkage) { return true; @@ -145,8 +145,8 @@ impl CodegenCx<'_, '_> { } // Thread-local variables generally don't support copy relocations. - let is_thread_local_var = llvm::LLVMIsAGlobalVariable(llval) - .is_some_and(|v| llvm::LLVMIsThreadLocal(v) == llvm::True); + let is_thread_local_var = unsafe { llvm::LLVMIsAGlobalVariable(llval) } + .is_some_and(|v| unsafe { llvm::LLVMIsThreadLocal(v) } == llvm::True); if is_thread_local_var { return false; } diff --git a/compiler/rustc_codegen_ssa/src/back/lto.rs b/compiler/rustc_codegen_ssa/src/back/lto.rs index cb6244050df24..5291cad148e26 100644 --- a/compiler/rustc_codegen_ssa/src/back/lto.rs +++ b/compiler/rustc_codegen_ssa/src/back/lto.rs @@ -72,7 +72,7 @@ impl LtoModuleCodegen { B::optimize_fat(cgcx, &mut module)?; Ok(module) } - LtoModuleCodegen::Thin(thin) => B::optimize_thin(cgcx, thin), + LtoModuleCodegen::Thin(thin) => unsafe { B::optimize_thin(cgcx, thin) }, } } diff --git a/compiler/rustc_llvm/src/lib.rs b/compiler/rustc_llvm/src/lib.rs index e5366c9b51830..1365afbce1c37 100644 --- a/compiler/rustc_llvm/src/lib.rs +++ b/compiler/rustc_llvm/src/lib.rs @@ -33,7 +33,7 @@ pub unsafe extern "C" fn LLVMRustStringWriteImpl( ptr: *const c_char, size: size_t, ) { - let slice = slice::from_raw_parts(ptr as *const u8, size); + let slice = unsafe { slice::from_raw_parts(ptr as *const u8, size) }; sr.bytes.borrow_mut().extend_from_slice(slice); } diff --git a/compiler/rustc_middle/src/ty/context/tls.rs b/compiler/rustc_middle/src/ty/context/tls.rs index 5e256dc8d26e2..7b5ccae35682e 100644 --- a/compiler/rustc_middle/src/ty/context/tls.rs +++ b/compiler/rustc_middle/src/ty/context/tls.rs @@ -67,7 +67,7 @@ fn erase(context: &ImplicitCtxt<'_, '_>) -> *const () { #[inline] unsafe fn downcast<'a, 'tcx>(context: *const ()) -> &'a ImplicitCtxt<'a, 'tcx> { - &*(context as *const ImplicitCtxt<'a, 'tcx>) + unsafe { &*(context as *const ImplicitCtxt<'a, 'tcx>) } } /// Sets `context` as the new current `ImplicitCtxt` for the duration of the function `f`. diff --git a/compiler/rustc_span/src/analyze_source_file.rs b/compiler/rustc_span/src/analyze_source_file.rs index 80c5c3bf1b5a7..d9e1ebaf0bce0 100644 --- a/compiler/rustc_span/src/analyze_source_file.rs +++ b/compiler/rustc_span/src/analyze_source_file.rs @@ -89,13 +89,13 @@ cfg_match! { let ptr = src_bytes.as_ptr() as *const __m128i; // We don't know if the pointer is aligned to 16 bytes, so we // use `loadu`, which supports unaligned loading. - let chunk = _mm_loadu_si128(ptr.add(chunk_index)); + let chunk = unsafe { _mm_loadu_si128(ptr.add(chunk_index)) }; // For character in the chunk, see if its byte value is < 0, which // indicates that it's part of a UTF-8 char. - let multibyte_test = _mm_cmplt_epi8(chunk, _mm_set1_epi8(0)); + let multibyte_test = unsafe { _mm_cmplt_epi8(chunk, _mm_set1_epi8(0)) }; // Create a bit mask from the comparison results. - let multibyte_mask = _mm_movemask_epi8(multibyte_test); + let multibyte_mask = unsafe { _mm_movemask_epi8(multibyte_test) }; // If the bit mask is all zero, we only have ASCII chars here: if multibyte_mask == 0 { @@ -104,19 +104,19 @@ cfg_match! { // Check if there are any control characters in the chunk. All // control characters that we can encounter at this point have a // byte value less than 32 or ... - let control_char_test0 = _mm_cmplt_epi8(chunk, _mm_set1_epi8(32)); - let control_char_mask0 = _mm_movemask_epi8(control_char_test0); + let control_char_test0 = unsafe { _mm_cmplt_epi8(chunk, _mm_set1_epi8(32)) }; + let control_char_mask0 = unsafe { _mm_movemask_epi8(control_char_test0) }; // ... it's the ASCII 'DEL' character with a value of 127. - let control_char_test1 = _mm_cmpeq_epi8(chunk, _mm_set1_epi8(127)); - let control_char_mask1 = _mm_movemask_epi8(control_char_test1); + let control_char_test1 = unsafe { _mm_cmpeq_epi8(chunk, _mm_set1_epi8(127)) }; + let control_char_mask1 = unsafe { _mm_movemask_epi8(control_char_test1) }; let control_char_mask = control_char_mask0 | control_char_mask1; if control_char_mask != 0 { // Check for newlines in the chunk - let newlines_test = _mm_cmpeq_epi8(chunk, _mm_set1_epi8(b'\n' as i8)); - let newlines_mask = _mm_movemask_epi8(newlines_test); + let newlines_test = unsafe { _mm_cmpeq_epi8(chunk, _mm_set1_epi8(b'\n' as i8)) }; + let newlines_mask = unsafe { _mm_movemask_epi8(newlines_test) }; if control_char_mask == newlines_mask { // All control characters are newlines, record them diff --git a/src/bootstrap/src/core/builder.rs b/src/bootstrap/src/core/builder.rs index f033905e9f62c..604fd8e199088 100644 --- a/src/bootstrap/src/core/builder.rs +++ b/src/bootstrap/src/core/builder.rs @@ -2001,6 +2001,7 @@ impl<'a> Builder<'a> { // FIXME(edition_2024): Change this to `-Wrust_2024_idioms` when all // of the individual lints are satisfied. rustflags.arg("-Wkeyword_idents_2024"); + rustflags.arg("-Wunsafe_op_in_unsafe_fn"); } if self.config.rust_frame_pointers { From 664907cab68408a2a67c70d5f6864f558840b119 Mon Sep 17 00:00:00 2001 From: Mrmaxmeier Date: Tue, 16 Jul 2024 11:01:35 +0200 Subject: [PATCH 09/17] run-make-support: update gimli to 0.31.0 --- Cargo.lock | 13 ++++++++++++- src/tools/run-make-support/Cargo.toml | 2 +- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index cafc623c185a6..68478d55e2319 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1618,6 +1618,17 @@ dependencies = [ "rustc-std-workspace-core", ] +[[package]] +name = "gimli" +version = "0.31.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32085ea23f3234fc7846555e85283ba4de91e21016dc0455a16286d87a292d64" +dependencies = [ + "fallible-iterator", + "indexmap", + "stable_deref_trait", +] + [[package]] name = "glob" version = "0.3.1" @@ -3421,7 +3432,7 @@ dependencies = [ "ar", "bstr", "build_helper", - "gimli 0.28.1", + "gimli 0.31.0", "object 0.34.0", "regex", "similar", diff --git a/src/tools/run-make-support/Cargo.toml b/src/tools/run-make-support/Cargo.toml index 969552dec84ad..681284b1a489c 100644 --- a/src/tools/run-make-support/Cargo.toml +++ b/src/tools/run-make-support/Cargo.toml @@ -9,7 +9,7 @@ object = "0.34.0" similar = "2.5.0" wasmparser = "0.118.2" regex = "1.8" # 1.8 to avoid memchr 2.6.0, as 2.5.0 is pinned in the workspace -gimli = "0.28.1" +gimli = "0.31.0" ar = "0.9.0" build_helper = { path = "../build_helper" } From fb98fbb759cf7b2e3cb262bf3621407cae9e3c6d Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 16 Jul 2024 11:31:04 +0000 Subject: [PATCH 10/17] Make `ErrorGuaranteed` discoverable outside types, consts, and lifetimes --- .../rustc_middle/src/ty/structural_impls.rs | 19 ++++++++-- compiler/rustc_type_ir/src/visit.rs | 36 +++++++------------ 2 files changed, 29 insertions(+), 26 deletions(-) diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index a9dca47ab4373..33c04b4111735 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -257,7 +257,6 @@ TrivialTypeTraversalImpls! { crate::ty::adjustment::PointerCoercion, ::rustc_span::Span, ::rustc_span::symbol::Ident, - ::rustc_errors::ErrorGuaranteed, ty::BoundVar, ty::ValTree<'tcx>, } @@ -443,13 +442,14 @@ impl<'tcx> TypeSuperVisitable> for Ty<'tcx> { pat.visit_with(visitor) } + ty::Error(guar) => guar.visit_with(visitor), + ty::Bool | ty::Char | ty::Str | ty::Int(_) | ty::Uint(_) | ty::Float(_) - | ty::Error(_) | ty::Infer(_) | ty::Bound(..) | ty::Placeholder(..) @@ -602,6 +602,21 @@ impl<'tcx> TypeSuperVisitable> for ty::Const<'tcx> { } } +impl<'tcx> TypeVisitable> for rustc_span::ErrorGuaranteed { + fn visit_with>>(&self, visitor: &mut V) -> V::Result { + visitor.visit_error(*self) + } +} + +impl<'tcx> TypeFoldable> for rustc_span::ErrorGuaranteed { + fn try_fold_with>>( + self, + _folder: &mut F, + ) -> Result { + Ok(self) + } +} + impl<'tcx> TypeFoldable> for InferConst { fn try_fold_with>>( self, diff --git a/compiler/rustc_type_ir/src/visit.rs b/compiler/rustc_type_ir/src/visit.rs index 25eb56fe3fb51..d604199b8e06a 100644 --- a/compiler/rustc_type_ir/src/visit.rs +++ b/compiler/rustc_type_ir/src/visit.rs @@ -101,8 +101,12 @@ pub trait TypeVisitor: Sized { // The default region visitor is a no-op because `Region` is non-recursive // and has no `super_visit_with` method to call. - fn visit_region(&mut self, _r: I::Region) -> Self::Result { - Self::Result::output() + fn visit_region(&mut self, r: I::Region) -> Self::Result { + if let ty::ReError(guar) = r.kind() { + self.visit_error(guar) + } else { + Self::Result::output() + } } fn visit_const(&mut self, c: I::Const) -> Self::Result { @@ -116,6 +120,10 @@ pub trait TypeVisitor: Sized { fn visit_clauses(&mut self, p: I::Clauses) -> Self::Result { p.super_visit_with(self) } + + fn visit_error(&mut self, _guar: I::ErrorGuaranteed) -> Self::Result { + Self::Result::output() + } } /////////////////////////////////////////////////////////////////////////// @@ -547,27 +555,7 @@ struct HasErrorVisitor; impl TypeVisitor for HasErrorVisitor { type Result = ControlFlow; - fn visit_ty(&mut self, t: ::Ty) -> Self::Result { - if let ty::Error(guar) = t.kind() { - ControlFlow::Break(guar) - } else { - t.super_visit_with(self) - } - } - - fn visit_const(&mut self, c: ::Const) -> Self::Result { - if let ty::ConstKind::Error(guar) = c.kind() { - ControlFlow::Break(guar) - } else { - c.super_visit_with(self) - } - } - - fn visit_region(&mut self, r: ::Region) -> Self::Result { - if let ty::ReError(guar) = r.kind() { - ControlFlow::Break(guar) - } else { - ControlFlow::Continue(()) - } + fn visit_error(&mut self, guar: ::ErrorGuaranteed) -> Self::Result { + ControlFlow::Break(guar) } } From 077d0da30a888ea049a471bca6301d706ca66c25 Mon Sep 17 00:00:00 2001 From: yukang Date: Tue, 16 Jul 2024 21:57:12 +0800 Subject: [PATCH 11/17] add test for issue 127590 --- .../invalid-suggest-deref-issue-127590.rs | 18 +++++ .../invalid-suggest-deref-issue-127590.stderr | 69 +++++++++++++++++++ 2 files changed, 87 insertions(+) create mode 100644 tests/ui/traits/suggest-dereferences/invalid-suggest-deref-issue-127590.rs create mode 100644 tests/ui/traits/suggest-dereferences/invalid-suggest-deref-issue-127590.stderr diff --git a/tests/ui/traits/suggest-dereferences/invalid-suggest-deref-issue-127590.rs b/tests/ui/traits/suggest-dereferences/invalid-suggest-deref-issue-127590.rs new file mode 100644 index 0000000000000..a71657316ae60 --- /dev/null +++ b/tests/ui/traits/suggest-dereferences/invalid-suggest-deref-issue-127590.rs @@ -0,0 +1,18 @@ +fn main() { + let fields = vec![1]; + let variant = vec![2]; + + // should not suggest `*&variant.iter()` + for (src, dest) in std::iter::zip(fields.iter(), &variant.iter()) { + //~^ ERROR `&std::slice::Iter<'_, {integer}>` is not an iterator + //~| ERROR `&std::slice::Iter<'_, {integer}>` is not an iterator + eprintln!("{} {}", src, dest); + } + + // don't suggest add `variant.iter().clone().clone()` + for (src, dest) in std::iter::zip(fields.iter(), &variant.iter().clone()) { + //~^ ERROR `&std::slice::Iter<'_, {integer}>` is not an iterator + //~| ERROR `&std::slice::Iter<'_, {integer}>` is not an iterator + eprintln!("{} {}", src, dest); + } +} diff --git a/tests/ui/traits/suggest-dereferences/invalid-suggest-deref-issue-127590.stderr b/tests/ui/traits/suggest-dereferences/invalid-suggest-deref-issue-127590.stderr new file mode 100644 index 0000000000000..14befe796cf0d --- /dev/null +++ b/tests/ui/traits/suggest-dereferences/invalid-suggest-deref-issue-127590.stderr @@ -0,0 +1,69 @@ +error[E0277]: `&std::slice::Iter<'_, {integer}>` is not an iterator + --> $DIR/invalid-suggest-deref-issue-127590.rs:6:54 + | +LL | for (src, dest) in std::iter::zip(fields.iter(), &variant.iter()) { + | -------------- ^^^^^^^^^^^^^^^ `&std::slice::Iter<'_, {integer}>` is not an iterator + | | + | required by a bound introduced by this call + | + = help: the trait `Iterator` is not implemented for `&std::slice::Iter<'_, {integer}>`, which is required by `&std::slice::Iter<'_, {integer}>: IntoIterator` + = note: required for `&std::slice::Iter<'_, {integer}>` to implement `IntoIterator` +note: required by a bound in `std::iter::zip` + --> $SRC_DIR/core/src/iter/adapters/zip.rs:LL:COL +help: consider dereferencing here + | +LL | for (src, dest) in std::iter::zip(fields.iter(), *&variant.iter()) { + | + +help: consider removing the leading `&`-reference + | +LL - for (src, dest) in std::iter::zip(fields.iter(), &variant.iter()) { +LL + for (src, dest) in std::iter::zip(fields.iter(), variant.iter()) { + | + +error[E0277]: `&std::slice::Iter<'_, {integer}>` is not an iterator + --> $DIR/invalid-suggest-deref-issue-127590.rs:6:24 + | +LL | for (src, dest) in std::iter::zip(fields.iter(), &variant.iter()) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `&std::slice::Iter<'_, {integer}>` is not an iterator + | + = help: the trait `Iterator` is not implemented for `&std::slice::Iter<'_, {integer}>`, which is required by `Zip, &std::slice::Iter<'_, {integer}>>: IntoIterator` + = help: the trait `Iterator` is implemented for `std::slice::Iter<'a, T>` + = note: required for `Zip, &std::slice::Iter<'_, {integer}>>` to implement `Iterator` + = note: required for `Zip, &std::slice::Iter<'_, {integer}>>` to implement `IntoIterator` + +error[E0277]: `&std::slice::Iter<'_, {integer}>` is not an iterator + --> $DIR/invalid-suggest-deref-issue-127590.rs:13:54 + | +LL | for (src, dest) in std::iter::zip(fields.iter(), &variant.iter().clone()) { + | -------------- ^^^^^^^^^^^^^^^^^^^^^^^ `&std::slice::Iter<'_, {integer}>` is not an iterator + | | + | required by a bound introduced by this call + | + = help: the trait `Iterator` is not implemented for `&std::slice::Iter<'_, {integer}>`, which is required by `&std::slice::Iter<'_, {integer}>: IntoIterator` + = note: required for `&std::slice::Iter<'_, {integer}>` to implement `IntoIterator` +note: required by a bound in `std::iter::zip` + --> $SRC_DIR/core/src/iter/adapters/zip.rs:LL:COL +help: consider dereferencing here + | +LL | for (src, dest) in std::iter::zip(fields.iter(), *&variant.iter().clone()) { + | + +help: consider removing the leading `&`-reference + | +LL - for (src, dest) in std::iter::zip(fields.iter(), &variant.iter().clone()) { +LL + for (src, dest) in std::iter::zip(fields.iter(), variant.iter().clone()) { + | + +error[E0277]: `&std::slice::Iter<'_, {integer}>` is not an iterator + --> $DIR/invalid-suggest-deref-issue-127590.rs:13:24 + | +LL | for (src, dest) in std::iter::zip(fields.iter(), &variant.iter().clone()) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `&std::slice::Iter<'_, {integer}>` is not an iterator + | + = help: the trait `Iterator` is not implemented for `&std::slice::Iter<'_, {integer}>`, which is required by `Zip, &std::slice::Iter<'_, {integer}>>: IntoIterator` + = help: the trait `Iterator` is implemented for `std::slice::Iter<'a, T>` + = note: required for `Zip, &std::slice::Iter<'_, {integer}>>` to implement `Iterator` + = note: required for `Zip, &std::slice::Iter<'_, {integer}>>` to implement `IntoIterator` + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0277`. From 48ddf5e32398287efed553e88043bafc04177917 Mon Sep 17 00:00:00 2001 From: yukang Date: Tue, 16 Jul 2024 22:00:04 +0800 Subject: [PATCH 12/17] Fix the issue of invalid suggestion for a reference of iterator --- .../src/error_reporting/traits/suggestions.rs | 4 +++- .../invalid-suggest-deref-issue-127590.stderr | 8 -------- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs index f8843b892db3d..2bf582dcfb11d 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs @@ -466,7 +466,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { && let Some(arg_ty) = typeck_results.expr_ty_adjusted_opt(expr) { // Suggest dereferencing the argument to a function/method call if possible - let mut real_trait_pred = trait_pred; while let Some((parent_code, parent_trait_pred)) = code.parent() { code = parent_code; @@ -553,6 +552,9 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { ); if self.predicate_may_hold(&obligation) && self.predicate_must_hold_modulo_regions(&sized_obligation) + // Do not suggest * if it is already a reference, + // will suggest removing the borrow instead in that case. + && !matches!(expr.kind, hir::ExprKind::AddrOf(..)) { let call_node = self.tcx.hir_node(*call_hir_id); let msg = "consider dereferencing here"; diff --git a/tests/ui/traits/suggest-dereferences/invalid-suggest-deref-issue-127590.stderr b/tests/ui/traits/suggest-dereferences/invalid-suggest-deref-issue-127590.stderr index 14befe796cf0d..a3ed51ace0880 100644 --- a/tests/ui/traits/suggest-dereferences/invalid-suggest-deref-issue-127590.stderr +++ b/tests/ui/traits/suggest-dereferences/invalid-suggest-deref-issue-127590.stderr @@ -10,10 +10,6 @@ LL | for (src, dest) in std::iter::zip(fields.iter(), &variant.iter()) { = note: required for `&std::slice::Iter<'_, {integer}>` to implement `IntoIterator` note: required by a bound in `std::iter::zip` --> $SRC_DIR/core/src/iter/adapters/zip.rs:LL:COL -help: consider dereferencing here - | -LL | for (src, dest) in std::iter::zip(fields.iter(), *&variant.iter()) { - | + help: consider removing the leading `&`-reference | LL - for (src, dest) in std::iter::zip(fields.iter(), &variant.iter()) { @@ -43,10 +39,6 @@ LL | for (src, dest) in std::iter::zip(fields.iter(), &variant.iter().clone( = note: required for `&std::slice::Iter<'_, {integer}>` to implement `IntoIterator` note: required by a bound in `std::iter::zip` --> $SRC_DIR/core/src/iter/adapters/zip.rs:LL:COL -help: consider dereferencing here - | -LL | for (src, dest) in std::iter::zip(fields.iter(), *&variant.iter().clone()) { - | + help: consider removing the leading `&`-reference | LL - for (src, dest) in std::iter::zip(fields.iter(), &variant.iter().clone()) { From 53f7f8ce5cb01a4bdef70b0bdb4aa812fe548ce7 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 16 Jul 2024 11:31:18 +0000 Subject: [PATCH 13/17] Remove an unnecessary impl --- compiler/rustc_middle/src/ty/structural_impls.rs | 6 ------ compiler/rustc_type_ir/src/visit.rs | 9 +++++++++ 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index 33c04b4111735..00ea87690c1ab 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -632,12 +632,6 @@ impl<'tcx> TypeVisitable> for InferConst { } } -impl<'tcx> TypeSuperVisitable> for ty::UnevaluatedConst<'tcx> { - fn super_visit_with>>(&self, visitor: &mut V) -> V::Result { - self.args.visit_with(visitor) - } -} - impl<'tcx> TypeVisitable> for TyAndLayout<'tcx, Ty<'tcx>> { fn visit_with>>(&self, visitor: &mut V) -> V::Result { visitor.visit_ty(self.ty) diff --git a/compiler/rustc_type_ir/src/visit.rs b/compiler/rustc_type_ir/src/visit.rs index d604199b8e06a..6ec38b78fc22a 100644 --- a/compiler/rustc_type_ir/src/visit.rs +++ b/compiler/rustc_type_ir/src/visit.rs @@ -447,6 +447,15 @@ impl TypeVisitor for HasTypeFlagsVisitor { ControlFlow::Continue(()) } } + + #[inline] + fn visit_error(&mut self, _guar: ::ErrorGuaranteed) -> Self::Result { + if self.flags.intersects(TypeFlags::HAS_ERROR) { + ControlFlow::Break(FoundFlags) + } else { + ControlFlow::Continue(()) + } + } } #[derive(Debug, PartialEq, Eq, Copy, Clone)] From 9a4c1058fac8cbbf771740928ec9a954b451c653 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 8 Jul 2024 09:48:12 +0000 Subject: [PATCH 14/17] Just store a span instead of the whole item --- compiler/rustc_ast_passes/src/ast_validation.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index dd0d904c52cc2..507329cc899f6 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -81,7 +81,7 @@ struct AstValidator<'a> { features: &'a Features, /// The span of the `extern` in an `extern { ... }` block, if any. - extern_mod: Option<&'a Item>, + extern_mod: Option, outer_trait_or_trait_impl: Option>, @@ -579,7 +579,7 @@ impl<'a> AstValidator<'a> { } fn current_extern_span(&self) -> Span { - self.session.source_map().guess_head_span(self.extern_mod.unwrap().span) + self.session.source_map().guess_head_span(self.extern_mod.unwrap()) } /// An `fn` in `extern { ... }` cannot have qualifiers, e.g. `async fn`. @@ -1080,7 +1080,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { } ItemKind::ForeignMod(ForeignMod { abi, safety, .. }) => { self.with_in_extern_mod(*safety, |this| { - let old_item = mem::replace(&mut this.extern_mod, Some(item)); + let old_item = mem::replace(&mut this.extern_mod, Some(item.span)); this.visibility_not_permitted( &item.vis, errors::VisibilityNotPermittedNote::IndividualForeignItems, From b879e29864c30d2bb2be2fffb910d66f0f4e9773 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 9 Jul 2024 08:54:11 +0000 Subject: [PATCH 15/17] Remove a needless borrow --- compiler/rustc_ast_passes/src/ast_validation.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index 507329cc899f6..45c6211598bec 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -61,12 +61,12 @@ enum DisallowTildeConstContext<'a> { Item, } -enum TraitOrTraitImpl<'a> { +enum TraitOrTraitImpl { Trait { span: Span, constness: Option }, - TraitImpl { constness: Const, polarity: ImplPolarity, trait_ref: &'a TraitRef }, + TraitImpl { constness: Const, polarity: ImplPolarity, trait_ref: Span }, } -impl<'a> TraitOrTraitImpl<'a> { +impl TraitOrTraitImpl { fn constness(&self) -> Option { match self { Self::Trait { constness: Some(span), .. } @@ -83,7 +83,7 @@ struct AstValidator<'a> { /// The span of the `extern` in an `extern { ... }` block, if any. extern_mod: Option, - outer_trait_or_trait_impl: Option>, + outer_trait_or_trait_impl: Option, has_proc_macro_decls: bool, @@ -115,7 +115,7 @@ impl<'a> AstValidator<'a> { trait_.map(|(constness, polarity, trait_ref)| TraitOrTraitImpl::TraitImpl { constness, polarity, - trait_ref, + trait_ref: trait_ref.path.span, }), ); f(self); @@ -354,7 +354,7 @@ impl<'a> AstValidator<'a> { } } - fn check_trait_fn_not_const(&self, constness: Const, parent: &TraitOrTraitImpl<'a>) { + fn check_trait_fn_not_const(&self, constness: Const, parent: &TraitOrTraitImpl) { let Const::Yes(span) = constness else { return; }; @@ -367,7 +367,7 @@ impl<'a> AstValidator<'a> { .. } = parent { - Some(trait_ref.path.span.shrink_to_lo()) + Some(trait_ref.shrink_to_lo()) } else { None }; From d9f959292464c7bd68672801a42113e5b6d262b8 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 9 Jul 2024 09:54:19 +0000 Subject: [PATCH 16/17] Remove a boilerplaty abstraction --- .../rustc_ast_passes/src/ast_validation.rs | 76 ++++--------------- compiler/rustc_ast_passes/src/errors.rs | 2 +- 2 files changed, 17 insertions(+), 61 deletions(-) diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index 45c6211598bec..e6cc2e4069b7e 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -38,7 +38,7 @@ use std::mem; use std::ops::{Deref, DerefMut}; use thin_vec::thin_vec; -use crate::errors; +use crate::errors::{self, TildeConstReason}; /// Is `self` allowed semantically as the first parameter in an `FnDecl`? enum SelfSemantic { @@ -46,21 +46,6 @@ enum SelfSemantic { No, } -/// What is the context that prevents using `~const`? -// FIXME(effects): Consider getting rid of this in favor of `errors::TildeConstReason`, they're -// almost identical. This gets rid of an abstraction layer which might be considered bad. -enum DisallowTildeConstContext<'a> { - TraitObject, - Fn(FnKind<'a>), - Trait(Span), - TraitImpl(Span), - Impl(Span), - TraitAssocTy(Span), - TraitImplAssocTy(Span), - InherentAssocTy(Span), - Item, -} - enum TraitOrTraitImpl { Trait { span: Span, constness: Option }, TraitImpl { constness: Const, polarity: ImplPolarity, trait_ref: Span }, @@ -92,7 +77,7 @@ struct AstValidator<'a> { /// e.g., `impl Iterator`. outer_impl_trait: Option, - disallow_tilde_const: Option>, + disallow_tilde_const: Option, /// Used to ban `impl Trait` in path projections like `::Item` /// or `Foo::Bar` @@ -145,7 +130,7 @@ impl<'a> AstValidator<'a> { fn with_tilde_const( &mut self, - disallowed: Option>, + disallowed: Option, f: impl FnOnce(&mut Self), ) { let old = mem::replace(&mut self.disallow_tilde_const, disallowed); @@ -224,7 +209,7 @@ impl<'a> AstValidator<'a> { } } TyKind::TraitObject(..) => self - .with_tilde_const(Some(DisallowTildeConstContext::TraitObject), |this| { + .with_tilde_const(Some(TildeConstReason::TraitObject), |this| { visit::walk_ty(this, t) }), TyKind::Path(qself, path) => { @@ -980,7 +965,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { this.visit_vis(&item.vis); this.visit_ident(item.ident); let disallowed = matches!(constness, Const::No) - .then(|| DisallowTildeConstContext::TraitImpl(item.span)); + .then(|| TildeConstReason::TraitImpl { span: item.span }); this.with_tilde_const(disallowed, |this| this.visit_generics(generics)); this.visit_trait_ref(t); this.visit_ty(self_ty); @@ -1035,7 +1020,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { this.visit_vis(&item.vis); this.visit_ident(item.ident); this.with_tilde_const( - Some(DisallowTildeConstContext::Impl(item.span)), + Some(TildeConstReason::Impl { span: item.span }), |this| this.visit_generics(generics), ); this.visit_ty(self_ty); @@ -1154,7 +1139,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { this.visit_ident(item.ident); let disallowed = is_const_trait .is_none() - .then(|| DisallowTildeConstContext::Trait(item.span)); + .then(|| TildeConstReason::Trait { span: item.span }); this.with_tilde_const(disallowed, |this| { this.visit_generics(generics); walk_list!(this, visit_param_bound, bounds, BoundKind::SuperTraits) @@ -1399,40 +1384,8 @@ impl<'a> Visitor<'a> for AstValidator<'a> { self.dcx().emit_err(errors::ConstBoundTraitObject { span: trait_ref.span }); } (_, BoundConstness::Maybe(span), BoundPolarity::Positive) - if let Some(reason) = &self.disallow_tilde_const => + if let Some(reason) = self.disallow_tilde_const => { - let reason = match reason { - DisallowTildeConstContext::Fn(FnKind::Closure(..)) => { - errors::TildeConstReason::Closure - } - DisallowTildeConstContext::Fn(FnKind::Fn(_, ident, ..)) => { - errors::TildeConstReason::Function { ident: ident.span } - } - &DisallowTildeConstContext::Trait(span) => { - errors::TildeConstReason::Trait { span } - } - &DisallowTildeConstContext::TraitImpl(span) => { - errors::TildeConstReason::TraitImpl { span } - } - &DisallowTildeConstContext::Impl(span) => { - // FIXME(effects): Consider providing a help message or even a structured - // suggestion for moving such bounds to the assoc const fns if available. - errors::TildeConstReason::Impl { span } - } - &DisallowTildeConstContext::TraitAssocTy(span) => { - errors::TildeConstReason::TraitAssocTy { span } - } - &DisallowTildeConstContext::TraitImplAssocTy(span) => { - errors::TildeConstReason::TraitImplAssocTy { span } - } - &DisallowTildeConstContext::InherentAssocTy(span) => { - errors::TildeConstReason::InherentAssocTy { span } - } - DisallowTildeConstContext::TraitObject => { - errors::TildeConstReason::TraitObject - } - DisallowTildeConstContext::Item => errors::TildeConstReason::Item, - }; self.dcx().emit_err(errors::TildeConstDisallowed { span, reason }); } ( @@ -1569,7 +1522,10 @@ impl<'a> Visitor<'a> for AstValidator<'a> { .and_then(TraitOrTraitImpl::constness) .is_some(); - let disallowed = (!tilde_const_allowed).then(|| DisallowTildeConstContext::Fn(fk)); + let disallowed = (!tilde_const_allowed).then(|| match fk { + FnKind::Fn(_, ident, _, _, _, _) => TildeConstReason::Function { ident: ident.span }, + FnKind::Closure(_, _, _) => TildeConstReason::Closure, + }); self.with_tilde_const(disallowed, |this| visit::walk_fn(this, fk)); } @@ -1664,12 +1620,12 @@ impl<'a> Visitor<'a> for AstValidator<'a> { AssocItemKind::Type(_) => { let disallowed = (!parent_is_const).then(|| match self.outer_trait_or_trait_impl { Some(TraitOrTraitImpl::Trait { .. }) => { - DisallowTildeConstContext::TraitAssocTy(item.span) + TildeConstReason::TraitAssocTy { span: item.span } } Some(TraitOrTraitImpl::TraitImpl { .. }) => { - DisallowTildeConstContext::TraitImplAssocTy(item.span) + TildeConstReason::TraitImplAssocTy { span: item.span } } - None => DisallowTildeConstContext::InherentAssocTy(item.span), + None => TildeConstReason::InherentAssocTy { span: item.span }, }); self.with_tilde_const(disallowed, |this| { this.with_in_trait_impl(None, |this| visit::walk_assoc_item(this, item, ctxt)) @@ -1852,7 +1808,7 @@ pub fn check_crate( outer_trait_or_trait_impl: None, has_proc_macro_decls: false, outer_impl_trait: None, - disallow_tilde_const: Some(DisallowTildeConstContext::Item), + disallow_tilde_const: Some(TildeConstReason::Item), is_impl_trait_banned: false, extern_mod_safety: None, lint_buffer: lints, diff --git a/compiler/rustc_ast_passes/src/errors.rs b/compiler/rustc_ast_passes/src/errors.rs index bfb9047645011..2c18b47f0f7f0 100644 --- a/compiler/rustc_ast_passes/src/errors.rs +++ b/compiler/rustc_ast_passes/src/errors.rs @@ -612,7 +612,7 @@ pub struct TildeConstDisallowed { pub reason: TildeConstReason, } -#[derive(Subdiagnostic)] +#[derive(Subdiagnostic, Copy, Clone)] pub enum TildeConstReason { #[note(ast_passes_closure)] Closure, From 117ff0a4fd11c5a71766ce76bf4b4467abd7ddf1 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 9 Jul 2024 11:22:09 +0000 Subject: [PATCH 17/17] Fix a bunch of sites that were walking instead of visiting, making it impossible for visitor impls to look at these values --- compiler/rustc_ast/src/mut_visit.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index 1c1163551db5f..39d0f2c7305f9 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -482,7 +482,7 @@ pub fn noop_visit_ty(ty: &mut P, vis: &mut T) { TyKind::Slice(ty) => vis.visit_ty(ty), TyKind::Ptr(mt) => vis.visit_mt(mt), TyKind::Ref(lt, mt) => { - visit_opt(lt, |lt| noop_visit_lifetime(lt, vis)); + visit_opt(lt, |lt| vis.visit_lifetime(lt)); vis.visit_mt(mt); } TyKind::BareFn(bft) => { @@ -925,7 +925,7 @@ pub fn noop_flat_map_generic_param( vis.visit_id(id); visit_attrs(attrs, vis); vis.visit_ident(ident); - visit_vec(bounds, |bound| noop_visit_param_bound(bound, vis)); + visit_vec(bounds, |bound| vis.visit_param_bound(bound)); match kind { GenericParamKind::Lifetime => {} GenericParamKind::Type { default } => { @@ -983,7 +983,7 @@ fn noop_visit_where_predicate(pred: &mut WherePredicate, vis: &mu } WherePredicate::RegionPredicate(rp) => { let WhereRegionPredicate { span, lifetime, bounds } = rp; - noop_visit_lifetime(lifetime, vis); + vis.visit_lifetime(lifetime); visit_vec(bounds, |bound| noop_visit_param_bound(bound, vis)); vis.visit_span(span); }