From bebaa8a29da776739f7d507d4e6a679656e687f2 Mon Sep 17 00:00:00 2001 From: binarycat Date: Wed, 9 Apr 2025 12:43:06 -0500 Subject: [PATCH 01/16] add sitemap to rust docs --- src/bootstrap/src/core/build_steps/dist.rs | 1 + src/doc/robots.txt | 2 ++ src/doc/sitemap.txt | 4 ++++ 3 files changed, 7 insertions(+) create mode 100644 src/doc/sitemap.txt diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs index 83f71aeed7204..6ec39ffc4366c 100644 --- a/src/bootstrap/src/core/build_steps/dist.rs +++ b/src/bootstrap/src/core/build_steps/dist.rs @@ -82,6 +82,7 @@ impl Step for Docs { tarball.set_product_name("Rust Documentation"); tarball.add_bulk_dir(builder.doc_out(host), dest); tarball.add_file(builder.src.join("src/doc/robots.txt"), dest, FileType::Regular); + tarball.add_file(builder.src.join("src/doc/sitemap.txt"), dest, FileType::Regular); Some(tarball.generate()) } } diff --git a/src/doc/robots.txt b/src/doc/robots.txt index 3a2552e9a159b..71a60f89c14c6 100644 --- a/src/doc/robots.txt +++ b/src/doc/robots.txt @@ -9,3 +9,5 @@ Disallow: /beta/book/first-edition/ Disallow: /beta/book/second-edition/ Disallow: /nightly/book/first-edition/ Disallow: /nightly/book/second-edition/ + +Sitemap: https://doc.rust-lang.org/sitemap.txt diff --git a/src/doc/sitemap.txt b/src/doc/sitemap.txt new file mode 100644 index 0000000000000..6e5f0fbad37f5 --- /dev/null +++ b/src/doc/sitemap.txt @@ -0,0 +1,4 @@ +https://doc.rust-lang.org/stable/ +https://doc.rust-lang.org/beta/ +https://doc.rust-lang.org/nightly/ + From 2ce6154b32c50b3588e0c58b6f106647a8831de8 Mon Sep 17 00:00:00 2001 From: Martin Nordholts Date: Sat, 30 Aug 2025 10:38:23 +0200 Subject: [PATCH 02/16] compiler: Include span of too huge array with `-Cdebuginfo=2` We have a few ui tests to ensure we emit an error if we encounter too big arrays. Before this fix, compiling the tests with `-Cdebuginfo=2` would not include the spans of the instantiation sites, because the error is then emitted from a different code path that does not include the span. Propagate the span to the error also in the debuginfo case, so the tests passes regardless of debuginfo level. --- compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs | 7 ++++--- compiler/rustc_codegen_llvm/src/type_of.rs | 7 ++++++- ....stderr => huge-array-simple-64.full-debuginfo.stderr} | 2 +- tests/ui/limits/huge-array-simple-64.no-debuginfo.stderr | 8 ++++++++ tests/ui/limits/huge-array-simple-64.rs | 5 +++++ ...huge-array.stderr => huge-array.full-debuginfo.stderr} | 2 +- tests/ui/limits/huge-array.no-debuginfo.stderr | 8 ++++++++ tests/ui/limits/huge-array.rs | 5 +++++ ...919-64.stderr => issue-15919-64.full-debuginfo.stderr} | 2 +- tests/ui/limits/issue-15919-64.no-debuginfo.stderr | 8 ++++++++ tests/ui/limits/issue-15919-64.rs | 5 +++++ 11 files changed, 52 insertions(+), 7 deletions(-) rename tests/ui/limits/{huge-array-simple-64.stderr => huge-array-simple-64.full-debuginfo.stderr} (83%) create mode 100644 tests/ui/limits/huge-array-simple-64.no-debuginfo.stderr rename tests/ui/limits/{huge-array.stderr => huge-array.full-debuginfo.stderr} (87%) create mode 100644 tests/ui/limits/huge-array.no-debuginfo.stderr rename tests/ui/limits/{issue-15919-64.stderr => issue-15919-64.full-debuginfo.stderr} (85%) create mode 100644 tests/ui/limits/issue-15919-64.no-debuginfo.stderr diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs index caa3369f413a8..1790e21225269 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs @@ -103,16 +103,17 @@ fn build_fixed_size_array_di_node<'ll, 'tcx>( cx: &CodegenCx<'ll, 'tcx>, unique_type_id: UniqueTypeId<'tcx>, array_type: Ty<'tcx>, + span: Span, ) -> DINodeCreationResult<'ll> { let ty::Array(element_type, len) = array_type.kind() else { bug!("build_fixed_size_array_di_node() called with non-ty::Array type `{:?}`", array_type) }; - let element_type_di_node = type_di_node(cx, *element_type); + let element_type_di_node = spanned_type_di_node(cx, *element_type, span); return_if_di_node_created_in_meantime!(cx, unique_type_id); - let (size, align) = cx.size_and_align_of(array_type); + let (size, align) = cx.spanned_size_and_align_of(array_type, span); let upper_bound = len .try_to_target_usize(cx.tcx) @@ -447,7 +448,7 @@ pub(crate) fn spanned_type_di_node<'ll, 'tcx>( build_basic_type_di_node(cx, t) } ty::Tuple(elements) if elements.is_empty() => build_basic_type_di_node(cx, t), - ty::Array(..) => build_fixed_size_array_di_node(cx, unique_type_id, t), + ty::Array(..) => build_fixed_size_array_di_node(cx, unique_type_id, t, span), ty::Slice(_) | ty::Str => build_slice_type_di_node(cx, t, unique_type_id), ty::Dynamic(..) => build_dyn_type_di_node(cx, t, unique_type_id), ty::Foreign(..) => build_foreign_type_di_node(cx, t, unique_type_id), diff --git a/compiler/rustc_codegen_llvm/src/type_of.rs b/compiler/rustc_codegen_llvm/src/type_of.rs index 4e7096da502d0..53218340414e5 100644 --- a/compiler/rustc_codegen_llvm/src/type_of.rs +++ b/compiler/rustc_codegen_llvm/src/type_of.rs @@ -7,6 +7,7 @@ use rustc_middle::bug; use rustc_middle::ty::layout::{LayoutOf, TyAndLayout}; use rustc_middle::ty::print::{with_no_trimmed_paths, with_no_visible_paths}; use rustc_middle::ty::{self, CoroutineArgsExt, Ty, TypeVisitableExt}; +use rustc_span::{DUMMY_SP, Span}; use tracing::debug; use crate::common::*; @@ -149,7 +150,11 @@ impl<'a, 'tcx> CodegenCx<'a, 'tcx> { } pub(crate) fn size_and_align_of(&self, ty: Ty<'tcx>) -> (Size, Align) { - let layout = self.layout_of(ty); + self.spanned_size_and_align_of(ty, DUMMY_SP) + } + + pub(crate) fn spanned_size_and_align_of(&self, ty: Ty<'tcx>, span: Span) -> (Size, Align) { + let layout = self.spanned_layout_of(ty, span); (layout.size, layout.align.abi) } } diff --git a/tests/ui/limits/huge-array-simple-64.stderr b/tests/ui/limits/huge-array-simple-64.full-debuginfo.stderr similarity index 83% rename from tests/ui/limits/huge-array-simple-64.stderr rename to tests/ui/limits/huge-array-simple-64.full-debuginfo.stderr index 46df288d4f78a..8ce93ab1884ea 100644 --- a/tests/ui/limits/huge-array-simple-64.stderr +++ b/tests/ui/limits/huge-array-simple-64.full-debuginfo.stderr @@ -1,5 +1,5 @@ error: values of the type `[u8; 2305843011361177600]` are too big for the target architecture - --> $DIR/huge-array-simple-64.rs:7:9 + --> $DIR/huge-array-simple-64.rs:12:9 | LL | let _fat: [u8; (1<<61)+(1<<31)] = | ^^^^ diff --git a/tests/ui/limits/huge-array-simple-64.no-debuginfo.stderr b/tests/ui/limits/huge-array-simple-64.no-debuginfo.stderr new file mode 100644 index 0000000000000..8ce93ab1884ea --- /dev/null +++ b/tests/ui/limits/huge-array-simple-64.no-debuginfo.stderr @@ -0,0 +1,8 @@ +error: values of the type `[u8; 2305843011361177600]` are too big for the target architecture + --> $DIR/huge-array-simple-64.rs:12:9 + | +LL | let _fat: [u8; (1<<61)+(1<<31)] = + | ^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/limits/huge-array-simple-64.rs b/tests/ui/limits/huge-array-simple-64.rs index d2838e0d41e70..0c000940062fc 100644 --- a/tests/ui/limits/huge-array-simple-64.rs +++ b/tests/ui/limits/huge-array-simple-64.rs @@ -1,3 +1,8 @@ +// FIXME(#61117): Remove revisions once x86_64-gnu-debug CI job sets rust.debuginfo-level-tests=2 +// NOTE: The .stderr for both revisions shall be identical. +//@ revisions: no-debuginfo full-debuginfo +//@[no-debuginfo] compile-flags: -Cdebuginfo=0 +//@[full-debuginfo] compile-flags: -Cdebuginfo=2 //@ build-fail //@ ignore-32bit diff --git a/tests/ui/limits/huge-array.stderr b/tests/ui/limits/huge-array.full-debuginfo.stderr similarity index 87% rename from tests/ui/limits/huge-array.stderr rename to tests/ui/limits/huge-array.full-debuginfo.stderr index ce0c0d650c2f8..0a9c8c67ce9a4 100644 --- a/tests/ui/limits/huge-array.stderr +++ b/tests/ui/limits/huge-array.full-debuginfo.stderr @@ -1,5 +1,5 @@ error: values of the type `[[u8; 1518599999]; 1518600000]` are too big for the target architecture - --> $DIR/huge-array.rs:4:9 + --> $DIR/huge-array.rs:9:9 | LL | let s: [T; 1518600000] = [t; 1518600000]; | ^ diff --git a/tests/ui/limits/huge-array.no-debuginfo.stderr b/tests/ui/limits/huge-array.no-debuginfo.stderr new file mode 100644 index 0000000000000..0a9c8c67ce9a4 --- /dev/null +++ b/tests/ui/limits/huge-array.no-debuginfo.stderr @@ -0,0 +1,8 @@ +error: values of the type `[[u8; 1518599999]; 1518600000]` are too big for the target architecture + --> $DIR/huge-array.rs:9:9 + | +LL | let s: [T; 1518600000] = [t; 1518600000]; + | ^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/limits/huge-array.rs b/tests/ui/limits/huge-array.rs index 97cfd1ff8fb2c..0cf5902769472 100644 --- a/tests/ui/limits/huge-array.rs +++ b/tests/ui/limits/huge-array.rs @@ -1,3 +1,8 @@ +// FIXME(#61117): Remove revisions once x86_64-gnu-debug CI job sets rust.debuginfo-level-tests=2 +// NOTE: The .stderr for both revisions shall be identical. +//@ revisions: no-debuginfo full-debuginfo +//@[no-debuginfo] compile-flags: -Cdebuginfo=0 +//@[full-debuginfo] compile-flags: -Cdebuginfo=2 //@ build-fail fn generic(t: T) { diff --git a/tests/ui/limits/issue-15919-64.stderr b/tests/ui/limits/issue-15919-64.full-debuginfo.stderr similarity index 85% rename from tests/ui/limits/issue-15919-64.stderr rename to tests/ui/limits/issue-15919-64.full-debuginfo.stderr index cd443f2065bbd..54434675d2506 100644 --- a/tests/ui/limits/issue-15919-64.stderr +++ b/tests/ui/limits/issue-15919-64.full-debuginfo.stderr @@ -1,5 +1,5 @@ error: values of the type `[usize; usize::MAX]` are too big for the target architecture - --> $DIR/issue-15919-64.rs:5:9 + --> $DIR/issue-15919-64.rs:10:9 | LL | let x = [0usize; 0xffff_ffff_ffff_ffff]; | ^ diff --git a/tests/ui/limits/issue-15919-64.no-debuginfo.stderr b/tests/ui/limits/issue-15919-64.no-debuginfo.stderr new file mode 100644 index 0000000000000..54434675d2506 --- /dev/null +++ b/tests/ui/limits/issue-15919-64.no-debuginfo.stderr @@ -0,0 +1,8 @@ +error: values of the type `[usize; usize::MAX]` are too big for the target architecture + --> $DIR/issue-15919-64.rs:10:9 + | +LL | let x = [0usize; 0xffff_ffff_ffff_ffff]; + | ^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/limits/issue-15919-64.rs b/tests/ui/limits/issue-15919-64.rs index 7e6200882a966..c1eee1d95ba17 100644 --- a/tests/ui/limits/issue-15919-64.rs +++ b/tests/ui/limits/issue-15919-64.rs @@ -1,3 +1,8 @@ +// FIXME(#61117): Remove revisions once x86_64-gnu-debug CI job sets rust.debuginfo-level-tests=2 +// NOTE: The .stderr for both revisions shall be identical. +//@ revisions: no-debuginfo full-debuginfo +//@[no-debuginfo] compile-flags: -Cdebuginfo=0 +//@[full-debuginfo] compile-flags: -Cdebuginfo=2 //@ build-fail //@ ignore-32bit From 4fec3aa2a4e087c981a083dca59e7434cac52625 Mon Sep 17 00:00:00 2001 From: Daniel Paoliello Date: Wed, 3 Sep 2025 16:59:03 -0700 Subject: [PATCH 03/16] In the rustc_llvm build script, don't consider arm64* to be 32-bit --- compiler/rustc_llvm/build.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_llvm/build.rs b/compiler/rustc_llvm/build.rs index d01f79dcade0b..804f46374d570 100644 --- a/compiler/rustc_llvm/build.rs +++ b/compiler/rustc_llvm/build.rs @@ -254,7 +254,10 @@ fn main() { println!("cargo:rustc-link-lib=kstat"); } - if (target.starts_with("arm") && !target.contains("freebsd") && !target.contains("ohos")) + if (target.starts_with("arm") + && !target.starts_with("arm64") + && !target.contains("freebsd") + && !target.contains("ohos")) || target.starts_with("mips-") || target.starts_with("mipsel-") || target.starts_with("powerpc-") From 02602ef65125ac743cc0a61c5afe7c0c5acbad56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gabriel=20Bj=C3=B8rnager=20Jensen?= Date: Sun, 7 Sep 2025 18:01:39 +0200 Subject: [PATCH 04/16] Implement 'Sum' and 'Product' for 'f16' and 'f128'; --- library/core/src/iter/traits/accum.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/iter/traits/accum.rs b/library/core/src/iter/traits/accum.rs index 73122369b41dd..3b805139ded17 100644 --- a/library/core/src/iter/traits/accum.rs +++ b/library/core/src/iter/traits/accum.rs @@ -203,7 +203,7 @@ macro_rules! float_sum_product { integer_sum_product! { i8 i16 i32 i64 i128 isize u8 u16 u32 u64 u128 usize } saturating_integer_sum_product! { u8 u16 u32 u64 u128 usize } -float_sum_product! { f32 f64 } +float_sum_product! { f16 f32 f64 f128 } #[stable(feature = "iter_arith_traits_result", since = "1.16.0")] impl Sum> for Result From aed0ed4c93d661fc7b66dc4a39690948476e8a4a Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 8 Sep 2025 10:40:18 +0200 Subject: [PATCH 05/16] const-eval: disable pointer fragment support --- .../rustc_const_eval/src/interpret/memory.rs | 6 ++- .../src/mir/interpret/allocation.rs | 5 +++ .../interpret/allocation/provenance_map.rs | 16 +++++++- library/core/src/ptr/mod.rs | 38 ++++++++++++++++++- library/coretests/tests/ptr.rs | 9 +++-- tests/ui/consts/const-eval/ptr_fragments.rs | 1 + .../const-eval/ptr_fragments_in_final.rs | 1 + .../consts/const-eval/ptr_fragments_mixed.rs | 28 ++++++++++++++ .../const-eval/ptr_fragments_mixed.stderr | 23 +++++++++++ .../ui/consts/const-eval/read_partial_ptr.rs | 1 + 10 files changed, 119 insertions(+), 9 deletions(-) create mode 100644 tests/ui/consts/const-eval/ptr_fragments_mixed.rs create mode 100644 tests/ui/consts/const-eval/ptr_fragments_mixed.stderr diff --git a/compiler/rustc_const_eval/src/interpret/memory.rs b/compiler/rustc_const_eval/src/interpret/memory.rs index 2c1e5087e1c6b..6ec85648d6d88 100644 --- a/compiler/rustc_const_eval/src/interpret/memory.rs +++ b/compiler/rustc_const_eval/src/interpret/memory.rs @@ -1501,8 +1501,10 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { // `get_bytes_mut` will clear the provenance, which is correct, // since we don't want to keep any provenance at the target. // This will also error if copying partial provenance is not supported. - let provenance = - src_alloc.provenance().prepare_copy(src_range, dest_offset, num_copies, self); + let provenance = src_alloc + .provenance() + .prepare_copy(src_range, dest_offset, num_copies, self) + .map_err(|e| e.to_interp_error(src_alloc_id))?; // Prepare a copy of the initialization mask. let init = src_alloc.init_mask().prepare_copy(src_range); diff --git a/compiler/rustc_middle/src/mir/interpret/allocation.rs b/compiler/rustc_middle/src/mir/interpret/allocation.rs index 2ea92a39d4828..67962813ae437 100644 --- a/compiler/rustc_middle/src/mir/interpret/allocation.rs +++ b/compiler/rustc_middle/src/mir/interpret/allocation.rs @@ -724,6 +724,11 @@ impl Allocation } // If we get here, we have to check per-byte provenance, and join them together. let prov = 'prov: { + if !Prov::OFFSET_IS_ADDR { + // FIXME(#146291): We need to ensure that we don't mix different pointers with + // the same provenance. + return Err(AllocError::ReadPartialPointer(range.start)); + } // Initialize with first fragment. Must have index 0. let Some((mut joint_prov, 0)) = self.provenance.get_byte(range.start, cx) else { break 'prov None; diff --git a/compiler/rustc_middle/src/mir/interpret/allocation/provenance_map.rs b/compiler/rustc_middle/src/mir/interpret/allocation/provenance_map.rs index dbbd95408c8ab..720e58d7aa0eb 100644 --- a/compiler/rustc_middle/src/mir/interpret/allocation/provenance_map.rs +++ b/compiler/rustc_middle/src/mir/interpret/allocation/provenance_map.rs @@ -11,6 +11,7 @@ use rustc_serialize::{Decodable, Decoder, Encodable, Encoder}; use tracing::trace; use super::{AllocRange, CtfeProvenance, Provenance, alloc_range}; +use crate::mir::interpret::{AllocError, AllocResult}; /// Stores the provenance information of pointers stored in memory. #[derive(Clone, PartialEq, Eq, Hash, Debug)] @@ -137,6 +138,11 @@ impl ProvenanceMap { let Some(bytes) = self.bytes.as_deref_mut() else { return true; }; + if !Prov::OFFSET_IS_ADDR { + // FIXME(#146291): We need to ensure that we don't mix different pointers with + // the same provenance. + return false; + } let ptr_size = cx.data_layout().pointer_size(); while let Some((offset, (prov, _))) = bytes.iter().next().copied() { // Check if this fragment starts a pointer. @@ -285,7 +291,7 @@ impl ProvenanceMap { dest: Size, count: u64, cx: &impl HasDataLayout, - ) -> ProvenanceCopy { + ) -> AllocResult> { let shift_offset = move |idx, offset| { // compute offset for current repetition let dest_offset = dest + src.size * idx; // `Size` operations @@ -363,6 +369,12 @@ impl ProvenanceMap { } trace!("byte provenances: {bytes:?}"); + if !bytes.is_empty() && !Prov::OFFSET_IS_ADDR { + // FIXME(#146291): We need to ensure that we don't mix different pointers with + // the same provenance. + return Err(AllocError::ReadPartialPointer(src.start)); + } + // And again a buffer for the new list on the target side. let mut dest_bytes = Vec::with_capacity(bytes.len() * (count as usize)); for i in 0..count { @@ -373,7 +385,7 @@ impl ProvenanceMap { dest_bytes_box = Some(dest_bytes.into_boxed_slice()); } - ProvenanceCopy { dest_ptrs: dest_ptrs_box, dest_bytes: dest_bytes_box } + Ok(ProvenanceCopy { dest_ptrs: dest_ptrs_box, dest_bytes: dest_bytes_box }) } /// Applies a provenance copy. diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs index 6b94088cb5679..625024373ef47 100644 --- a/library/core/src/ptr/mod.rs +++ b/library/core/src/ptr/mod.rs @@ -1348,6 +1348,40 @@ pub const unsafe fn swap(x: *mut T, y: *mut T) { /// assert_eq!(x, [7, 8, 3, 4]); /// assert_eq!(y, [1, 2, 9]); /// ``` +/// +/// # Const evaluation limitations +/// +/// If this function is invoked during const-evaluation, the current implementation has a small (and +/// rarely relevant) limitation: if `count` is at least 2 and the data pointed to by `x` or `y` +/// contains a pointer that crosses the boundary of two `T`-sized chunks of memory, the function may +/// fail to evaluate (similar to a panic during const-evaluation). This behavior may change in the +/// future. +/// +/// The limitation is illustrated by the following example: +/// +/// ``` +/// use std::mem::size_of; +/// use std::ptr; +/// +/// const { unsafe { +/// const PTR_SIZE: usize = size_of::<*const i32>(); +/// let mut data1 = [0u8; PTR_SIZE]; +/// let mut data2 = [0u8; PTR_SIZE]; +/// // Store a pointer in `data1`. +/// data1.as_mut_ptr().cast::<*const i32>().write_unaligned(&42); +/// // Swap the contents of `data1` and `data2` by swapping `PTR_SIZE` many `u8`-sized chunks. +/// // This call will fail, because the pointer in `data1` crosses the boundary +/// // between several of the 1-byte chunks that are being swapped here. +/// //ptr::swap_nonoverlapping(data1.as_mut_ptr(), data2.as_mut_ptr(), PTR_SIZE); +/// // Swap the contents of `data1` and `data2` by swapping a single chunk of size +/// // `[u8; PTR_SIZE]`. That works, as there is no pointer crossing the boundary between +/// // two chunks. +/// ptr::swap_nonoverlapping(&mut data1, &mut data2, 1); +/// // Read the pointer from `data2` and dereference it. +/// let ptr = data2.as_ptr().cast::<*const i32>().read_unaligned(); +/// assert!(*ptr == 42); +/// } } +/// ``` #[inline] #[stable(feature = "swap_nonoverlapping", since = "1.27.0")] #[rustc_const_stable(feature = "const_swap_nonoverlapping", since = "1.88.0")] @@ -1376,7 +1410,9 @@ pub const unsafe fn swap_nonoverlapping(x: *mut T, y: *mut T, count: usize) { const_eval_select!( @capture[T] { x: *mut T, y: *mut T, count: usize }: if const { - // At compile-time we don't need all the special code below. + // At compile-time we want to always copy this in chunks of `T`, to ensure that if there + // are pointers inside `T` we will copy them in one go rather than trying to copy a part + // of a pointer (which would not work). // SAFETY: Same preconditions as this function unsafe { swap_nonoverlapping_const(x, y, count) } } else { diff --git a/library/coretests/tests/ptr.rs b/library/coretests/tests/ptr.rs index c13fb96a67f92..f8774833d0a54 100644 --- a/library/coretests/tests/ptr.rs +++ b/library/coretests/tests/ptr.rs @@ -936,12 +936,13 @@ fn test_const_swap_ptr() { assert!(*s1.0.ptr == 666); assert!(*s2.0.ptr == 1); - // Swap them back, byte-for-byte + // Swap them back, again as an array. + // FIXME(#146291): we should be swapping back at type `u8` but that currently does not work. unsafe { ptr::swap_nonoverlapping( - ptr::from_mut(&mut s1).cast::(), - ptr::from_mut(&mut s2).cast::(), - size_of::(), + ptr::from_mut(&mut s1).cast::(), + ptr::from_mut(&mut s2).cast::(), + 1, ); } diff --git a/tests/ui/consts/const-eval/ptr_fragments.rs b/tests/ui/consts/const-eval/ptr_fragments.rs index 04dcbe55590e9..7dc5870f89e2b 100644 --- a/tests/ui/consts/const-eval/ptr_fragments.rs +++ b/tests/ui/consts/const-eval/ptr_fragments.rs @@ -1,5 +1,6 @@ //! Test that various operations involving pointer fragments work as expected. //@ run-pass +//@ ignore-test: disabled due to use std::mem::{self, MaybeUninit, transmute}; use std::ptr; diff --git a/tests/ui/consts/const-eval/ptr_fragments_in_final.rs b/tests/ui/consts/const-eval/ptr_fragments_in_final.rs index e2f3f51b08638..aed33d7ed8d31 100644 --- a/tests/ui/consts/const-eval/ptr_fragments_in_final.rs +++ b/tests/ui/consts/const-eval/ptr_fragments_in_final.rs @@ -1,4 +1,5 @@ //! Test that we properly error when there is a pointer fragment in the final value. +//@ ignore-test: disabled due to use std::{mem::{self, MaybeUninit}, ptr}; diff --git a/tests/ui/consts/const-eval/ptr_fragments_mixed.rs b/tests/ui/consts/const-eval/ptr_fragments_mixed.rs new file mode 100644 index 0000000000000..79a42820f501e --- /dev/null +++ b/tests/ui/consts/const-eval/ptr_fragments_mixed.rs @@ -0,0 +1,28 @@ +//! This mixes fragments from different pointers to the same allocarion, in a way +//! that we should not accept. See . +static A: u8 = 123; + +const HALF_PTR: usize = std::mem::size_of::<*const ()>() / 2; + +const fn mix_ptr() -> *const u8 { + unsafe { + let x: *const u8 = &raw const A; + let mut y = x.wrapping_add(usize::MAX / 4); + core::ptr::copy_nonoverlapping( + (&raw const x).cast::(), + (&raw mut y).cast::(), + HALF_PTR, + ); + y + } +} + +const APTR: *const u8 = mix_ptr(); //~ERROR: unable to read parts of a pointer + +fn main() { + let a = APTR; + println!("{a:p}"); + let b = mix_ptr(); + println!("{b:p}"); + assert_eq!(a, b); +} diff --git a/tests/ui/consts/const-eval/ptr_fragments_mixed.stderr b/tests/ui/consts/const-eval/ptr_fragments_mixed.stderr new file mode 100644 index 0000000000000..9e991ab7a7d38 --- /dev/null +++ b/tests/ui/consts/const-eval/ptr_fragments_mixed.stderr @@ -0,0 +1,23 @@ +error[E0080]: unable to read parts of a pointer from memory at ALLOC0 + --> $DIR/ptr_fragments_mixed.rs:20:25 + | +LL | const APTR: *const u8 = mix_ptr(); + | ^^^^^^^^^ evaluation of `APTR` failed inside this call + | + = help: this code performed an operation that depends on the underlying bytes representing a pointer + = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported +note: inside `mix_ptr` + --> $DIR/ptr_fragments_mixed.rs:11:9 + | +LL | / core::ptr::copy_nonoverlapping( +LL | | (&raw const x).cast::(), +LL | | (&raw mut y).cast::(), +LL | | HALF_PTR, +LL | | ); + | |_________^ +note: inside `std::ptr::copy_nonoverlapping::` + --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/consts/const-eval/read_partial_ptr.rs b/tests/ui/consts/const-eval/read_partial_ptr.rs index bccef9c0bc6ca..c153e274e41f6 100644 --- a/tests/ui/consts/const-eval/read_partial_ptr.rs +++ b/tests/ui/consts/const-eval/read_partial_ptr.rs @@ -1,4 +1,5 @@ //! Ensure we error when trying to load from a pointer whose provenance has been messed with. +//@ ignore-test: disabled due to const PARTIAL_OVERWRITE: () = { let mut p = &42; From edc94e61841506c6957e1ee0ed57a2232fe339c4 Mon Sep 17 00:00:00 2001 From: cyrgani Date: Sun, 7 Sep 2025 23:20:40 +0200 Subject: [PATCH 06/16] mark `format_args_nl!` as `#[doc(hidden)]` --- library/core/src/macros/mod.rs | 1 + src/librustdoc/html/highlight.rs | 2 +- src/librustdoc/lib.rs | 1 - 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/library/core/src/macros/mod.rs b/library/core/src/macros/mod.rs index ccf41dfb01dd1..3f58fc448aa68 100644 --- a/library/core/src/macros/mod.rs +++ b/library/core/src/macros/mod.rs @@ -1017,6 +1017,7 @@ pub(crate) mod builtin { )] #[allow_internal_unstable(fmt_internals)] #[rustc_builtin_macro] + #[doc(hidden)] #[macro_export] macro_rules! format_args_nl { ($fmt:expr) => {{ /* compiler built-in */ }}; diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs index feafb41dc9905..0e06361024b9f 100644 --- a/src/librustdoc/html/highlight.rs +++ b/src/librustdoc/html/highlight.rs @@ -578,7 +578,7 @@ pub(super) fn write_code( } fn write_footer(out: &mut String, playground_button: Option<&str>) { - write_str(out, format_args_nl!("{}", playground_button.unwrap_or_default())); + write_str(out, format_args!("{}", playground_button.unwrap_or_default())); } /// How a span of text is classified. Mostly corresponds to token kinds. diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index f62eba4b3c195..9871066b9eb51 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -10,7 +10,6 @@ #![feature(box_patterns)] #![feature(debug_closure_helpers)] #![feature(file_buffered)] -#![feature(format_args_nl)] #![feature(if_let_guard)] #![feature(iter_advance_by)] #![feature(iter_intersperse)] From f7dbd752fd9abcd419ee6bdf1cccd5e806e2d6e7 Mon Sep 17 00:00:00 2001 From: rustbot <47979223+rustbot@users.noreply.github.com> Date: Mon, 8 Sep 2025 19:01:31 +0200 Subject: [PATCH 07/16] Update books --- src/doc/nomicon | 2 +- src/doc/reference | 2 +- src/doc/rust-by-example | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/doc/nomicon b/src/doc/nomicon index 57ed447366056..f17a018b99894 160000 --- a/src/doc/nomicon +++ b/src/doc/nomicon @@ -1 +1 @@ -Subproject commit 57ed4473660565d9357fcae176b358d7e8724ebf +Subproject commit f17a018b9989430967d1c58e9a12c51169abc744 diff --git a/src/doc/reference b/src/doc/reference index 89f67b3c1b904..b3ce60628c6f5 160000 --- a/src/doc/reference +++ b/src/doc/reference @@ -1 +1 @@ -Subproject commit 89f67b3c1b904cbcd9ed55e443d6fc67c8ca2769 +Subproject commit b3ce60628c6f55ab8ff3dba9f3d20203df1c0dee diff --git a/src/doc/rust-by-example b/src/doc/rust-by-example index ad27f82c18464..dd26bc8e726dc 160000 --- a/src/doc/rust-by-example +++ b/src/doc/rust-by-example @@ -1 +1 @@ -Subproject commit ad27f82c18464525c761a4a8db2e01785da59e1f +Subproject commit dd26bc8e726dc2e73534c8972d4dccd1bed7495f From 8b58777968a4c663d6c1293bacff6da99e6e5203 Mon Sep 17 00:00:00 2001 From: nixxo Date: Thu, 4 Sep 2025 09:33:11 +0200 Subject: [PATCH 08/16] fix partial urlencoded link support - added full urlencoding to properly check urlencoded anchor links against non-urlencoded heading IDs - added tests urlecoding provided by https://crates.io/crates/urlencoding --- Cargo.lock | 7 +++++++ src/tools/linkchecker/Cargo.toml | 1 + src/tools/linkchecker/main.rs | 13 +------------ src/tools/linkchecker/tests/valid/inner/bar.html | 3 +++ src/tools/linkchecker/tests/valid/inner/foo.html | 8 ++++++++ .../linkchecker/tests/valid/inner/redir-target.html | 3 +++ 6 files changed, 23 insertions(+), 12 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 52f5048115753..fd4b661c40de7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2167,6 +2167,7 @@ version = "0.1.0" dependencies = [ "html5ever", "regex", + "urlencoding", ] [[package]] @@ -5825,6 +5826,12 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "urlencoding" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" + [[package]] name = "utf-8" version = "0.7.6" diff --git a/src/tools/linkchecker/Cargo.toml b/src/tools/linkchecker/Cargo.toml index fb5bff3fe63ff..f0886e31b243f 100644 --- a/src/tools/linkchecker/Cargo.toml +++ b/src/tools/linkchecker/Cargo.toml @@ -10,3 +10,4 @@ path = "main.rs" [dependencies] regex = "1" html5ever = "0.29.0" +urlencoding = "2.1.3" diff --git a/src/tools/linkchecker/main.rs b/src/tools/linkchecker/main.rs index 1dc45728c90cd..e07a0784cdb3a 100644 --- a/src/tools/linkchecker/main.rs +++ b/src/tools/linkchecker/main.rs @@ -232,18 +232,7 @@ enum FileEntry { type Cache = HashMap; fn small_url_encode(s: &str) -> String { - s.replace('<', "%3C") - .replace('>', "%3E") - .replace(' ', "%20") - .replace('?', "%3F") - .replace('\'', "%27") - .replace('&', "%26") - .replace(',', "%2C") - .replace(':', "%3A") - .replace(';', "%3B") - .replace('[', "%5B") - .replace(']', "%5D") - .replace('\"', "%22") + urlencoding::encode(s).to_string() } impl Checker { diff --git a/src/tools/linkchecker/tests/valid/inner/bar.html b/src/tools/linkchecker/tests/valid/inner/bar.html index 4b500d78b76e4..6ffda259c40eb 100644 --- a/src/tools/linkchecker/tests/valid/inner/bar.html +++ b/src/tools/linkchecker/tests/valid/inner/bar.html @@ -3,5 +3,8 @@

Bar

+ +

Bar

+ diff --git a/src/tools/linkchecker/tests/valid/inner/foo.html b/src/tools/linkchecker/tests/valid/inner/foo.html index 3c6a7483bcd46..f30bf71820519 100644 --- a/src/tools/linkchecker/tests/valid/inner/foo.html +++ b/src/tools/linkchecker/tests/valid/inner/foo.html @@ -8,7 +8,15 @@
external links not validated Redirect + + + + +

Local

+ +

Local

+ diff --git a/src/tools/linkchecker/tests/valid/inner/redir-target.html b/src/tools/linkchecker/tests/valid/inner/redir-target.html index bd59884a01ecf..ac1dec6d5b4aa 100644 --- a/src/tools/linkchecker/tests/valid/inner/redir-target.html +++ b/src/tools/linkchecker/tests/valid/inner/redir-target.html @@ -1,5 +1,8 @@

Redir

+ + +

Redir

From d51f0ea172290f2e99e98a061c326af12edfbd3c Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Mon, 8 Sep 2025 19:06:24 +0200 Subject: [PATCH 09/16] Reorder test to make failures clearer --- library/std/src/sys/platform_version/darwin/tests.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/library/std/src/sys/platform_version/darwin/tests.rs b/library/std/src/sys/platform_version/darwin/tests.rs index 76dc4482c9835..eecd58ec79e35 100644 --- a/library/std/src/sys/platform_version/darwin/tests.rs +++ b/library/std/src/sys/platform_version/darwin/tests.rs @@ -28,6 +28,9 @@ fn compare_against_sw_vers() { let subminor: i32 = sw_vers.next().unwrap_or("0").parse().unwrap(); assert_eq!(sw_vers.count(), 0); + // Test directly against the lookup + assert_eq!(lookup_version().get(), pack_os_version(major as _, minor as _, subminor as _)); + // Current version is available assert_eq!(__isOSVersionAtLeast(major, minor, subminor), 1); @@ -40,9 +43,6 @@ fn compare_against_sw_vers() { assert_eq!(__isOSVersionAtLeast(major, minor, subminor + 1), 0); assert_eq!(__isOSVersionAtLeast(major, minor + 1, subminor), 0); assert_eq!(__isOSVersionAtLeast(major + 1, minor, subminor), 0); - - // Test directly against the lookup - assert_eq!(lookup_version().get(), pack_os_version(major as _, minor as _, subminor as _)); } #[test] From fe6f8cc6f5eef1e0dc5e51ca621b32208af0da3c Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Mon, 8 Sep 2025 20:10:08 +0200 Subject: [PATCH 10/16] Weakly export platform_version symbols The symbols __isPlatformVersionAtLeast and __isOSVersionAtLeast. This allows the user to link both compiler_rt and std. --- library/std/src/sys/platform_version/darwin/public_extern.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/library/std/src/sys/platform_version/darwin/public_extern.rs b/library/std/src/sys/platform_version/darwin/public_extern.rs index 967cdb4920fd4..c0848d94798f2 100644 --- a/library/std/src/sys/platform_version/darwin/public_extern.rs +++ b/library/std/src/sys/platform_version/darwin/public_extern.rs @@ -77,6 +77,10 @@ use super::{current_version, pack_i32_os_version}; // NOTE: This symbol has a workaround in the compiler's symbol mangling to avoid mangling it, while // still not exposing it from non-cdylib (like `#[no_mangle]` would). #[rustc_std_internal_symbol] +// NOTE: Making this a weak symbol might not be entirely the right solution for this, `compiler_rt` +// doesn't do that, it instead makes the symbol have "hidden" visibility. But since this is placed +// in `libstd`, which might be used as a dylib, we cannot do the same here. +#[linkage = "weak"] // extern "C" is correct, Clang assumes the function cannot unwind: // https://github.com/llvm/llvm-project/blob/llvmorg-20.1.0/clang/lib/CodeGen/CGObjC.cpp#L3980 // @@ -145,6 +149,7 @@ pub(super) extern "C" fn __isPlatformVersionAtLeast( /// Old entry point for availability. Used when compiling with older Clang versions. // SAFETY: Same as for `__isPlatformVersionAtLeast`. #[rustc_std_internal_symbol] +#[linkage = "weak"] pub(super) extern "C" fn __isOSVersionAtLeast(major: i32, minor: i32, subminor: i32) -> i32 { let version = pack_i32_os_version(major, minor, subminor); (version <= current_version()) as i32 From 9899ab3fa4559461c1ddae641565995acf9c2223 Mon Sep 17 00:00:00 2001 From: cyrgani Date: Mon, 8 Sep 2025 21:21:55 +0200 Subject: [PATCH 11/16] simplify the declaration of the legacy integer modules (`std::u32` etc.) --- library/core/src/lib.rs | 51 +++---------- library/core/src/num/shells/i128.rs | 11 --- library/core/src/num/shells/i16.rs | 11 --- library/core/src/num/shells/i32.rs | 11 --- library/core/src/num/shells/i64.rs | 11 --- library/core/src/num/shells/i8.rs | 11 --- library/core/src/num/shells/int_macros.rs | 46 ------------ library/core/src/num/shells/isize.rs | 11 --- .../core/src/num/shells/legacy_int_modules.rs | 71 +++++++++++++++++++ library/core/src/num/shells/u128.rs | 11 --- library/core/src/num/shells/u16.rs | 11 --- library/core/src/num/shells/u32.rs | 11 --- library/core/src/num/shells/u64.rs | 11 --- library/core/src/num/shells/u8.rs | 11 --- library/core/src/num/shells/usize.rs | 11 --- 15 files changed, 81 insertions(+), 219 deletions(-) delete mode 100644 library/core/src/num/shells/i128.rs delete mode 100644 library/core/src/num/shells/i16.rs delete mode 100644 library/core/src/num/shells/i32.rs delete mode 100644 library/core/src/num/shells/i64.rs delete mode 100644 library/core/src/num/shells/i8.rs delete mode 100644 library/core/src/num/shells/int_macros.rs delete mode 100644 library/core/src/num/shells/isize.rs create mode 100644 library/core/src/num/shells/legacy_int_modules.rs delete mode 100644 library/core/src/num/shells/u128.rs delete mode 100644 library/core/src/num/shells/u16.rs delete mode 100644 library/core/src/num/shells/u32.rs delete mode 100644 library/core/src/num/shells/u64.rs delete mode 100644 library/core/src/num/shells/u8.rs delete mode 100644 library/core/src/num/shells/usize.rs diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index c306011bdda39..86a68e18b0af4 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -252,47 +252,16 @@ pub use crate::macros::cfg_select; #[macro_use] mod internal_macros; -#[path = "num/shells/int_macros.rs"] -#[macro_use] -mod int_macros; - -#[rustc_diagnostic_item = "i128_legacy_mod"] -#[path = "num/shells/i128.rs"] -pub mod i128; -#[rustc_diagnostic_item = "i16_legacy_mod"] -#[path = "num/shells/i16.rs"] -pub mod i16; -#[rustc_diagnostic_item = "i32_legacy_mod"] -#[path = "num/shells/i32.rs"] -pub mod i32; -#[rustc_diagnostic_item = "i64_legacy_mod"] -#[path = "num/shells/i64.rs"] -pub mod i64; -#[rustc_diagnostic_item = "i8_legacy_mod"] -#[path = "num/shells/i8.rs"] -pub mod i8; -#[rustc_diagnostic_item = "isize_legacy_mod"] -#[path = "num/shells/isize.rs"] -pub mod isize; - -#[rustc_diagnostic_item = "u128_legacy_mod"] -#[path = "num/shells/u128.rs"] -pub mod u128; -#[rustc_diagnostic_item = "u16_legacy_mod"] -#[path = "num/shells/u16.rs"] -pub mod u16; -#[rustc_diagnostic_item = "u32_legacy_mod"] -#[path = "num/shells/u32.rs"] -pub mod u32; -#[rustc_diagnostic_item = "u64_legacy_mod"] -#[path = "num/shells/u64.rs"] -pub mod u64; -#[rustc_diagnostic_item = "u8_legacy_mod"] -#[path = "num/shells/u8.rs"] -pub mod u8; -#[rustc_diagnostic_item = "usize_legacy_mod"] -#[path = "num/shells/usize.rs"] -pub mod usize; +#[path = "num/shells/legacy_int_modules.rs"] +mod legacy_int_modules; +#[stable(feature = "rust1", since = "1.0.0")] +#[allow(clippy::useless_attribute)] // FIXME false positive (https://github.com/rust-lang/rust-clippy/issues/15636) +#[allow(deprecated_in_future)] +pub use legacy_int_modules::{i8, i16, i32, i64, isize, u8, u16, u32, u64, usize}; +#[stable(feature = "i128", since = "1.26.0")] +#[allow(clippy::useless_attribute)] // FIXME false positive (https://github.com/rust-lang/rust-clippy/issues/15636) +#[allow(deprecated_in_future)] +pub use legacy_int_modules::{i128, u128}; #[path = "num/f128.rs"] pub mod f128; diff --git a/library/core/src/num/shells/i128.rs b/library/core/src/num/shells/i128.rs deleted file mode 100644 index b3b3d3b4875ab..0000000000000 --- a/library/core/src/num/shells/i128.rs +++ /dev/null @@ -1,11 +0,0 @@ -//! Redundant constants module for the [`i128` primitive type][i128]. -//! -//! New code should use the associated constants directly on the primitive type. - -#![stable(feature = "i128", since = "1.26.0")] -#![deprecated( - since = "TBD", - note = "all constants in this module replaced by associated constants on `i128`" -)] - -int_module! { i128, #[stable(feature = "i128", since="1.26.0")] } diff --git a/library/core/src/num/shells/i16.rs b/library/core/src/num/shells/i16.rs deleted file mode 100644 index 70a452e193983..0000000000000 --- a/library/core/src/num/shells/i16.rs +++ /dev/null @@ -1,11 +0,0 @@ -//! Redundant constants module for the [`i16` primitive type][i16]. -//! -//! New code should use the associated constants directly on the primitive type. - -#![stable(feature = "rust1", since = "1.0.0")] -#![deprecated( - since = "TBD", - note = "all constants in this module replaced by associated constants on `i16`" -)] - -int_module! { i16 } diff --git a/library/core/src/num/shells/i32.rs b/library/core/src/num/shells/i32.rs deleted file mode 100644 index c30849e2591c3..0000000000000 --- a/library/core/src/num/shells/i32.rs +++ /dev/null @@ -1,11 +0,0 @@ -//! Redundant constants module for the [`i32` primitive type][i32]. -//! -//! New code should use the associated constants directly on the primitive type. - -#![stable(feature = "rust1", since = "1.0.0")] -#![deprecated( - since = "TBD", - note = "all constants in this module replaced by associated constants on `i32`" -)] - -int_module! { i32 } diff --git a/library/core/src/num/shells/i64.rs b/library/core/src/num/shells/i64.rs deleted file mode 100644 index 77d95d712506b..0000000000000 --- a/library/core/src/num/shells/i64.rs +++ /dev/null @@ -1,11 +0,0 @@ -//! Redundant constants module for the [`i64` primitive type][i64]. -//! -//! New code should use the associated constants directly on the primitive type. - -#![stable(feature = "rust1", since = "1.0.0")] -#![deprecated( - since = "TBD", - note = "all constants in this module replaced by associated constants on `i64`" -)] - -int_module! { i64 } diff --git a/library/core/src/num/shells/i8.rs b/library/core/src/num/shells/i8.rs deleted file mode 100644 index 516ba8cdef3bf..0000000000000 --- a/library/core/src/num/shells/i8.rs +++ /dev/null @@ -1,11 +0,0 @@ -//! Redundant constants module for the [`i8` primitive type][i8]. -//! -//! New code should use the associated constants directly on the primitive type. - -#![stable(feature = "rust1", since = "1.0.0")] -#![deprecated( - since = "TBD", - note = "all constants in this module replaced by associated constants on `i8`" -)] - -int_module! { i8 } diff --git a/library/core/src/num/shells/int_macros.rs b/library/core/src/num/shells/int_macros.rs deleted file mode 100644 index 8ae9b7abae3bd..0000000000000 --- a/library/core/src/num/shells/int_macros.rs +++ /dev/null @@ -1,46 +0,0 @@ -#![doc(hidden)] - -macro_rules! int_module { - ($T:ident) => (int_module!($T, #[stable(feature = "rust1", since = "1.0.0")]);); - ($T:ident, #[$attr:meta]) => ( - #[doc = concat!( - "The smallest value that can be represented by this integer type. Use ", - "[`", stringify!($T), "::MIN", "`] instead." - )] - /// - /// # Examples - /// - /// ```rust - /// // deprecated way - #[doc = concat!("let min = std::", stringify!($T), "::MIN;")] - /// - /// // intended way - #[doc = concat!("let min = ", stringify!($T), "::MIN;")] - /// ``` - /// - #[$attr] - #[deprecated(since = "TBD", note = "replaced by the `MIN` associated constant on this type")] - #[rustc_diagnostic_item = concat!(stringify!($T), "_legacy_const_min")] - pub const MIN: $T = $T::MIN; - - #[doc = concat!( - "The largest value that can be represented by this integer type. Use ", - "[`", stringify!($T), "::MAX", "`] instead." - )] - /// - /// # Examples - /// - /// ```rust - /// // deprecated way - #[doc = concat!("let max = std::", stringify!($T), "::MAX;")] - /// - /// // intended way - #[doc = concat!("let max = ", stringify!($T), "::MAX;")] - /// ``` - /// - #[$attr] - #[deprecated(since = "TBD", note = "replaced by the `MAX` associated constant on this type")] - #[rustc_diagnostic_item = concat!(stringify!($T), "_legacy_const_max")] - pub const MAX: $T = $T::MAX; - ) -} diff --git a/library/core/src/num/shells/isize.rs b/library/core/src/num/shells/isize.rs deleted file mode 100644 index 828f7345bafbe..0000000000000 --- a/library/core/src/num/shells/isize.rs +++ /dev/null @@ -1,11 +0,0 @@ -//! Redundant constants module for the [`isize` primitive type][isize]. -//! -//! New code should use the associated constants directly on the primitive type. - -#![stable(feature = "rust1", since = "1.0.0")] -#![deprecated( - since = "TBD", - note = "all constants in this module replaced by associated constants on `isize`" -)] - -int_module! { isize } diff --git a/library/core/src/num/shells/legacy_int_modules.rs b/library/core/src/num/shells/legacy_int_modules.rs new file mode 100644 index 0000000000000..6b4f253911157 --- /dev/null +++ b/library/core/src/num/shells/legacy_int_modules.rs @@ -0,0 +1,71 @@ +#![doc(hidden)] + +macro_rules! legacy_int_module { + ($T:ident) => (legacy_int_module!($T, #[stable(feature = "rust1", since = "1.0.0")]);); + ($T:ident, #[$attr:meta]) => ( + #[$attr] + #[deprecated( + since = "TBD", + note = "all constants in this module replaced by associated constants on the type" + )] + #[rustc_diagnostic_item = concat!(stringify!($T), "_legacy_mod")] + pub mod $T { + #![doc = concat!("Redundant constants module for the [`", stringify!($T), "` primitive type][", stringify!($T), "].")] + //! + //! New code should use the associated constants directly on the primitive type. + + #[doc = concat!( + "The smallest value that can be represented by this integer type. Use ", + "[`", stringify!($T), "::MIN", "`] instead." + )] + /// + /// # Examples + /// + /// ```rust + /// // deprecated way + #[doc = concat!("let min = std::", stringify!($T), "::MIN;")] + /// + /// // intended way + #[doc = concat!("let min = ", stringify!($T), "::MIN;")] + /// ``` + /// + #[$attr] + #[deprecated(since = "TBD", note = "replaced by the `MIN` associated constant on this type")] + #[rustc_diagnostic_item = concat!(stringify!($T), "_legacy_const_min")] + pub const MIN: $T = $T::MIN; + + #[doc = concat!( + "The largest value that can be represented by this integer type. Use ", + "[`", stringify!($T), "::MAX", "`] instead." + )] + /// + /// # Examples + /// + /// ```rust + /// // deprecated way + #[doc = concat!("let max = std::", stringify!($T), "::MAX;")] + /// + /// // intended way + #[doc = concat!("let max = ", stringify!($T), "::MAX;")] + /// ``` + /// + #[$attr] + #[deprecated(since = "TBD", note = "replaced by the `MAX` associated constant on this type")] + #[rustc_diagnostic_item = concat!(stringify!($T), "_legacy_const_max")] + pub const MAX: $T = $T::MAX; + } + ) +} + +legacy_int_module! { i128, #[stable(feature = "i128", since = "1.26.0")] } +legacy_int_module! { i16 } +legacy_int_module! { i32 } +legacy_int_module! { i64 } +legacy_int_module! { i8 } +legacy_int_module! { isize } +legacy_int_module! { u128, #[stable(feature = "i128", since = "1.26.0")] } +legacy_int_module! { u16 } +legacy_int_module! { u32 } +legacy_int_module! { u64 } +legacy_int_module! { u8 } +legacy_int_module! { usize } diff --git a/library/core/src/num/shells/u128.rs b/library/core/src/num/shells/u128.rs deleted file mode 100644 index b1e30e3843525..0000000000000 --- a/library/core/src/num/shells/u128.rs +++ /dev/null @@ -1,11 +0,0 @@ -//! Redundant constants module for the [`u128` primitive type][u128]. -//! -//! New code should use the associated constants directly on the primitive type. - -#![stable(feature = "i128", since = "1.26.0")] -#![deprecated( - since = "TBD", - note = "all constants in this module replaced by associated constants on `u128`" -)] - -int_module! { u128, #[stable(feature = "i128", since="1.26.0")] } diff --git a/library/core/src/num/shells/u16.rs b/library/core/src/num/shells/u16.rs deleted file mode 100644 index 7394977e5078a..0000000000000 --- a/library/core/src/num/shells/u16.rs +++ /dev/null @@ -1,11 +0,0 @@ -//! Redundant constants module for the [`u16` primitive type][u16]. -//! -//! New code should use the associated constants directly on the primitive type. - -#![stable(feature = "rust1", since = "1.0.0")] -#![deprecated( - since = "TBD", - note = "all constants in this module replaced by associated constants on `u16`" -)] - -int_module! { u16 } diff --git a/library/core/src/num/shells/u32.rs b/library/core/src/num/shells/u32.rs deleted file mode 100644 index 4c84274e752ec..0000000000000 --- a/library/core/src/num/shells/u32.rs +++ /dev/null @@ -1,11 +0,0 @@ -//! Redundant constants module for the [`u32` primitive type][u32]. -//! -//! New code should use the associated constants directly on the primitive type. - -#![stable(feature = "rust1", since = "1.0.0")] -#![deprecated( - since = "TBD", - note = "all constants in this module replaced by associated constants on `u32`" -)] - -int_module! { u32 } diff --git a/library/core/src/num/shells/u64.rs b/library/core/src/num/shells/u64.rs deleted file mode 100644 index 47a95c6820f2f..0000000000000 --- a/library/core/src/num/shells/u64.rs +++ /dev/null @@ -1,11 +0,0 @@ -//! Redundant constants module for the [`u64` primitive type][u64]. -//! -//! New code should use the associated constants directly on the primitive type. - -#![stable(feature = "rust1", since = "1.0.0")] -#![deprecated( - since = "TBD", - note = "all constants in this module replaced by associated constants on `u64`" -)] - -int_module! { u64 } diff --git a/library/core/src/num/shells/u8.rs b/library/core/src/num/shells/u8.rs deleted file mode 100644 index 360baef722869..0000000000000 --- a/library/core/src/num/shells/u8.rs +++ /dev/null @@ -1,11 +0,0 @@ -//! Redundant constants module for the [`u8` primitive type][u8]. -//! -//! New code should use the associated constants directly on the primitive type. - -#![stable(feature = "rust1", since = "1.0.0")] -#![deprecated( - since = "TBD", - note = "all constants in this module replaced by associated constants on `u8`" -)] - -int_module! { u8 } diff --git a/library/core/src/num/shells/usize.rs b/library/core/src/num/shells/usize.rs deleted file mode 100644 index 44c24dfc2cf58..0000000000000 --- a/library/core/src/num/shells/usize.rs +++ /dev/null @@ -1,11 +0,0 @@ -//! Redundant constants module for the [`usize` primitive type][usize]. -//! -//! New code should use the associated constants directly on the primitive type. - -#![stable(feature = "rust1", since = "1.0.0")] -#![deprecated( - since = "TBD", - note = "all constants in this module replaced by associated constants on `usize`" -)] - -int_module! { usize } From 92f24020967e4e1f1375dbb2d1ba85cd4430fc78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Sun, 24 Aug 2025 10:56:41 +0200 Subject: [PATCH 12/16] port `#[recursion_limit]` to the new attribute parsing infrastructure --- compiler/rustc_attr_parsing/messages.ftl | 4 ++ .../src/attributes/crate_level.rs | 62 ++++++++++++++++++- .../src/attributes/prelude.rs | 2 +- compiler/rustc_attr_parsing/src/context.rs | 3 +- .../src/session_diagnostics.rs | 10 +++ .../rustc_hir/src/attrs/data_structures.rs | 3 + .../rustc_hir/src/attrs/encode_cross_crate.rs | 1 + .../rustc_hir/src/attrs/pretty_printing.rs | 2 +- compiler/rustc_passes/src/check_attr.rs | 1 + 9 files changed, 84 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_attr_parsing/messages.ftl b/compiler/rustc_attr_parsing/messages.ftl index 7fa1293463cc5..839a5d23c3b4d 100644 --- a/compiler/rustc_attr_parsing/messages.ftl +++ b/compiler/rustc_attr_parsing/messages.ftl @@ -247,3 +247,7 @@ attr_parsing_raw_dylib_only_windows = attr_parsing_whole_archive_needs_static = linking modifier `whole-archive` is only compatible with `static` linking kind + +attr_parsing_limit_invalid = + `limit` must be a non-negative integer + .label = {$error_str} diff --git a/compiler/rustc_attr_parsing/src/attributes/crate_level.rs b/compiler/rustc_attr_parsing/src/attributes/crate_level.rs index 2fed09b85e87b..e3654d495801b 100644 --- a/compiler/rustc_attr_parsing/src/attributes/crate_level.rs +++ b/compiler/rustc_attr_parsing/src/attributes/crate_level.rs @@ -1,7 +1,40 @@ -use rustc_feature::AttributeType; +use std::num::IntErrorKind; + +use crate::session_diagnostics::LimitInvalid; use super::prelude::*; +impl AcceptContext<'_, '_, S> { + fn parse_limit_int(&self, nv: &NameValueParser) -> Option { + let Some(limit) = nv.value_as_str() else { + self.expected_string_literal(nv.value_span, Some(nv.value_as_lit())); + return None; + }; + + let error_str = match limit.as_str().parse() { + Ok(i) => return Some(i), + Err(e) => match e.kind() { + IntErrorKind::PosOverflow => "`limit` is too large", + IntErrorKind::Empty => "`limit` must be a non-negative integer", + IntErrorKind::InvalidDigit => "not a valid integer", + IntErrorKind::NegOverflow => { + panic!( + "`limit` should never negatively overflow since we're parsing into a usize and we'd get Empty instead" + ) + } + IntErrorKind::Zero => { + panic!("zero is a valid `limit` so should have returned Ok() when parsing") + } + kind => panic!("unimplemented IntErrorKind variant: {:?}", kind), + }, + }; + + self.emit_err(LimitInvalid { span: self.attr_span, value_span: nv.value_span, error_str }); + + None + } +} + pub(crate) struct CrateNameParser; impl SingleAttributeParser for CrateNameParser { @@ -34,3 +67,30 @@ impl SingleAttributeParser for CrateNameParser { }) } } + +pub(crate) struct RecursionLimitParser; + +impl SingleAttributeParser for RecursionLimitParser { + const PATH: &[Symbol] = &[sym::recursion_limit]; + const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::WarnButFutureError; + const TEMPLATE: AttributeTemplate = template!(NameValueStr: "N", "https://doc.rust-lang.org/reference/attributes/limits.html#the-recursion_limit-attribute"); + const TYPE: AttributeType = AttributeType::CrateLevel; + + // FIXME: recursion limit is allowed on all targets and ignored, + // even though it should only be valid on crates of course + const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS); + + fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option { + let ArgParser::NameValue(nv) = args else { + cx.expected_name_value(cx.attr_span, None); + return None; + }; + + Some(AttributeKind::RecursionLimit { + limit: cx.parse_limit_int(nv)?, + attr_span: cx.attr_span, + limit_span: nv.value_span, + }) + } +} diff --git a/compiler/rustc_attr_parsing/src/attributes/prelude.rs b/compiler/rustc_attr_parsing/src/attributes/prelude.rs index 6aef7e7a67be4..e53a436613180 100644 --- a/compiler/rustc_attr_parsing/src/attributes/prelude.rs +++ b/compiler/rustc_attr_parsing/src/attributes/prelude.rs @@ -1,6 +1,6 @@ // templates #[doc(hidden)] -pub(super) use rustc_feature::{AttributeTemplate, template}; +pub(super) use rustc_feature::{AttributeTemplate, AttributeType, template}; // data structures #[doc(hidden)] pub(super) use rustc_hir::attrs::AttributeKind; diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index 7f5b810f244f1..5700668145bfd 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -24,7 +24,7 @@ use crate::attributes::codegen_attrs::{ UsedParser, }; use crate::attributes::confusables::ConfusablesParser; -use crate::attributes::crate_level::CrateNameParser; +use crate::attributes::crate_level::{CrateNameParser, RecursionLimitParser}; use crate::attributes::deprecation::DeprecationParser; use crate::attributes::dummy::DummyParser; use crate::attributes::inline::{InlineParser, RustcForceInlineParser}; @@ -185,6 +185,7 @@ attribute_parsers!( Single, Single, Single, + Single, Single, Single, Single, diff --git a/compiler/rustc_attr_parsing/src/session_diagnostics.rs b/compiler/rustc_attr_parsing/src/session_diagnostics.rs index a9dee23bf6a3b..32ea9005a97d0 100644 --- a/compiler/rustc_attr_parsing/src/session_diagnostics.rs +++ b/compiler/rustc_attr_parsing/src/session_diagnostics.rs @@ -930,3 +930,13 @@ pub(crate) struct ImportNameTypeRaw { #[primary_span] pub span: Span, } + +#[derive(Diagnostic)] +#[diag(attr_parsing_limit_invalid)] +pub(crate) struct LimitInvalid<'a> { + #[primary_span] + pub span: Span, + #[label] + pub value_span: Span, + pub error_str: &'a str, +} diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index dd5565d6f9092..bfc7613342a06 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -611,6 +611,9 @@ pub enum AttributeKind { /// Represents `#[rustc_pub_transparent]` (used by the `repr_transparent_external_private_fields` lint). PubTransparent(Span), + /// Represents [`#[recursion_limit]`](https://doc.rust-lang.org/reference/attributes/limits.html#the-recursion_limit-attribute) + RecursionLimit { attr_span: Span, limit_span: Span, limit: usize }, + /// Represents [`#[repr]`](https://doc.rust-lang.org/stable/reference/type-layout.html#representations). Repr { reprs: ThinVec<(ReprAttr, Span)>, first_span: Span }, diff --git a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs index 3810bb6d0038e..26929e805a52f 100644 --- a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs +++ b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs @@ -75,6 +75,7 @@ impl AttributeKind { ProcMacroAttribute(..) => No, ProcMacroDerive { .. } => No, PubTransparent(..) => Yes, + RecursionLimit { .. } => No, Repr { .. } => No, RustcBuiltinMacro { .. } => Yes, RustcLayoutScalarValidRangeEnd(..) => Yes, diff --git a/compiler/rustc_hir/src/attrs/pretty_printing.rs b/compiler/rustc_hir/src/attrs/pretty_printing.rs index e65de25b45117..a4c2beb689dcc 100644 --- a/compiler/rustc_hir/src/attrs/pretty_printing.rs +++ b/compiler/rustc_hir/src/attrs/pretty_printing.rs @@ -146,7 +146,7 @@ macro_rules! print_tup { print_tup!(A B C D E F G H); print_skip!(Span, (), ErrorGuaranteed); -print_disp!(u16, bool, NonZero); +print_disp!(u16, bool, NonZero, usize); print_debug!( Symbol, Ident, diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 2cd4830b5d935..9a94f849a089c 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -270,6 +270,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | AttributeKind::Linkage(..) | AttributeKind::MustUse { .. } | AttributeKind::CrateName { .. } + | AttributeKind::RecursionLimit { .. } ) => { /* do nothing */ } Attribute::Unparsed(attr_item) => { style = Some(attr_item.style); From a38288bbe00f64204967819fd2cfe107a7902404 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Sun, 24 Aug 2025 13:14:27 +0200 Subject: [PATCH 13/16] port `#[move_size_limit]` to the new attribute parsing infrastructure --- .../src/attributes/crate_level.rs | 26 +++++++++++++++++++ compiler/rustc_attr_parsing/src/context.rs | 3 ++- .../rustc_hir/src/attrs/data_structures.rs | 3 +++ .../rustc_hir/src/attrs/encode_cross_crate.rs | 1 + compiler/rustc_passes/src/check_attr.rs | 1 + 5 files changed, 33 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/crate_level.rs b/compiler/rustc_attr_parsing/src/attributes/crate_level.rs index e3654d495801b..af19b9f552da0 100644 --- a/compiler/rustc_attr_parsing/src/attributes/crate_level.rs +++ b/compiler/rustc_attr_parsing/src/attributes/crate_level.rs @@ -94,3 +94,29 @@ impl SingleAttributeParser for RecursionLimitParser { }) } } + +pub(crate) struct MoveSizeLimitParser; + +impl SingleAttributeParser for MoveSizeLimitParser { + const PATH: &[Symbol] = &[sym::move_size_limit]; + const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; + const TEMPLATE: AttributeTemplate = template!(NameValueStr: "N"); + + // FIXME: move size limit is allowed on all targets and ignored, + // even though it should only be valid on crates of course + const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]); + + fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option { + let ArgParser::NameValue(nv) = args else { + cx.expected_name_value(cx.attr_span, None); + return None; + }; + + Some(AttributeKind::MoveSizeLimit { + limit: cx.parse_limit_int(nv)?, + attr_span: cx.attr_span, + limit_span: nv.value_span, + }) + } +} diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index 5700668145bfd..4ec9df88e8274 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -24,7 +24,7 @@ use crate::attributes::codegen_attrs::{ UsedParser, }; use crate::attributes::confusables::ConfusablesParser; -use crate::attributes::crate_level::{CrateNameParser, RecursionLimitParser}; +use crate::attributes::crate_level::{CrateNameParser, MoveSizeLimitParser, RecursionLimitParser}; use crate::attributes::deprecation::DeprecationParser; use crate::attributes::dummy::DummyParser; use crate::attributes::inline::{InlineParser, RustcForceInlineParser}; @@ -181,6 +181,7 @@ attribute_parsers!( Single, Single, Single, + Single, Single, Single, Single, diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index bfc7613342a06..c565b8226197e 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -565,6 +565,9 @@ pub enum AttributeKind { /// Represents [`#[may_dangle]`](https://std-dev-guide.rust-lang.org/tricky/may-dangle.html). MayDangle(Span), + /// Represents `#[move_size_limit]` + MoveSizeLimit { attr_span: Span, limit_span: Span, limit: usize }, + /// Represents `#[must_use]`. MustUse { span: Span, diff --git a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs index 26929e805a52f..4df77c901557c 100644 --- a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs +++ b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs @@ -61,6 +61,7 @@ impl AttributeKind { MacroUse { .. } => No, Marker(..) => No, MayDangle(..) => No, + MoveSizeLimit { .. } => No, MustUse { .. } => Yes, Naked(..) => No, NoImplicitPrelude(..) => No, diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 9a94f849a089c..08c3162b83170 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -271,6 +271,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | AttributeKind::MustUse { .. } | AttributeKind::CrateName { .. } | AttributeKind::RecursionLimit { .. } + | AttributeKind::MoveSizeLimit { .. } ) => { /* do nothing */ } Attribute::Unparsed(attr_item) => { style = Some(attr_item.style); From 5dbe099dd3b9abb13cd63f8655e495f7a8d1bfcb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Sun, 24 Aug 2025 13:18:51 +0200 Subject: [PATCH 14/16] port `#[type_length_limit]` to the new attribute parsing infrastructure --- .../src/attributes/crate_level.rs | 27 +++++++++++++++++++ compiler/rustc_attr_parsing/src/context.rs | 5 +++- .../rustc_hir/src/attrs/data_structures.rs | 3 +++ .../rustc_hir/src/attrs/encode_cross_crate.rs | 1 + compiler/rustc_passes/src/check_attr.rs | 1 + 5 files changed, 36 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/crate_level.rs b/compiler/rustc_attr_parsing/src/attributes/crate_level.rs index af19b9f552da0..34793a7f403f2 100644 --- a/compiler/rustc_attr_parsing/src/attributes/crate_level.rs +++ b/compiler/rustc_attr_parsing/src/attributes/crate_level.rs @@ -120,3 +120,30 @@ impl SingleAttributeParser for MoveSizeLimitParser { }) } } + +pub(crate) struct TypeLengthLimitParser; + +impl SingleAttributeParser for TypeLengthLimitParser { + const PATH: &[Symbol] = &[sym::type_length_limit]; + const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::WarnButFutureError; + const TEMPLATE: AttributeTemplate = template!(NameValueStr: "N"); + const TYPE: AttributeType = AttributeType::CrateLevel; + + // FIXME: recursion limit is allowed on all targets and ignored, + // even though it should only be valid on crates of course + const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowListWarnRest(&[Target::Crate]); + + fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option { + let ArgParser::NameValue(nv) = args else { + cx.expected_name_value(cx.attr_span, None); + return None; + }; + + Some(AttributeKind::TypeLengthLimit { + limit: cx.parse_limit_int(nv)?, + attr_span: cx.attr_span, + limit_span: nv.value_span, + }) + } +} diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index 4ec9df88e8274..25a1993d08964 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -24,7 +24,9 @@ use crate::attributes::codegen_attrs::{ UsedParser, }; use crate::attributes::confusables::ConfusablesParser; -use crate::attributes::crate_level::{CrateNameParser, MoveSizeLimitParser, RecursionLimitParser}; +use crate::attributes::crate_level::{ + CrateNameParser, MoveSizeLimitParser, RecursionLimitParser, TypeLengthLimitParser, +}; use crate::attributes::deprecation::DeprecationParser; use crate::attributes::dummy::DummyParser; use crate::attributes::inline::{InlineParser, RustcForceInlineParser}; @@ -196,6 +198,7 @@ attribute_parsers!( Single, Single, Single, + Single, Single>, Single>, Single>, diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index c565b8226197e..22b39cb19e11e 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -667,6 +667,9 @@ pub enum AttributeKind { /// Represents `#[type_const]`. TypeConst(Span), + /// Represents `#[type_length_limit]` + TypeLengthLimit { attr_span: Span, limit_span: Span, limit: usize }, + /// Represents `#[rustc_unsafe_specialization_marker]`. UnsafeSpecializationMarker(Span), diff --git a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs index 4df77c901557c..e1f2d6d36403b 100644 --- a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs +++ b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs @@ -91,6 +91,7 @@ impl AttributeKind { TargetFeature { .. } => No, TrackCaller(..) => Yes, TypeConst(..) => Yes, + TypeLengthLimit { .. } => Yes, UnsafeSpecializationMarker(..) => No, UnstableFeatureBound(..) => No, Used { .. } => No, diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 08c3162b83170..e69071c73e1e7 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -272,6 +272,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | AttributeKind::CrateName { .. } | AttributeKind::RecursionLimit { .. } | AttributeKind::MoveSizeLimit { .. } + | AttributeKind::TypeLengthLimit { .. } ) => { /* do nothing */ } Attribute::Unparsed(attr_item) => { style = Some(attr_item.style); From b82171de5fe2a13a12f35ce4368ef34a477f55c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Sun, 24 Aug 2025 13:19:31 +0200 Subject: [PATCH 15/16] port `#[pattern_complexity_limit]` to the new attribute parsing infrastructure --- .../src/attributes/crate_level.rs | 27 +++++++++++++++++++ compiler/rustc_attr_parsing/src/context.rs | 4 ++- .../rustc_hir/src/attrs/data_structures.rs | 3 +++ .../rustc_hir/src/attrs/encode_cross_crate.rs | 1 + compiler/rustc_passes/src/check_attr.rs | 1 + 5 files changed, 35 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/crate_level.rs b/compiler/rustc_attr_parsing/src/attributes/crate_level.rs index 34793a7f403f2..6fd4a4a753b66 100644 --- a/compiler/rustc_attr_parsing/src/attributes/crate_level.rs +++ b/compiler/rustc_attr_parsing/src/attributes/crate_level.rs @@ -147,3 +147,30 @@ impl SingleAttributeParser for TypeLengthLimitParser { }) } } + +pub(crate) struct PatternComplexityLimitParser; + +impl SingleAttributeParser for PatternComplexityLimitParser { + const PATH: &[Symbol] = &[sym::pattern_complexity_limit]; + const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; + const TEMPLATE: AttributeTemplate = template!(NameValueStr: "N"); + const TYPE: AttributeType = AttributeType::CrateLevel; + + // FIXME: recursion limit is allowed on all targets and ignored, + // even though it should only be valid on crates of course + const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]); + + fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option { + let ArgParser::NameValue(nv) = args else { + cx.expected_name_value(cx.attr_span, None); + return None; + }; + + Some(AttributeKind::PatternComplexityLimit { + limit: cx.parse_limit_int(nv)?, + attr_span: cx.attr_span, + limit_span: nv.value_span, + }) + } +} diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index 25a1993d08964..fc41e38c797b4 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -25,7 +25,8 @@ use crate::attributes::codegen_attrs::{ }; use crate::attributes::confusables::ConfusablesParser; use crate::attributes::crate_level::{ - CrateNameParser, MoveSizeLimitParser, RecursionLimitParser, TypeLengthLimitParser, + CrateNameParser, MoveSizeLimitParser, PatternComplexityLimitParser, RecursionLimitParser, + TypeLengthLimitParser, }; use crate::attributes::deprecation::DeprecationParser; use crate::attributes::dummy::DummyParser; @@ -187,6 +188,7 @@ attribute_parsers!( Single, Single, Single, + Single, Single, Single, Single, diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index 22b39cb19e11e..c4e068ad42577 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -599,6 +599,9 @@ pub enum AttributeKind { /// Represents `#[path]` Path(Symbol, Span), + /// Represents `#[pattern_complexity_limit]` + PatternComplexityLimit { attr_span: Span, limit_span: Span, limit: usize }, + /// Represents `#[pointee]` Pointee(Span), diff --git a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs index e1f2d6d36403b..89ba1e0d7de45 100644 --- a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs +++ b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs @@ -71,6 +71,7 @@ impl AttributeKind { ParenSugar(..) => No, PassByValue(..) => Yes, Path(..) => No, + PatternComplexityLimit { .. } => No, Pointee(..) => No, ProcMacro(..) => No, ProcMacroAttribute(..) => No, diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index e69071c73e1e7..487bdd2a888e7 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -273,6 +273,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | AttributeKind::RecursionLimit { .. } | AttributeKind::MoveSizeLimit { .. } | AttributeKind::TypeLengthLimit { .. } + | AttributeKind::PatternComplexityLimit { .. } ) => { /* do nothing */ } Attribute::Unparsed(attr_item) => { style = Some(attr_item.style); From 6087d89004eda5e1f6406182b9866497ecb22e99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Sun, 24 Aug 2025 13:25:36 +0200 Subject: [PATCH 16/16] fixup limit handling code --- Cargo.lock | 1 - .../src/attributes/crate_level.rs | 34 +-- .../src/attributes/prelude.rs | 3 +- compiler/rustc_attr_parsing/src/context.rs | 13 +- .../src/interpret/eval_context.rs | 2 +- compiler/rustc_expand/src/base.rs | 3 +- compiler/rustc_expand/src/errors.rs | 2 +- compiler/rustc_expand/src/expand.rs | 4 +- .../rustc_hir/src/attrs/data_structures.rs | 9 +- .../rustc_hir/src/attrs/encode_cross_crate.rs | 2 +- .../rustc_hir/src/attrs/pretty_printing.rs | 4 +- compiler/rustc_hir/src/lib.rs | 1 + compiler/rustc_hir/src/limit.rs | 63 +++++ compiler/rustc_hir_analysis/src/autoderef.rs | 2 +- compiler/rustc_hir_analysis/src/errors.rs | 3 +- compiler/rustc_interface/messages.ftl | 4 - compiler/rustc_interface/src/errors.rs | 10 - compiler/rustc_interface/src/limits.rs | 88 ++---- compiler/rustc_interface/src/passes.rs | 54 ++-- compiler/rustc_middle/src/error.rs | 2 +- compiler/rustc_middle/src/ty/context.rs | 3 +- compiler/rustc_middle/src/ty/error.rs | 3 +- compiler/rustc_middle/src/ty/print/pretty.rs | 2 +- compiler/rustc_middle/src/ty/util.rs | 2 +- .../rustc_mir_transform/src/inline/cycle.rs | 2 +- compiler/rustc_monomorphize/src/collector.rs | 2 +- .../src/mono_checks/move_check.rs | 2 +- compiler/rustc_query_impl/Cargo.toml | 1 - compiler/rustc_query_impl/src/plumbing.rs | 2 +- compiler/rustc_query_system/src/error.rs | 2 +- compiler/rustc_session/src/session.rs | 62 +---- .../src/error_reporting/traits/overflow.rs | 4 +- compiler/rustc_ty_utils/src/needs_drop.rs | 2 +- .../issue-43106-gating-of-builtin-attrs.rs | 24 +- ...issue-43106-gating-of-builtin-attrs.stderr | 262 ++++++++++-------- .../lint/unused/unused-attr-duplicate.stderr | 52 ++-- .../unused/unused-attr-macro-rules.stderr | 35 +-- tests/ui/recursion_limit/empty.rs | 8 +- tests/ui/recursion_limit/empty.stderr | 12 +- tests/ui/recursion_limit/invalid_digit.rs | 8 +- tests/ui/recursion_limit/invalid_digit.stderr | 12 +- .../recursion_limit/invalid_digit_type.stderr | 8 +- tests/ui/recursion_limit/invalid_macro.rs | 2 +- tests/ui/recursion_limit/invalid_macro.stderr | 8 +- tests/ui/recursion_limit/no-value.stderr | 3 +- tests/ui/recursion_limit/overflow.rs | 3 - tests/ui/recursion_limit/overflow.stderr | 12 +- 47 files changed, 385 insertions(+), 457 deletions(-) create mode 100644 compiler/rustc_hir/src/limit.rs diff --git a/Cargo.lock b/Cargo.lock index 81f19668c24b7..78be59b3091be 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4409,7 +4409,6 @@ dependencies = [ "rustc_middle", "rustc_query_system", "rustc_serialize", - "rustc_session", "rustc_span", "tracing", ] diff --git a/compiler/rustc_attr_parsing/src/attributes/crate_level.rs b/compiler/rustc_attr_parsing/src/attributes/crate_level.rs index 6fd4a4a753b66..d23a7ae72f8c8 100644 --- a/compiler/rustc_attr_parsing/src/attributes/crate_level.rs +++ b/compiler/rustc_attr_parsing/src/attributes/crate_level.rs @@ -1,18 +1,19 @@ use std::num::IntErrorKind; -use crate::session_diagnostics::LimitInvalid; +use rustc_hir::limit::Limit; use super::prelude::*; +use crate::session_diagnostics::LimitInvalid; impl AcceptContext<'_, '_, S> { - fn parse_limit_int(&self, nv: &NameValueParser) -> Option { + fn parse_limit_int(&self, nv: &NameValueParser) -> Option { let Some(limit) = nv.value_as_str() else { self.expected_string_literal(nv.value_span, Some(nv.value_as_lit())); return None; }; let error_str = match limit.as_str().parse() { - Ok(i) => return Some(i), + Ok(i) => return Some(Limit::new(i)), Err(e) => match e.kind() { IntErrorKind::PosOverflow => "`limit` is too large", IntErrorKind::Empty => "`limit` must be a non-negative integer", @@ -44,8 +45,8 @@ impl SingleAttributeParser for CrateNameParser { const TEMPLATE: AttributeTemplate = template!(NameValueStr: "name"); const TYPE: AttributeType = AttributeType::CrateLevel; - // FIXME: crate name is allowed on all targets and ignored, - // even though it should only be valid on crates of course + // because it's a crate-level attribute, we already warn about it. + // Putting target limitations here would give duplicate warnings const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS); fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option { @@ -77,8 +78,8 @@ impl SingleAttributeParser for RecursionLimitParser { const TEMPLATE: AttributeTemplate = template!(NameValueStr: "N", "https://doc.rust-lang.org/reference/attributes/limits.html#the-recursion_limit-attribute"); const TYPE: AttributeType = AttributeType::CrateLevel; - // FIXME: recursion limit is allowed on all targets and ignored, - // even though it should only be valid on crates of course + // because it's a crate-level attribute, we already warn about it. + // Putting target limitations here would give duplicate warnings const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS); fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option { @@ -102,10 +103,11 @@ impl SingleAttributeParser for MoveSizeLimitParser { const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost; const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const TEMPLATE: AttributeTemplate = template!(NameValueStr: "N"); + const TYPE: AttributeType = AttributeType::CrateLevel; - // FIXME: move size limit is allowed on all targets and ignored, - // even though it should only be valid on crates of course - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]); + // because it's a crate-level attribute, we already warn about it. + // Putting target limitations here would give duplicate warnings + const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS); fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option { let ArgParser::NameValue(nv) = args else { @@ -130,9 +132,9 @@ impl SingleAttributeParser for TypeLengthLimitParser { const TEMPLATE: AttributeTemplate = template!(NameValueStr: "N"); const TYPE: AttributeType = AttributeType::CrateLevel; - // FIXME: recursion limit is allowed on all targets and ignored, - // even though it should only be valid on crates of course - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowListWarnRest(&[Target::Crate]); + // because it's a crate-level attribute, we already warn about it. + // Putting target limitations here would give duplicate warnings + const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS); fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option { let ArgParser::NameValue(nv) = args else { @@ -157,9 +159,9 @@ impl SingleAttributeParser for PatternComplexityLimitParser { const TEMPLATE: AttributeTemplate = template!(NameValueStr: "N"); const TYPE: AttributeType = AttributeType::CrateLevel; - // FIXME: recursion limit is allowed on all targets and ignored, - // even though it should only be valid on crates of course - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]); + // because it's a crate-level attribute, we already warn about it. + // Putting target limitations here would give duplicate warnings + const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS); fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option { let ArgParser::NameValue(nv) = args else { diff --git a/compiler/rustc_attr_parsing/src/attributes/prelude.rs b/compiler/rustc_attr_parsing/src/attributes/prelude.rs index e53a436613180..8f040ffb9d41c 100644 --- a/compiler/rustc_attr_parsing/src/attributes/prelude.rs +++ b/compiler/rustc_attr_parsing/src/attributes/prelude.rs @@ -1,7 +1,6 @@ -// templates +// data structures #[doc(hidden)] pub(super) use rustc_feature::{AttributeTemplate, AttributeType, template}; -// data structures #[doc(hidden)] pub(super) use rustc_hir::attrs::AttributeKind; #[doc(hidden)] diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index fc41e38c797b4..98e86838a3a18 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -353,7 +353,10 @@ impl<'f, 'sess: 'f, S: Stage> SharedContext<'f, 'sess, S> { /// must be delayed until after HIR is built. This method will take care of the details of /// that. pub(crate) fn emit_lint(&mut self, lint: AttributeLintKind, span: Span) { - if matches!(self.stage.should_emit(), ShouldEmit::Nothing) { + if !matches!( + self.stage.should_emit(), + ShouldEmit::ErrorsAndLints | ShouldEmit::EarlyFatal { also_emit_lints: true } + ) { return; } let id = self.target_id; @@ -677,20 +680,20 @@ pub enum ShouldEmit { /// /// Only relevant when early parsing, in late parsing equivalent to `ErrorsAndLints`. /// Late parsing is never fatal, and instead tries to emit as many diagnostics as possible. - EarlyFatal, + EarlyFatal { also_emit_lints: bool }, /// The operation will emit errors and lints. /// This is usually what you need. ErrorsAndLints, /// The operation will emit *not* errors and lints. - /// Use this if you are *sure* that this operation will be called at a different time with `ShouldEmit::Emit`. + /// Use this if you are *sure* that this operation will be called at a different time with `ShouldEmit::ErrorsAndLints`. Nothing, } impl ShouldEmit { pub(crate) fn emit_err(&self, diag: Diag<'_>) -> ErrorGuaranteed { match self { - ShouldEmit::EarlyFatal if diag.level() == Level::DelayedBug => diag.emit(), - ShouldEmit::EarlyFatal => diag.upgrade_to_fatal().emit(), + ShouldEmit::EarlyFatal { .. } if diag.level() == Level::DelayedBug => diag.emit(), + ShouldEmit::EarlyFatal { .. } => diag.upgrade_to_fatal().emit(), ShouldEmit::ErrorsAndLints => diag.emit(), ShouldEmit::Nothing => diag.delay_as_bug(), } diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs index 9681d89ce35f2..91ed71ac3e54c 100644 --- a/compiler/rustc_const_eval/src/interpret/eval_context.rs +++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs @@ -4,6 +4,7 @@ use either::{Left, Right}; use rustc_abi::{Align, HasDataLayout, Size, TargetDataLayout}; use rustc_errors::DiagCtxtHandle; use rustc_hir::def_id::DefId; +use rustc_hir::limit::Limit; use rustc_middle::mir::interpret::{ErrorHandled, InvalidMetaKind, ReportedErrorInfo}; use rustc_middle::query::TyCtxtAt; use rustc_middle::ty::layout::{ @@ -12,7 +13,6 @@ use rustc_middle::ty::layout::{ }; use rustc_middle::ty::{self, GenericArgsRef, Ty, TyCtxt, TypeFoldable, TypingEnv, Variance}; use rustc_middle::{mir, span_bug}; -use rustc_session::Limit; use rustc_span::Span; use rustc_target::callconv::FnAbi; use tracing::{debug, trace}; diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs index 8ff21509f4a9b..88f88f30a8c69 100644 --- a/compiler/rustc_expand/src/base.rs +++ b/compiler/rustc_expand/src/base.rs @@ -18,13 +18,14 @@ use rustc_feature::Features; use rustc_hir as hir; use rustc_hir::attrs::{AttributeKind, CfgEntry, Deprecation}; use rustc_hir::def::MacroKinds; +use rustc_hir::limit::Limit; use rustc_hir::{Stability, find_attr}; use rustc_lint_defs::RegisteredTools; use rustc_parse::MACRO_ARGUMENTS; use rustc_parse::parser::{ForceCollect, Parser}; +use rustc_session::Session; use rustc_session::config::CollapseMacroDebuginfo; use rustc_session::parse::ParseSess; -use rustc_session::{Limit, Session}; use rustc_span::def_id::{CrateNum, DefId, LocalDefId}; use rustc_span::edition::Edition; use rustc_span::hygiene::{AstPass, ExpnData, ExpnKind, LocalExpnId, MacroKind}; diff --git a/compiler/rustc_expand/src/errors.rs b/compiler/rustc_expand/src/errors.rs index ba9d76970f0cc..6eb5cd65846eb 100644 --- a/compiler/rustc_expand/src/errors.rs +++ b/compiler/rustc_expand/src/errors.rs @@ -2,8 +2,8 @@ use std::borrow::Cow; use rustc_ast::ast; use rustc_errors::codes::*; +use rustc_hir::limit::Limit; use rustc_macros::{Diagnostic, Subdiagnostic}; -use rustc_session::Limit; use rustc_span::{Ident, MacroRulesNormalizedIdent, Span, Symbol}; #[derive(Diagnostic)] diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index dbb4a9de9e03a..38e057d2776e4 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -19,14 +19,15 @@ use rustc_errors::PResult; use rustc_feature::Features; use rustc_hir::Target; use rustc_hir::def::MacroKinds; +use rustc_hir::limit::Limit; use rustc_parse::parser::{ AttemptLocalParseRecovery, CommaRecoveryMode, ForceCollect, Parser, RecoverColon, RecoverComma, token_descr, }; +use rustc_session::Session; use rustc_session::lint::BuiltinLintDiag; use rustc_session::lint::builtin::{UNUSED_ATTRIBUTES, UNUSED_DOC_COMMENTS}; use rustc_session::parse::feature_err; -use rustc_session::{Limit, Session}; use rustc_span::hygiene::SyntaxContext; use rustc_span::{ErrorGuaranteed, FileName, Ident, LocalExpnId, Span, Symbol, sym}; use smallvec::SmallVec; @@ -2529,6 +2530,7 @@ impl ExpansionConfig<'_> { ExpansionConfig { crate_name, features, + // FIXME should this limit be configurable? recursion_limit: Limit::new(1024), trace_mac: false, should_test: false, diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index c4e068ad42577..b4c1b61b9b586 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -14,6 +14,7 @@ pub use rustc_target::spec::SanitizerSet; use thin_vec::ThinVec; use crate::attrs::pretty_printing::PrintAttribute; +use crate::limit::Limit; use crate::{DefaultBodyStability, PartialConstStability, RustcVersion, Stability}; #[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug, HashStable_Generic, PrintAttribute)] @@ -566,7 +567,7 @@ pub enum AttributeKind { MayDangle(Span), /// Represents `#[move_size_limit]` - MoveSizeLimit { attr_span: Span, limit_span: Span, limit: usize }, + MoveSizeLimit { attr_span: Span, limit_span: Span, limit: Limit }, /// Represents `#[must_use]`. MustUse { @@ -600,7 +601,7 @@ pub enum AttributeKind { Path(Symbol, Span), /// Represents `#[pattern_complexity_limit]` - PatternComplexityLimit { attr_span: Span, limit_span: Span, limit: usize }, + PatternComplexityLimit { attr_span: Span, limit_span: Span, limit: Limit }, /// Represents `#[pointee]` Pointee(Span), @@ -618,7 +619,7 @@ pub enum AttributeKind { PubTransparent(Span), /// Represents [`#[recursion_limit]`](https://doc.rust-lang.org/reference/attributes/limits.html#the-recursion_limit-attribute) - RecursionLimit { attr_span: Span, limit_span: Span, limit: usize }, + RecursionLimit { attr_span: Span, limit_span: Span, limit: Limit }, /// Represents [`#[repr]`](https://doc.rust-lang.org/stable/reference/type-layout.html#representations). Repr { reprs: ThinVec<(ReprAttr, Span)>, first_span: Span }, @@ -671,7 +672,7 @@ pub enum AttributeKind { TypeConst(Span), /// Represents `#[type_length_limit]` - TypeLengthLimit { attr_span: Span, limit_span: Span, limit: usize }, + TypeLengthLimit { attr_span: Span, limit_span: Span, limit: Limit }, /// Represents `#[rustc_unsafe_specialization_marker]`. UnsafeSpecializationMarker(Span), diff --git a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs index 89ba1e0d7de45..0e208be3497ae 100644 --- a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs +++ b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs @@ -92,7 +92,7 @@ impl AttributeKind { TargetFeature { .. } => No, TrackCaller(..) => Yes, TypeConst(..) => Yes, - TypeLengthLimit { .. } => Yes, + TypeLengthLimit { .. } => No, UnsafeSpecializationMarker(..) => No, UnstableFeatureBound(..) => No, Used { .. } => No, diff --git a/compiler/rustc_hir/src/attrs/pretty_printing.rs b/compiler/rustc_hir/src/attrs/pretty_printing.rs index a4c2beb689dcc..d13cd3fd1dab0 100644 --- a/compiler/rustc_hir/src/attrs/pretty_printing.rs +++ b/compiler/rustc_hir/src/attrs/pretty_printing.rs @@ -9,6 +9,8 @@ use rustc_span::{ErrorGuaranteed, Ident, Span, Symbol}; use rustc_target::spec::SanitizerSet; use thin_vec::ThinVec; +use crate::limit::Limit; + /// This trait is used to print attributes in `rustc_hir_pretty`. /// /// For structs and enums it can be derived using [`rustc_macros::PrintAttribute`]. @@ -146,7 +148,7 @@ macro_rules! print_tup { print_tup!(A B C D E F G H); print_skip!(Span, (), ErrorGuaranteed); -print_disp!(u16, bool, NonZero, usize); +print_disp!(u16, bool, NonZero, Limit); print_debug!( Symbol, Ident, diff --git a/compiler/rustc_hir/src/lib.rs b/compiler/rustc_hir/src/lib.rs index 78fc63753a2e4..eb630fc801863 100644 --- a/compiler/rustc_hir/src/lib.rs +++ b/compiler/rustc_hir/src/lib.rs @@ -25,6 +25,7 @@ mod hir; pub use rustc_hir_id::{self as hir_id, *}; pub mod intravisit; pub mod lang_items; +pub mod limit; pub mod lints; pub mod pat_util; mod stability; diff --git a/compiler/rustc_hir/src/limit.rs b/compiler/rustc_hir/src/limit.rs new file mode 100644 index 0000000000000..7e6d23f51bdb9 --- /dev/null +++ b/compiler/rustc_hir/src/limit.rs @@ -0,0 +1,63 @@ +use std::fmt; +use std::ops::{Div, Mul}; + +use rustc_error_messages::{DiagArgValue, IntoDiagArg}; +use rustc_macros::{Decodable, Encodable, HashStable_Generic}; + +/// New-type wrapper around `usize` for representing limits. Ensures that comparisons against +/// limits are consistent throughout the compiler. +#[derive(Clone, Copy, Debug, HashStable_Generic, Encodable, Decodable)] +pub struct Limit(pub usize); + +impl Limit { + /// Create a new limit from a `usize`. + pub fn new(value: usize) -> Self { + Limit(value) + } + + /// Create a new unlimited limit. + pub fn unlimited() -> Self { + Limit(usize::MAX) + } + + /// Check that `value` is within the limit. Ensures that the same comparisons are used + /// throughout the compiler, as mismatches can cause ICEs, see #72540. + #[inline] + pub fn value_within_limit(&self, value: usize) -> bool { + value <= self.0 + } +} + +impl From for Limit { + fn from(value: usize) -> Self { + Self::new(value) + } +} + +impl fmt::Display for Limit { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + self.0.fmt(f) + } +} + +impl Div for Limit { + type Output = Limit; + + fn div(self, rhs: usize) -> Self::Output { + Limit::new(self.0 / rhs) + } +} + +impl Mul for Limit { + type Output = Limit; + + fn mul(self, rhs: usize) -> Self::Output { + Limit::new(self.0 * rhs) + } +} + +impl IntoDiagArg for Limit { + fn into_diag_arg(self, _: &mut Option) -> DiagArgValue { + self.to_string().into_diag_arg(&mut None) + } +} diff --git a/compiler/rustc_hir_analysis/src/autoderef.rs b/compiler/rustc_hir_analysis/src/autoderef.rs index e27e68d36624e..e8237471e1b68 100644 --- a/compiler/rustc_hir_analysis/src/autoderef.rs +++ b/compiler/rustc_hir_analysis/src/autoderef.rs @@ -1,7 +1,7 @@ +use rustc_hir::limit::Limit; use rustc_infer::infer::InferCtxt; use rustc_infer::traits::PredicateObligations; use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt}; -use rustc_session::Limit; use rustc_span::def_id::{LOCAL_CRATE, LocalDefId}; use rustc_span::{ErrorGuaranteed, Span}; use rustc_trait_selection::traits::ObligationCtxt; diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs index 6565ad7cf5367..3b6367219b7ff 100644 --- a/compiler/rustc_hir_analysis/src/errors.rs +++ b/compiler/rustc_hir_analysis/src/errors.rs @@ -6,6 +6,7 @@ use rustc_errors::{ Applicability, Diag, DiagCtxtHandle, DiagSymbolList, Diagnostic, EmissionGuarantee, Level, MultiSpan, }; +use rustc_hir::limit::Limit; use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic}; use rustc_middle::ty::Ty; use rustc_span::{Ident, Span, Symbol}; @@ -557,7 +558,7 @@ pub(crate) struct AutoDerefReachedRecursionLimit<'a> { #[label] pub span: Span, pub ty: Ty<'a>, - pub suggested_limit: rustc_session::Limit, + pub suggested_limit: Limit, pub crate_name: Symbol, } diff --git a/compiler/rustc_interface/messages.ftl b/compiler/rustc_interface/messages.ftl index 4b9c71d71725c..d83b18cbc2df6 100644 --- a/compiler/rustc_interface/messages.ftl +++ b/compiler/rustc_interface/messages.ftl @@ -30,10 +30,6 @@ interface_ignoring_out_dir = ignoring --out-dir flag due to -o flag interface_input_file_would_be_overwritten = the input file "{$path}" would be overwritten by the generated executable -interface_limit_invalid = - `limit` must be a non-negative integer - .label = {$error_str} - interface_mixed_bin_crate = cannot mix `bin` crate type with others diff --git a/compiler/rustc_interface/src/errors.rs b/compiler/rustc_interface/src/errors.rs index 6b39b4f18911c..d1082eaf6173c 100644 --- a/compiler/rustc_interface/src/errors.rs +++ b/compiler/rustc_interface/src/errors.rs @@ -108,13 +108,3 @@ pub(crate) struct AbiRequiredTargetFeature<'a> { pub feature: &'a str, pub enabled: &'a str, } - -#[derive(Diagnostic)] -#[diag(interface_limit_invalid)] -pub(crate) struct LimitInvalid<'a> { - #[primary_span] - pub span: Span, - #[label] - pub value_span: Span, - pub error_str: &'a str, -} diff --git a/compiler/rustc_interface/src/limits.rs b/compiler/rustc_interface/src/limits.rs index 8f01edec09f33..10e58f32256f1 100644 --- a/compiler/rustc_interface/src/limits.rs +++ b/compiler/rustc_interface/src/limits.rs @@ -8,78 +8,32 @@ //! Users can override these limits via an attribute on the crate like //! `#![recursion_limit="22"]`. This pass just looks for those attributes. -use std::num::IntErrorKind; - -use rustc_ast::attr::AttributeExt; -use rustc_middle::bug; +use rustc_hir::attrs::AttributeKind; +use rustc_hir::limit::Limit; +use rustc_hir::{Attribute, find_attr}; use rustc_middle::query::Providers; -use rustc_session::{Limit, Limits, Session}; -use rustc_span::{Symbol, sym}; - -use crate::errors::LimitInvalid; +use rustc_session::Limits; pub(crate) fn provide(providers: &mut Providers) { - providers.limits = |tcx, ()| Limits { - recursion_limit: get_recursion_limit(tcx.hir_krate_attrs(), tcx.sess), - move_size_limit: get_limit( - tcx.hir_krate_attrs(), - tcx.sess, - sym::move_size_limit, - Limit::new(tcx.sess.opts.unstable_opts.move_size_limit.unwrap_or(0)), - ), - type_length_limit: get_limit( - tcx.hir_krate_attrs(), - tcx.sess, - sym::type_length_limit, - Limit::new(2usize.pow(24)), - ), - pattern_complexity_limit: get_limit( - tcx.hir_krate_attrs(), - tcx.sess, - sym::pattern_complexity_limit, - Limit::unlimited(), - ), + providers.limits = |tcx, ()| { + let attrs = tcx.hir_krate_attrs(); + Limits { + recursion_limit: get_recursion_limit(tcx.hir_krate_attrs()), + move_size_limit: + find_attr!(attrs, AttributeKind::MoveSizeLimit { limit, .. } => *limit) + .unwrap_or(Limit::new(tcx.sess.opts.unstable_opts.move_size_limit.unwrap_or(0))), + type_length_limit: + find_attr!(attrs, AttributeKind::TypeLengthLimit { limit, .. } => *limit) + .unwrap_or(Limit::new(2usize.pow(24))), + pattern_complexity_limit: + find_attr!(attrs, AttributeKind::PatternComplexityLimit { limit, .. } => *limit) + .unwrap_or(Limit::unlimited()), + } } } // This one is separate because it must be read prior to macro expansion. -pub(crate) fn get_recursion_limit(krate_attrs: &[impl AttributeExt], sess: &Session) -> Limit { - get_limit(krate_attrs, sess, sym::recursion_limit, Limit::new(128)) -} - -fn get_limit( - krate_attrs: &[impl AttributeExt], - sess: &Session, - name: Symbol, - default: Limit, -) -> Limit { - for attr in krate_attrs { - if !attr.has_name(name) { - continue; - } - - if let Some(sym) = attr.value_str() { - match sym.as_str().parse() { - Ok(n) => return Limit::new(n), - Err(e) => { - let error_str = match e.kind() { - IntErrorKind::PosOverflow => "`limit` is too large", - IntErrorKind::Empty => "`limit` must be a non-negative integer", - IntErrorKind::InvalidDigit => "not a valid integer", - IntErrorKind::NegOverflow => { - bug!("`limit` should never negatively overflow") - } - IntErrorKind::Zero => bug!("zero is a valid `limit`"), - kind => bug!("unimplemented IntErrorKind variant: {:?}", kind), - }; - sess.dcx().emit_err(LimitInvalid { - span: attr.span(), - value_span: attr.value_span().unwrap(), - error_str, - }); - } - } - } - } - default +pub(crate) fn get_recursion_limit(attrs: &[Attribute]) -> Limit { + find_attr!(attrs, AttributeKind::RecursionLimit { limit, .. } => *limit) + .unwrap_or(Limit::new(128)) } diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index ca8c10311fb8f..6d9751d7d4d61 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -6,7 +6,7 @@ use std::sync::{Arc, LazyLock, OnceLock}; use std::{env, fs, iter}; use rustc_ast as ast; -use rustc_attr_parsing::{AttributeParser, ShouldEmit, validate_attr}; +use rustc_attr_parsing::{AttributeParser, ShouldEmit}; use rustc_codegen_ssa::traits::CodegenBackend; use rustc_data_structures::jobserver::Proxy; use rustc_data_structures::steal::Steal; @@ -19,6 +19,7 @@ use rustc_fs_util::try_canonicalize; use rustc_hir::attrs::AttributeKind; use rustc_hir::def_id::{LOCAL_CRATE, StableCrateId, StableCrateIdMap}; use rustc_hir::definitions::Definitions; +use rustc_hir::limit::Limit; use rustc_incremental::setup_dep_graph; use rustc_lint::{BufferedEarlyLint, EarlyCheckNode, LintStore, unerased_lint_store}; use rustc_metadata::EncodedMetadata; @@ -30,12 +31,12 @@ use rustc_middle::util::Providers; use rustc_parse::{new_parser_from_file, new_parser_from_source_str, unwrap_or_emit_fatal}; use rustc_passes::{abi_test, input_stats, layout_test}; use rustc_resolve::{Resolver, ResolverOutputs}; +use rustc_session::Session; use rustc_session::config::{CrateType, Input, OutFileName, OutputFilenames, OutputType}; use rustc_session::cstore::Untracked; use rustc_session::output::{collect_crate_types, filename_for_input}; use rustc_session::parse::feature_err; use rustc_session::search_paths::PathKind; -use rustc_session::{Limit, Session}; use rustc_span::{ DUMMY_SP, ErrorGuaranteed, ExpnKind, FileName, SourceFileHash, SourceFileHashAlgorithm, Span, Symbol, sym, @@ -1246,7 +1247,8 @@ pub fn get_crate_name(sess: &Session, krate_attrs: &[ast::Attribute]) -> Symbol // in all code paths that require the crate name very early on, namely before // macro expansion. - let attr_crate_name = parse_crate_name(sess, krate_attrs, ShouldEmit::EarlyFatal); + let attr_crate_name = + parse_crate_name(sess, krate_attrs, ShouldEmit::EarlyFatal { also_emit_lints: true }); let validate = |name, span| { rustc_session::output::validate_crate_name(sess, name, span); @@ -1307,36 +1309,18 @@ pub(crate) fn parse_crate_name( } fn get_recursion_limit(krate_attrs: &[ast::Attribute], sess: &Session) -> Limit { - // We don't permit macro calls inside of the attribute (e.g., #![recursion_limit = `expand!()`]) - // because that would require expanding this while in the middle of expansion, which needs to - // know the limit before expanding. - let _ = validate_and_find_value_str_builtin_attr(sym::recursion_limit, sess, krate_attrs); - crate::limits::get_recursion_limit(krate_attrs, sess) -} - -/// Validate *all* occurrences of the given "[value-str]" built-in attribute and return the first find. -/// -/// This validator is intended for built-in attributes whose value needs to be known very early -/// during compilation (namely, before macro expansion) and it mainly exists to reject macro calls -/// inside of the attributes, such as in `#![name = expand!()]`. Normal attribute validation happens -/// during semantic analysis via [`TyCtxt::check_mod_attrs`] which happens *after* macro expansion -/// when such macro calls (here: `expand`) have already been expanded and we can no longer check for -/// their presence. -/// -/// [value-str]: ast::Attribute::value_str -fn validate_and_find_value_str_builtin_attr( - name: Symbol, - sess: &Session, - krate_attrs: &[ast::Attribute], -) -> Option<(Symbol, Span)> { - let mut result = None; - // Validate *all* relevant attributes, not just the first occurrence. - for attr in ast::attr::filter_by_name(krate_attrs, name) { - let Some(value) = attr.value_str() else { - validate_attr::emit_fatal_malformed_builtin_attribute(&sess.psess, attr, name) - }; - // Choose the first occurrence as our result. - result.get_or_insert((value, attr.span)); - } - result + let attr = AttributeParser::parse_limited_should_emit( + sess, + &krate_attrs, + sym::recursion_limit, + DUMMY_SP, + rustc_ast::node_id::CRATE_NODE_ID, + None, + // errors are fatal here, but lints aren't. + // If things aren't fatal we continue, and will parse this again. + // That makes the same lint trigger again. + // So, no lints here to avoid duplicates. + ShouldEmit::EarlyFatal { also_emit_lints: false }, + ); + crate::limits::get_recursion_limit(attr.as_slice()) } diff --git a/compiler/rustc_middle/src/error.rs b/compiler/rustc_middle/src/error.rs index 7520bc262c6bc..dad402ec69616 100644 --- a/compiler/rustc_middle/src/error.rs +++ b/compiler/rustc_middle/src/error.rs @@ -72,7 +72,7 @@ pub enum TypeMismatchReason { #[help] pub(crate) struct RecursionLimitReached<'tcx> { pub ty: Ty<'tcx>, - pub suggested_limit: rustc_session::Limit, + pub suggested_limit: rustc_hir::limit::Limit, } #[derive(Diagnostic)] diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index de6fa4c344e69..218ac2cfbc19d 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -38,6 +38,7 @@ use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE, LocalDefId}; use rustc_hir::definitions::{DefPathData, Definitions, DisambiguatorState}; use rustc_hir::intravisit::VisitorExt; use rustc_hir::lang_items::LangItem; +use rustc_hir::limit::Limit; use rustc_hir::{self as hir, Attribute, HirId, Node, TraitCandidate, find_attr}; use rustc_index::IndexVec; use rustc_macros::{HashStable, TyDecodable, TyEncodable}; @@ -45,10 +46,10 @@ use rustc_query_system::cache::WithDepNode; use rustc_query_system::dep_graph::DepNodeIndex; use rustc_query_system::ich::StableHashingContext; use rustc_serialize::opaque::{FileEncodeResult, FileEncoder}; +use rustc_session::Session; use rustc_session::config::CrateType; use rustc_session::cstore::{CrateStoreDyn, Untracked}; use rustc_session::lint::Lint; -use rustc_session::{Limit, Session}; use rustc_span::def_id::{CRATE_DEF_ID, DefPathHash, StableCrateId}; use rustc_span::{DUMMY_SP, Ident, Span, Symbol, kw, sym}; use rustc_type_ir::TyKind::*; diff --git a/compiler/rustc_middle/src/ty/error.rs b/compiler/rustc_middle/src/ty/error.rs index 3f854038651aa..66542525d2841 100644 --- a/compiler/rustc_middle/src/ty/error.rs +++ b/compiler/rustc_middle/src/ty/error.rs @@ -7,6 +7,7 @@ use std::path::PathBuf; use rustc_errors::pluralize; use rustc_hir as hir; use rustc_hir::def::{CtorOf, DefKind}; +use rustc_hir::limit::Limit; use rustc_macros::extension; pub use rustc_type_ir::error::ExpectedFound; @@ -233,7 +234,7 @@ impl<'tcx> TyCtxt<'tcx> { loop { // Look for the longest properly trimmed path that still fits in length_limit. short = with_forced_trimmed_paths!({ - let mut p = FmtPrinter::new_with_limit(self, ns, rustc_session::Limit(type_limit)); + let mut p = FmtPrinter::new_with_limit(self, ns, Limit(type_limit)); self.lift(t) .expect("could not lift for printing") .print(&mut p) diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 74caee7336a5f..8101cabccdd02 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -13,8 +13,8 @@ use rustc_hir::LangItem; use rustc_hir::def::{self, CtorKind, DefKind, Namespace}; use rustc_hir::def_id::{DefIdMap, DefIdSet, LOCAL_CRATE, ModDefId}; use rustc_hir::definitions::{DefKey, DefPathDataName}; +use rustc_hir::limit::Limit; use rustc_macros::{Lift, extension}; -use rustc_session::Limit; use rustc_session::cstore::{ExternCrate, ExternCrateSource}; use rustc_span::{FileNameDisplayPreference, Ident, Symbol, kw, sym}; use rustc_type_ir::{Upcast as _, elaborate}; diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index a7d07adf78f02..b8c99e83a8f95 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -12,9 +12,9 @@ use rustc_hashes::Hash128; use rustc_hir as hir; use rustc_hir::def::{CtorOf, DefKind, Res}; use rustc_hir::def_id::{CrateNum, DefId, LocalDefId}; +use rustc_hir::limit::Limit; use rustc_index::bit_set::GrowableBitSet; use rustc_macros::{HashStable, TyDecodable, TyEncodable, extension}; -use rustc_session::Limit; use rustc_span::sym; use rustc_type_ir::solve::SizedTraitKind; use smallvec::{SmallVec, smallvec}; diff --git a/compiler/rustc_mir_transform/src/inline/cycle.rs b/compiler/rustc_mir_transform/src/inline/cycle.rs index 7f9234d1dc891..25a9baffe582d 100644 --- a/compiler/rustc_mir_transform/src/inline/cycle.rs +++ b/compiler/rustc_mir_transform/src/inline/cycle.rs @@ -2,9 +2,9 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet}; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_data_structures::unord::UnordSet; use rustc_hir::def_id::{DefId, LocalDefId}; +use rustc_hir::limit::Limit; use rustc_middle::mir::TerminatorKind; use rustc_middle::ty::{self, GenericArgsRef, InstanceKind, TyCtxt, TypeVisitableExt}; -use rustc_session::Limit; use rustc_span::sym; use tracing::{instrument, trace}; diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index cffeb6f980755..3169f2d4e1a44 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -217,6 +217,7 @@ use rustc_hir::attrs::InlineAttr; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, DefIdMap, LocalDefId}; use rustc_hir::lang_items::LangItem; +use rustc_hir::limit::Limit; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc_middle::mir::interpret::{AllocId, ErrorHandled, GlobalAlloc, Scalar}; use rustc_middle::mir::mono::{CollectionMode, InstantiationMode, MonoItem}; @@ -231,7 +232,6 @@ use rustc_middle::ty::{ }; use rustc_middle::util::Providers; use rustc_middle::{bug, span_bug}; -use rustc_session::Limit; use rustc_session::config::{DebugInfo, EntryFnType}; use rustc_span::source_map::{Spanned, dummy_spanned, respan}; use rustc_span::{DUMMY_SP, Span}; diff --git a/compiler/rustc_monomorphize/src/mono_checks/move_check.rs b/compiler/rustc_monomorphize/src/mono_checks/move_check.rs index 7251ef478c6f1..0adf1b089b53e 100644 --- a/compiler/rustc_monomorphize/src/mono_checks/move_check.rs +++ b/compiler/rustc_monomorphize/src/mono_checks/move_check.rs @@ -1,10 +1,10 @@ use rustc_abi::Size; use rustc_data_structures::fx::FxIndexSet; use rustc_hir::def_id::DefId; +use rustc_hir::limit::Limit; use rustc_middle::mir::visit::Visitor as MirVisitor; use rustc_middle::mir::{self, Location, traversal}; use rustc_middle::ty::{self, AssocTag, Instance, Ty, TyCtxt, TypeFoldable}; -use rustc_session::Limit; use rustc_session::lint::builtin::LARGE_ASSIGNMENTS; use rustc_span::source_map::Spanned; use rustc_span::{Ident, Span, sym}; diff --git a/compiler/rustc_query_impl/Cargo.toml b/compiler/rustc_query_impl/Cargo.toml index e5cceacf15da8..257785b10c8bc 100644 --- a/compiler/rustc_query_impl/Cargo.toml +++ b/compiler/rustc_query_impl/Cargo.toml @@ -13,7 +13,6 @@ rustc_index = { path = "../rustc_index" } rustc_middle = { path = "../rustc_middle" } rustc_query_system = { path = "../rustc_query_system" } rustc_serialize = { path = "../rustc_serialize" } -rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } tracing = "0.1" # tidy-alphabetical-end diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs index 55549cba737e6..4e601a6c59442 100644 --- a/compiler/rustc_query_impl/src/plumbing.rs +++ b/compiler/rustc_query_impl/src/plumbing.rs @@ -9,6 +9,7 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::sync::{DynSend, DynSync}; use rustc_data_structures::unord::UnordMap; use rustc_hashes::Hash64; +use rustc_hir::limit::Limit; use rustc_index::Idx; use rustc_middle::bug; use rustc_middle::dep_graph::{ @@ -31,7 +32,6 @@ use rustc_query_system::query::{ }; use rustc_query_system::{QueryOverflow, QueryOverflowNote}; use rustc_serialize::{Decodable, Encodable}; -use rustc_session::Limit; use rustc_span::def_id::LOCAL_CRATE; use crate::QueryConfigRestored; diff --git a/compiler/rustc_query_system/src/error.rs b/compiler/rustc_query_system/src/error.rs index 5108ecaeea3a1..2778b24e7741b 100644 --- a/compiler/rustc_query_system/src/error.rs +++ b/compiler/rustc_query_system/src/error.rs @@ -1,6 +1,6 @@ use rustc_errors::codes::*; +use rustc_hir::limit::Limit; use rustc_macros::{Diagnostic, Subdiagnostic}; -use rustc_session::Limit; use rustc_span::{Span, Symbol}; #[derive(Subdiagnostic)] diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index 96767d054398c..3525c7c1d1a99 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -1,10 +1,9 @@ use std::any::Any; -use std::ops::{Div, Mul}; use std::path::{Path, PathBuf}; use std::str::FromStr; use std::sync::Arc; use std::sync::atomic::AtomicBool; -use std::{env, fmt, io}; +use std::{env, io}; use rand::{RngCore, rng}; use rustc_ast::NodeId; @@ -25,6 +24,7 @@ use rustc_errors::{ Diag, DiagCtxt, DiagCtxtHandle, DiagMessage, Diagnostic, ErrorGuaranteed, FatalAbort, LintEmitter, TerminalUrl, fallback_fluent_bundle, }; +use rustc_hir::limit::Limit; use rustc_macros::HashStable_Generic; pub use rustc_span::def_id::StableCrateId; use rustc_span::edition::Edition; @@ -62,64 +62,6 @@ pub enum CtfeBacktrace { Immediate, } -/// New-type wrapper around `usize` for representing limits. Ensures that comparisons against -/// limits are consistent throughout the compiler. -#[derive(Clone, Copy, Debug, HashStable_Generic)] -pub struct Limit(pub usize); - -impl Limit { - /// Create a new limit from a `usize`. - pub fn new(value: usize) -> Self { - Limit(value) - } - - /// Create a new unlimited limit. - pub fn unlimited() -> Self { - Limit(usize::MAX) - } - - /// Check that `value` is within the limit. Ensures that the same comparisons are used - /// throughout the compiler, as mismatches can cause ICEs, see #72540. - #[inline] - pub fn value_within_limit(&self, value: usize) -> bool { - value <= self.0 - } -} - -impl From for Limit { - fn from(value: usize) -> Self { - Self::new(value) - } -} - -impl fmt::Display for Limit { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - self.0.fmt(f) - } -} - -impl Div for Limit { - type Output = Limit; - - fn div(self, rhs: usize) -> Self::Output { - Limit::new(self.0 / rhs) - } -} - -impl Mul for Limit { - type Output = Limit; - - fn mul(self, rhs: usize) -> Self::Output { - Limit::new(self.0 * rhs) - } -} - -impl rustc_errors::IntoDiagArg for Limit { - fn into_diag_arg(self, _: &mut Option) -> rustc_errors::DiagArgValue { - self.to_string().into_diag_arg(&mut None) - } -} - #[derive(Clone, Copy, Debug, HashStable_Generic)] pub struct Limits { /// The maximum recursion limit for potentially infinitely recursive diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/overflow.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/overflow.rs index 4f1f5c330e5f4..a0876d8fe7599 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/overflow.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/overflow.rs @@ -3,10 +3,10 @@ use std::fmt; use rustc_errors::{Diag, E0275, EmissionGuarantee, ErrorGuaranteed, struct_span_code_err}; use rustc_hir::def::Namespace; use rustc_hir::def_id::LOCAL_CRATE; +use rustc_hir::limit::Limit; use rustc_infer::traits::{Obligation, PredicateObligation}; use rustc_middle::ty::print::{FmtPrinter, Print}; use rustc_middle::ty::{self, TyCtxt, Upcast}; -use rustc_session::Limit; use rustc_span::Span; use tracing::debug; @@ -67,7 +67,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { // We don't need to save the type to a file, we will be talking about this type already // in a separate note when we explain the obligation, so it will be available that way. let mut p: FmtPrinter<'_, '_> = - FmtPrinter::new_with_limit(tcx, Namespace::TypeNS, rustc_session::Limit(6)); + FmtPrinter::new_with_limit(tcx, Namespace::TypeNS, Limit(6)); value.print(&mut p).unwrap(); p.into_buffer() } else { diff --git a/compiler/rustc_ty_utils/src/needs_drop.rs b/compiler/rustc_ty_utils/src/needs_drop.rs index 13d56889bd12a..0ef435b1a0e21 100644 --- a/compiler/rustc_ty_utils/src/needs_drop.rs +++ b/compiler/rustc_ty_utils/src/needs_drop.rs @@ -2,11 +2,11 @@ use rustc_data_structures::fx::FxHashSet; use rustc_hir::def_id::DefId; +use rustc_hir::limit::Limit; use rustc_middle::bug; use rustc_middle::query::Providers; use rustc_middle::ty::util::{AlwaysRequiresDrop, needs_drop_components}; use rustc_middle::ty::{self, EarlyBinder, GenericArgsRef, Ty, TyCtxt}; -use rustc_session::Limit; use rustc_span::sym; use tracing::{debug, instrument}; diff --git a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.rs b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.rs index e5dae4c0069e1..c2653dd82a9f5 100644 --- a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.rs +++ b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.rs @@ -917,50 +917,50 @@ mod no_builtins { #[recursion_limit="0200"] //~^ WARN crate-level attribute should be an inner attribute -//~| HELP add a `!` mod recursion_limit { + //~^ NOTE This attribute does not have an `!`, which means it is applied to this module mod inner { #![recursion_limit="0200"] } -//~^ WARN crate-level attribute should be in the root module +//~^ WARN the `#![recursion_limit]` attribute can only be used at the crate root #[recursion_limit="0200"] fn f() { } //~^ WARN crate-level attribute should be an inner attribute - //~| HELP add a `!` + //~| NOTE This attribute does not have an `!`, which means it is applied to this function #[recursion_limit="0200"] struct S; //~^ WARN crate-level attribute should be an inner attribute - //~| HELP add a `!` + //~| NOTE This attribute does not have an `!`, which means it is applied to this struct #[recursion_limit="0200"] type T = S; //~^ WARN crate-level attribute should be an inner attribute - //~| HELP add a `!` + //~| NOTE This attribute does not have an `!`, which means it is applied to this type alias #[recursion_limit="0200"] impl S { } //~^ WARN crate-level attribute should be an inner attribute - //~| HELP add a `!` + //~| NOTE This attribute does not have an `!`, which means it is applied to this implementation block } #[type_length_limit="0100"] //~^ WARN crate-level attribute should be an inner attribute -//~| HELP add a `!` mod type_length_limit { + //~^ NOTE This attribute does not have an `!`, which means it is applied to this module mod inner { #![type_length_limit="0100"] } -//~^ WARN crate-level attribute should be in the root module +//~^ WARN the `#![type_length_limit]` attribute can only be used at the crate root #[type_length_limit="0100"] fn f() { } //~^ WARN crate-level attribute should be an inner attribute - //~| HELP add a `!` + //~| NOTE This attribute does not have an `!`, which means it is applied to this function #[type_length_limit="0100"] struct S; //~^ WARN crate-level attribute should be an inner attribute - //~| HELP add a `!` + //~| NOTE This attribute does not have an `!`, which means it is applied to this struct #[type_length_limit="0100"] type T = S; //~^ WARN crate-level attribute should be an inner attribute - //~| HELP add a `!` + //~| NOTE This attribute does not have an `!`, which means it is applied to this type alias #[type_length_limit="0100"] impl S { } //~^ WARN crate-level attribute should be an inner attribute - //~| HELP add a `!` + //~| NOTE This attribute does not have an `!`, which means it is applied to this implementation block } fn main() {} diff --git a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr index ef74a00e5a1cd..4a3520972bf56 100644 --- a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr +++ b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr @@ -291,28 +291,6 @@ help: add a `!` LL | #![no_builtins] | + -warning: crate-level attribute should be an inner attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:918:1 - | -LL | #[recursion_limit="0200"] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - | -help: add a `!` - | -LL | #![recursion_limit="0200"] - | + - -warning: crate-level attribute should be an inner attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:942:1 - | -LL | #[type_length_limit="0100"] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -help: add a `!` - | -LL | #![type_length_limit="0100"] - | + - warning: attribute should be applied to an `extern` block with non-Rust ABI --> $DIR/issue-43106-gating-of-builtin-attrs.rs:72:1 | @@ -757,106 +735,6 @@ help: add a `!` LL | #![no_builtins] impl S { } | + -warning: crate-level attribute should be in the root module - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:922:17 - | -LL | mod inner { #![recursion_limit="0200"] } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - -warning: crate-level attribute should be an inner attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:925:5 - | -LL | #[recursion_limit="0200"] fn f() { } - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - | -help: add a `!` - | -LL | #![recursion_limit="0200"] fn f() { } - | + - -warning: crate-level attribute should be an inner attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:929:5 - | -LL | #[recursion_limit="0200"] struct S; - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - | -help: add a `!` - | -LL | #![recursion_limit="0200"] struct S; - | + - -warning: crate-level attribute should be an inner attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:933:5 - | -LL | #[recursion_limit="0200"] type T = S; - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - | -help: add a `!` - | -LL | #![recursion_limit="0200"] type T = S; - | + - -warning: crate-level attribute should be an inner attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:937:5 - | -LL | #[recursion_limit="0200"] impl S { } - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - | -help: add a `!` - | -LL | #![recursion_limit="0200"] impl S { } - | + - -warning: crate-level attribute should be in the root module - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:946:17 - | -LL | mod inner { #![type_length_limit="0100"] } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -warning: crate-level attribute should be an inner attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:949:5 - | -LL | #[type_length_limit="0100"] fn f() { } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -help: add a `!` - | -LL | #![type_length_limit="0100"] fn f() { } - | + - -warning: crate-level attribute should be an inner attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:953:5 - | -LL | #[type_length_limit="0100"] struct S; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -help: add a `!` - | -LL | #![type_length_limit="0100"] struct S; - | + - -warning: crate-level attribute should be an inner attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:957:5 - | -LL | #[type_length_limit="0100"] type T = S; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -help: add a `!` - | -LL | #![type_length_limit="0100"] type T = S; - | + - -warning: crate-level attribute should be an inner attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:961:5 - | -LL | #[type_length_limit="0100"] impl S { } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -help: add a `!` - | -LL | #![type_length_limit="0100"] impl S { } - | + - warning: `#[macro_use]` attribute cannot be used on functions --> $DIR/issue-43106-gating-of-builtin-attrs.rs:191:5 | @@ -1476,6 +1354,146 @@ note: This attribute does not have an `!`, which means it is applied to this imp LL | #[crate_name = "0900"] impl S { } | ^^^^^^^^^^ +warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![recursion_limit]` + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:918:1 + | +LL | #[recursion_limit="0200"] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: This attribute does not have an `!`, which means it is applied to this module + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:920:1 + | +LL | / mod recursion_limit { +LL | | +LL | | mod inner { #![recursion_limit="0200"] } +... | +LL | | } + | |_^ + +warning: the `#![recursion_limit]` attribute can only be used at the crate root + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:922:17 + | +LL | mod inner { #![recursion_limit="0200"] } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![recursion_limit]` + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:925:5 + | +LL | #[recursion_limit="0200"] fn f() { } + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: This attribute does not have an `!`, which means it is applied to this function + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:925:31 + | +LL | #[recursion_limit="0200"] fn f() { } + | ^^^^^^^^^^ + +warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![recursion_limit]` + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:929:5 + | +LL | #[recursion_limit="0200"] struct S; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: This attribute does not have an `!`, which means it is applied to this struct + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:929:31 + | +LL | #[recursion_limit="0200"] struct S; + | ^^^^^^^^^ + +warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![recursion_limit]` + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:933:5 + | +LL | #[recursion_limit="0200"] type T = S; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: This attribute does not have an `!`, which means it is applied to this type alias + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:933:31 + | +LL | #[recursion_limit="0200"] type T = S; + | ^^^^^^^^^^^ + +warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![recursion_limit]` + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:937:5 + | +LL | #[recursion_limit="0200"] impl S { } + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: This attribute does not have an `!`, which means it is applied to this implementation block + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:937:31 + | +LL | #[recursion_limit="0200"] impl S { } + | ^^^^^^^^^^ + +warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![type_length_limit]` + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:942:1 + | +LL | #[type_length_limit="0100"] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: This attribute does not have an `!`, which means it is applied to this module + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:944:1 + | +LL | / mod type_length_limit { +LL | | +LL | | mod inner { #![type_length_limit="0100"] } +... | +LL | | } + | |_^ + +warning: the `#![type_length_limit]` attribute can only be used at the crate root + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:946:17 + | +LL | mod inner { #![type_length_limit="0100"] } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![type_length_limit]` + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:949:5 + | +LL | #[type_length_limit="0100"] fn f() { } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: This attribute does not have an `!`, which means it is applied to this function + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:949:33 + | +LL | #[type_length_limit="0100"] fn f() { } + | ^^^^^^^^^^ + +warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![type_length_limit]` + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:953:5 + | +LL | #[type_length_limit="0100"] struct S; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: This attribute does not have an `!`, which means it is applied to this struct + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:953:33 + | +LL | #[type_length_limit="0100"] struct S; + | ^^^^^^^^^ + +warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![type_length_limit]` + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:957:5 + | +LL | #[type_length_limit="0100"] type T = S; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: This attribute does not have an `!`, which means it is applied to this type alias + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:957:33 + | +LL | #[type_length_limit="0100"] type T = S; + | ^^^^^^^^^^^ + +warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![type_length_limit]` + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:961:5 + | +LL | #[type_length_limit="0100"] impl S { } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: This attribute does not have an `!`, which means it is applied to this implementation block + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:961:33 + | +LL | #[type_length_limit="0100"] impl S { } + | ^^^^^^^^^^ + warning: `#[should_panic]` attribute cannot be used on crates --> $DIR/issue-43106-gating-of-builtin-attrs.rs:50:1 | diff --git a/tests/ui/lint/unused/unused-attr-duplicate.stderr b/tests/ui/lint/unused/unused-attr-duplicate.stderr index 203211d0d5620..076a08ac6f248 100644 --- a/tests/ui/lint/unused/unused-attr-duplicate.stderr +++ b/tests/ui/lint/unused/unused-attr-duplicate.stderr @@ -28,32 +28,6 @@ note: attribute also specified here LL | #[no_link] | ^^^^^^^^^^ -error: unused attribute - --> $DIR/unused-attr-duplicate.rs:21:1 - | -LL | #![recursion_limit = "256"] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute - | -note: attribute also specified here - --> $DIR/unused-attr-duplicate.rs:20:1 - | -LL | #![recursion_limit = "128"] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - -error: unused attribute - --> $DIR/unused-attr-duplicate.rs:24:1 - | -LL | #![type_length_limit = "1"] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute - | -note: attribute also specified here - --> $DIR/unused-attr-duplicate.rs:23:1 - | -LL | #![type_length_limit = "1048576"] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - error: unused attribute --> $DIR/unused-attr-duplicate.rs:27:1 | @@ -304,6 +278,32 @@ LL | #![crate_name = "unused_attr_duplicate"] = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +error: unused attribute + --> $DIR/unused-attr-duplicate.rs:21:1 + | +LL | #![recursion_limit = "256"] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute + | +note: attribute also specified here + --> $DIR/unused-attr-duplicate.rs:20:1 + | +LL | #![recursion_limit = "128"] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + +error: unused attribute + --> $DIR/unused-attr-duplicate.rs:24:1 + | +LL | #![type_length_limit = "1"] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute + | +note: attribute also specified here + --> $DIR/unused-attr-duplicate.rs:23:1 + | +LL | #![type_length_limit = "1048576"] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + error: unused attribute --> $DIR/unused-attr-duplicate.rs:29:1 | diff --git a/tests/ui/lint/unused/unused-attr-macro-rules.stderr b/tests/ui/lint/unused/unused-attr-macro-rules.stderr index af64be8f6e9bd..0c6825026ed3b 100644 --- a/tests/ui/lint/unused/unused-attr-macro-rules.stderr +++ b/tests/ui/lint/unused/unused-attr-macro-rules.stderr @@ -1,19 +1,3 @@ -error: crate-level attribute should be an inner attribute - --> $DIR/unused-attr-macro-rules.rs:11:1 - | -LL | #[recursion_limit="1"] - | ^^^^^^^^^^^^^^^^^^^^^^ - | -note: the lint level is defined here - --> $DIR/unused-attr-macro-rules.rs:1:9 - | -LL | #![deny(unused_attributes)] - | ^^^^^^^^^^^^^^^^^ -help: add a `!` - | -LL | #![recursion_limit="1"] - | + - error: `#[macro_use]` attribute cannot be used on macro defs --> $DIR/unused-attr-macro-rules.rs:7:1 | @@ -22,6 +6,11 @@ LL | #[macro_use] | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = help: `#[macro_use]` can be applied to modules, extern crates, and crates +note: the lint level is defined here + --> $DIR/unused-attr-macro-rules.rs:1:9 + | +LL | #![deny(unused_attributes)] + | ^^^^^^^^^^^^^^^^^ error: `#[path]` attribute cannot be used on macro defs --> $DIR/unused-attr-macro-rules.rs:9:1 @@ -32,5 +21,19 @@ LL | #[path="foo"] = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = help: `#[path]` can only be applied to modules +error: crate-level attribute should be an inner attribute: add an exclamation mark: `#![recursion_limit]` + --> $DIR/unused-attr-macro-rules.rs:11:1 + | +LL | #[recursion_limit="1"] + | ^^^^^^^^^^^^^^^^^^^^^^ + | +note: This attribute does not have an `!`, which means it is applied to this macro def + --> $DIR/unused-attr-macro-rules.rs:12:1 + | +LL | / macro_rules! foo { +LL | | () => {}; +LL | | } + | |_^ + error: aborting due to 3 previous errors diff --git a/tests/ui/recursion_limit/empty.rs b/tests/ui/recursion_limit/empty.rs index 5987fa2f881c2..a901267d847c7 100644 --- a/tests/ui/recursion_limit/empty.rs +++ b/tests/ui/recursion_limit/empty.rs @@ -1,9 +1,7 @@ // Test the parse error for an empty recursion_limit -#![recursion_limit = ""] //~ ERROR `limit` must be a non-negative integer - //~| NOTE `limit` must be a non-negative integer - //~| ERROR `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` +#![recursion_limit = ""] +//~^ ERROR `limit` must be a non-negative integer +//~| NOTE `limit` must be a non-negative integer fn main() {} diff --git a/tests/ui/recursion_limit/empty.stderr b/tests/ui/recursion_limit/empty.stderr index 2f73067750706..9afe9e6db565d 100644 --- a/tests/ui/recursion_limit/empty.stderr +++ b/tests/ui/recursion_limit/empty.stderr @@ -6,15 +6,5 @@ LL | #![recursion_limit = ""] | | | `limit` must be a non-negative integer -error: `limit` must be a non-negative integer - --> $DIR/empty.rs:3:1 - | -LL | #![recursion_limit = ""] - | ^^^^^^^^^^^^^^^^^^^^^--^ - | | - | `limit` must be a non-negative integer - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error diff --git a/tests/ui/recursion_limit/invalid_digit.rs b/tests/ui/recursion_limit/invalid_digit.rs index 79d8f3708bac6..1d0e6a18227ce 100644 --- a/tests/ui/recursion_limit/invalid_digit.rs +++ b/tests/ui/recursion_limit/invalid_digit.rs @@ -1,8 +1,6 @@ // Test the parse error for an invalid digit in recursion_limit -#![recursion_limit = "-100"] //~ ERROR `limit` must be a non-negative integer - //~| NOTE not a valid integer - //~| ERROR `limit` must be a non-negative integer - //~| NOTE not a valid integer - //~| NOTE duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +#![recursion_limit = "-100"] +//~^ ERROR `limit` must be a non-negative integer +//~| NOTE not a valid integer fn main() {} diff --git a/tests/ui/recursion_limit/invalid_digit.stderr b/tests/ui/recursion_limit/invalid_digit.stderr index 4fda3039032a8..9c2d1422df28e 100644 --- a/tests/ui/recursion_limit/invalid_digit.stderr +++ b/tests/ui/recursion_limit/invalid_digit.stderr @@ -6,15 +6,5 @@ LL | #![recursion_limit = "-100"] | | | not a valid integer -error: `limit` must be a non-negative integer - --> $DIR/invalid_digit.rs:3:1 - | -LL | #![recursion_limit = "-100"] - | ^^^^^^^^^^^^^^^^^^^^^------^ - | | - | not a valid integer - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error diff --git a/tests/ui/recursion_limit/invalid_digit_type.stderr b/tests/ui/recursion_limit/invalid_digit_type.stderr index a122262f1df45..489e8bd82c2d0 100644 --- a/tests/ui/recursion_limit/invalid_digit_type.stderr +++ b/tests/ui/recursion_limit/invalid_digit_type.stderr @@ -1,10 +1,14 @@ -error: malformed `recursion_limit` attribute input +error[E0539]: malformed `recursion_limit` attribute input --> $DIR/invalid_digit_type.rs:1:1 | LL | #![recursion_limit = 123] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#![recursion_limit = "N"]` + | ^^^^^^^^^^^^^^^^^^^^^---^ + | | | + | | expected a string literal here + | help: must be of the form: `#![recursion_limit = "N"]` | = note: for more information, visit error: aborting due to 1 previous error +For more information about this error, try `rustc --explain E0539`. diff --git a/tests/ui/recursion_limit/invalid_macro.rs b/tests/ui/recursion_limit/invalid_macro.rs index 7db67a8d16284..eae348523dbc8 100644 --- a/tests/ui/recursion_limit/invalid_macro.rs +++ b/tests/ui/recursion_limit/invalid_macro.rs @@ -1,4 +1,4 @@ -#![recursion_limit = foo!()] //~ ERROR malformed `recursion_limit` attribute +#![recursion_limit = foo!()] //~ ERROR attribute value must be a literal macro_rules! foo { () => {"128"}; diff --git a/tests/ui/recursion_limit/invalid_macro.stderr b/tests/ui/recursion_limit/invalid_macro.stderr index b4dbc9fcb1346..de1df3e9a3586 100644 --- a/tests/ui/recursion_limit/invalid_macro.stderr +++ b/tests/ui/recursion_limit/invalid_macro.stderr @@ -1,10 +1,8 @@ -error: malformed `recursion_limit` attribute input - --> $DIR/invalid_macro.rs:1:1 +error: attribute value must be a literal + --> $DIR/invalid_macro.rs:1:22 | LL | #![recursion_limit = foo!()] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#![recursion_limit = "N"]` - | - = note: for more information, visit + | ^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/recursion_limit/no-value.stderr b/tests/ui/recursion_limit/no-value.stderr index 4a0ad04f2715b..eafc50bafb49d 100644 --- a/tests/ui/recursion_limit/no-value.stderr +++ b/tests/ui/recursion_limit/no-value.stderr @@ -1,4 +1,4 @@ -error: malformed `recursion_limit` attribute input +error[E0539]: malformed `recursion_limit` attribute input --> $DIR/no-value.rs:3:1 | LL | #![recursion_limit] @@ -8,3 +8,4 @@ LL | #![recursion_limit] error: aborting due to 1 previous error +For more information about this error, try `rustc --explain E0539`. diff --git a/tests/ui/recursion_limit/overflow.rs b/tests/ui/recursion_limit/overflow.rs index 7cd1d572e0971..24cb8e286a895 100644 --- a/tests/ui/recursion_limit/overflow.rs +++ b/tests/ui/recursion_limit/overflow.rs @@ -3,8 +3,5 @@ #![recursion_limit = "999999999999999999999999"] //~^ ERROR `limit` must be a non-negative integer //~| NOTE `limit` is too large -//~| ERROR `limit` must be a non-negative integer -//~| NOTE `limit` is too large -//~| NOTE duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` fn main() {} diff --git a/tests/ui/recursion_limit/overflow.stderr b/tests/ui/recursion_limit/overflow.stderr index 6057177deb2f9..5a8548b7c7f1e 100644 --- a/tests/ui/recursion_limit/overflow.stderr +++ b/tests/ui/recursion_limit/overflow.stderr @@ -6,15 +6,5 @@ LL | #![recursion_limit = "999999999999999999999999"] | | | `limit` is too large -error: `limit` must be a non-negative integer - --> $DIR/overflow.rs:3:1 - | -LL | #![recursion_limit = "999999999999999999999999"] - | ^^^^^^^^^^^^^^^^^^^^^--------------------------^ - | | - | `limit` is too large - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error