From a375d1d15e67d9cf3013976c8231449edfec6c37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= <39484203+jieyouxu@users.noreply.github.com> Date: Sun, 2 Feb 2025 22:04:09 +0800 Subject: [PATCH 01/10] compiletest: cleanup `is_rustdoc` logic --- src/tools/compiletest/src/runtest.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index ca48abda5fc16..0e2da2b02ca0f 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -1417,9 +1417,7 @@ impl<'test> TestCx<'test> { } fn is_rustdoc(&self) -> bool { - self.config.src_base.ends_with("rustdoc-ui") - || self.config.src_base.ends_with("rustdoc-js") - || self.config.src_base.ends_with("rustdoc-json") + matches!(self.config.suite.as_str(), "rustdoc-ui" | "rustdoc-js" | "rustdoc-json") } fn get_mir_dump_dir(&self) -> PathBuf { From 788a38953f11cef41663cb912d51126cb595fef4 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 2 Feb 2025 14:23:59 +0100 Subject: [PATCH 02/10] miri: improve error when offset_from preconditions are violated --- compiler/rustc_const_eval/messages.ftl | 4 +++- .../src/interpret/intrinsics.rs | 20 ++++++++++++++++++- .../ptr_offset_from_different_allocs.rs | 5 +++++ .../ptr_offset_from_different_allocs.stderr | 15 ++++++++++++++ .../ptr_offset_from_different_ints.rs | 2 +- .../ptr_offset_from_different_ints.stderr | 4 ++-- .../fail/intrinsics/ptr_offset_from_oob.rs | 7 +++++++ .../intrinsics/ptr_offset_from_oob.stderr | 15 ++++++++++++++ tests/ui/const-ptr/forbidden_slices.stderr | 4 ++-- tests/ui/consts/offset_from_ub.rs | 10 +++++----- tests/ui/consts/offset_from_ub.stderr | 14 ++++++------- 11 files changed, 81 insertions(+), 19 deletions(-) create mode 100644 src/tools/miri/tests/fail/intrinsics/ptr_offset_from_different_allocs.rs create mode 100644 src/tools/miri/tests/fail/intrinsics/ptr_offset_from_different_allocs.stderr create mode 100644 src/tools/miri/tests/fail/intrinsics/ptr_offset_from_oob.rs create mode 100644 src/tools/miri/tests/fail/intrinsics/ptr_offset_from_oob.stderr diff --git a/compiler/rustc_const_eval/messages.ftl b/compiler/rustc_const_eval/messages.ftl index d600d223bffd3..eecc6690f5153 100644 --- a/compiler/rustc_const_eval/messages.ftl +++ b/compiler/rustc_const_eval/messages.ftl @@ -280,7 +280,9 @@ const_eval_nullary_intrinsic_fail = could not evaluate nullary intrinsic const_eval_offset_from_different_allocations = - `{$name}` called on pointers into different allocations + `{$name}` called on two different pointers that are not both derived from the same allocation +const_eval_offset_from_out_of_bounds = + `{$name}` called on two different pointers where the memory range between them is not in-bounds of an allocation const_eval_offset_from_overflow = `{$name}` called when first pointer is too far ahead of second const_eval_offset_from_test = diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs index 9f5f2533e085b..4ca317e3a1e53 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs @@ -319,7 +319,25 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { // Check that the memory between them is dereferenceable at all, starting from the // origin pointer: `dist` is `a - b`, so it is based on `b`. - self.check_ptr_access_signed(b, dist, CheckInAllocMsg::OffsetFromTest)?; + self.check_ptr_access_signed(b, dist, CheckInAllocMsg::OffsetFromTest) + .map_err_kind(|_| { + // This could mean they point to different allocations, or they point to the same allocation + // but not the entire range between the pointers is in-bounds. + if let Ok((a_alloc_id, ..)) = self.ptr_try_get_alloc_id(a, 0) + && let Ok((b_alloc_id, ..)) = self.ptr_try_get_alloc_id(b, 0) + && a_alloc_id == b_alloc_id + { + err_ub_custom!( + fluent::const_eval_offset_from_out_of_bounds, + name = intrinsic_name, + ) + } else { + err_ub_custom!( + fluent::const_eval_offset_from_different_allocations, + name = intrinsic_name, + ) + } + })?; // Then check that this is also dereferenceable from `a`. This ensures that they are // derived from the same allocation. self.check_ptr_access_signed( diff --git a/src/tools/miri/tests/fail/intrinsics/ptr_offset_from_different_allocs.rs b/src/tools/miri/tests/fail/intrinsics/ptr_offset_from_different_allocs.rs new file mode 100644 index 0000000000000..5a997ad8ec40c --- /dev/null +++ b/src/tools/miri/tests/fail/intrinsics/ptr_offset_from_different_allocs.rs @@ -0,0 +1,5 @@ +fn main() { + unsafe { + (&1_u8 as *const u8).offset_from(&2_u8); //~ERROR: not both derived from the same allocation + } +} diff --git a/src/tools/miri/tests/fail/intrinsics/ptr_offset_from_different_allocs.stderr b/src/tools/miri/tests/fail/intrinsics/ptr_offset_from_different_allocs.stderr new file mode 100644 index 0000000000000..34d7c6a8021d1 --- /dev/null +++ b/src/tools/miri/tests/fail/intrinsics/ptr_offset_from_different_allocs.stderr @@ -0,0 +1,15 @@ +error: Undefined Behavior: `ptr_offset_from` called on two different pointers that are not both derived from the same allocation + --> tests/fail/intrinsics/ptr_offset_from_different_allocs.rs:LL:CC + | +LL | (&1_u8 as *const u8).offset_from(&2_u8); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `ptr_offset_from` called on two different pointers that are not both derived from the same allocation + | + = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior + = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information + = note: BACKTRACE: + = note: inside `main` at tests/fail/intrinsics/ptr_offset_from_different_allocs.rs:LL:CC + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 1 previous error + diff --git a/src/tools/miri/tests/fail/intrinsics/ptr_offset_from_different_ints.rs b/src/tools/miri/tests/fail/intrinsics/ptr_offset_from_different_ints.rs index 0acda559d3a51..0d34e711ca79c 100644 --- a/src/tools/miri/tests/fail/intrinsics/ptr_offset_from_different_ints.rs +++ b/src/tools/miri/tests/fail/intrinsics/ptr_offset_from_different_ints.rs @@ -15,6 +15,6 @@ fn main() { let _ = p1.byte_offset_from(p1); // UB because different pointers. - let _ = p1.byte_offset_from(p2); //~ERROR: no provenance + let _ = p1.byte_offset_from(p2); //~ERROR: not both derived from the same allocation } } diff --git a/src/tools/miri/tests/fail/intrinsics/ptr_offset_from_different_ints.stderr b/src/tools/miri/tests/fail/intrinsics/ptr_offset_from_different_ints.stderr index 7ef66390fcda0..897945d6d5da2 100644 --- a/src/tools/miri/tests/fail/intrinsics/ptr_offset_from_different_ints.stderr +++ b/src/tools/miri/tests/fail/intrinsics/ptr_offset_from_different_ints.stderr @@ -1,8 +1,8 @@ -error: Undefined Behavior: out-of-bounds `offset_from` origin: expected a pointer to the end of 1 byte of memory, but got 0xb[noalloc] which is a dangling pointer (it has no provenance) +error: Undefined Behavior: `ptr_offset_from` called on two different pointers that are not both derived from the same allocation --> tests/fail/intrinsics/ptr_offset_from_different_ints.rs:LL:CC | LL | let _ = p1.byte_offset_from(p2); - | ^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds `offset_from` origin: expected a pointer to the end of 1 byte of memory, but got 0xb[noalloc] which is a dangling pointer (it has no provenance) + | ^^^^^^^^^^^^^^^^^^^^^^^ `ptr_offset_from` called on two different pointers that are not both derived from the same allocation | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/src/tools/miri/tests/fail/intrinsics/ptr_offset_from_oob.rs b/src/tools/miri/tests/fail/intrinsics/ptr_offset_from_oob.rs new file mode 100644 index 0000000000000..06f6b7a011746 --- /dev/null +++ b/src/tools/miri/tests/fail/intrinsics/ptr_offset_from_oob.rs @@ -0,0 +1,7 @@ +fn main() { + let mem = [0u8; 1]; + let ptr = mem.as_ptr(); + unsafe { + ptr.wrapping_add(4).offset_from(ptr); //~ERROR: the memory range between them is not in-bounds of an allocation + } +} diff --git a/src/tools/miri/tests/fail/intrinsics/ptr_offset_from_oob.stderr b/src/tools/miri/tests/fail/intrinsics/ptr_offset_from_oob.stderr new file mode 100644 index 0000000000000..67df633bef5b6 --- /dev/null +++ b/src/tools/miri/tests/fail/intrinsics/ptr_offset_from_oob.stderr @@ -0,0 +1,15 @@ +error: Undefined Behavior: `ptr_offset_from` called on two different pointers where the memory range between them is not in-bounds of an allocation + --> tests/fail/intrinsics/ptr_offset_from_oob.rs:LL:CC + | +LL | ptr.wrapping_add(4).offset_from(ptr); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `ptr_offset_from` called on two different pointers where the memory range between them is not in-bounds of an allocation + | + = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior + = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information + = note: BACKTRACE: + = note: inside `main` at tests/fail/intrinsics/ptr_offset_from_oob.rs:LL:CC + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 1 previous error + diff --git a/tests/ui/const-ptr/forbidden_slices.stderr b/tests/ui/const-ptr/forbidden_slices.stderr index fad078ad2b2bd..2e0c04dcf1ea9 100644 --- a/tests/ui/const-ptr/forbidden_slices.stderr +++ b/tests/ui/const-ptr/forbidden_slices.stderr @@ -190,7 +190,7 @@ LL | from_ptr_range(ptr..ptr.add(1)) error[E0080]: could not evaluate static initializer --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL | - = note: `ptr_offset_from_unsigned` called on pointers into different allocations + = note: `ptr_offset_from_unsigned` called on two different pointers that are not both derived from the same allocation | note: inside `std::ptr::const_ptr::::sub_ptr` --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL @@ -205,7 +205,7 @@ LL | pub static R9: &[u32] = unsafe { from_ptr_range(&D0..(&D0 as *const u32).ad error[E0080]: could not evaluate static initializer --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL | - = note: `ptr_offset_from_unsigned` called on pointers into different allocations + = note: `ptr_offset_from_unsigned` called on two different pointers that are not both derived from the same allocation | note: inside `std::ptr::const_ptr::::sub_ptr` --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL diff --git a/tests/ui/consts/offset_from_ub.rs b/tests/ui/consts/offset_from_ub.rs index 0232b03a813e8..8835690060505 100644 --- a/tests/ui/consts/offset_from_ub.rs +++ b/tests/ui/consts/offset_from_ub.rs @@ -17,7 +17,7 @@ pub const DIFFERENT_ALLOC: usize = { let uninit2 = std::mem::MaybeUninit::::uninit(); let field_ptr: *const Struct = &uninit2 as *const _ as *const Struct; let offset = unsafe { ptr_offset_from(field_ptr, base_ptr) }; //~ERROR evaluation of constant value failed - //~| pointers into different allocations + //~| not both derived from the same allocation offset as usize }; @@ -37,7 +37,7 @@ pub const DIFFERENT_INT: isize = { // offset_from with two different integers: l let ptr1 = 8 as *const u8; let ptr2 = 16 as *const u8; unsafe { ptr_offset_from(ptr2, ptr1) } //~ERROR evaluation of constant value failed - //~| dangling pointer + //~| not both derived from the same allocation }; const OUT_OF_BOUNDS_1: isize = { @@ -46,7 +46,7 @@ const OUT_OF_BOUNDS_1: isize = { let end_ptr = (start_ptr).wrapping_add(length); // First ptr is out of bounds unsafe { ptr_offset_from(end_ptr, start_ptr) } //~ERROR evaluation of constant value failed - //~| expected a pointer to 10 bytes of memory + //~| the memory range between them is not in-bounds of an allocation }; const OUT_OF_BOUNDS_2: isize = { @@ -55,7 +55,7 @@ const OUT_OF_BOUNDS_2: isize = { let end_ptr = (start_ptr).wrapping_add(length); // Second ptr is out of bounds unsafe { ptr_offset_from(start_ptr, end_ptr) } //~ERROR evaluation of constant value failed - //~| expected a pointer to the end of 10 bytes of memory + //~| the memory range between them is not in-bounds of an allocation }; pub const DIFFERENT_ALLOC_UNSIGNED: usize = { @@ -64,7 +64,7 @@ pub const DIFFERENT_ALLOC_UNSIGNED: usize = { let uninit2 = std::mem::MaybeUninit::::uninit(); let field_ptr: *const Struct = &uninit2 as *const _ as *const Struct; unsafe { ptr_offset_from_unsigned(field_ptr, base_ptr) } //~ERROR evaluation of constant value failed - //~| pointers into different allocations + //~| not both derived from the same allocation }; pub const TOO_FAR_APART1: isize = { diff --git a/tests/ui/consts/offset_from_ub.stderr b/tests/ui/consts/offset_from_ub.stderr index ac4597ff0119a..1379365cc25cc 100644 --- a/tests/ui/consts/offset_from_ub.stderr +++ b/tests/ui/consts/offset_from_ub.stderr @@ -2,12 +2,12 @@ error[E0080]: evaluation of constant value failed --> $DIR/offset_from_ub.rs:19:27 | LL | let offset = unsafe { ptr_offset_from(field_ptr, base_ptr) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `ptr_offset_from` called on pointers into different allocations + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `ptr_offset_from` called on two different pointers that are not both derived from the same allocation error[E0080]: evaluation of constant value failed --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL | - = note: `ptr_offset_from` called on pointers into different allocations + = note: `ptr_offset_from` called on two different pointers that are not both derived from the same allocation | note: inside `std::ptr::const_ptr::::offset_from` --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL @@ -27,25 +27,25 @@ error[E0080]: evaluation of constant value failed --> $DIR/offset_from_ub.rs:39:14 | LL | unsafe { ptr_offset_from(ptr2, ptr1) } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds `offset_from` origin: expected a pointer to $BYTES bytes of memory, but got 0x8[noalloc] which is a dangling pointer (it has no provenance) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `ptr_offset_from` called on two different pointers that are not both derived from the same allocation error[E0080]: evaluation of constant value failed --> $DIR/offset_from_ub.rs:48:14 | LL | unsafe { ptr_offset_from(end_ptr, start_ptr) } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds `offset_from` origin: expected a pointer to $BYTES bytes of memory, but got ALLOC0 which is only $BYTES bytes from the end of the allocation + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `ptr_offset_from` called on two different pointers where the memory range between them is not in-bounds of an allocation error[E0080]: evaluation of constant value failed --> $DIR/offset_from_ub.rs:57:14 | LL | unsafe { ptr_offset_from(start_ptr, end_ptr) } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds `offset_from` origin: expected a pointer to the end of $BYTES bytes of memory, but got ALLOC1+0xa which does not have enough space to the beginning of the allocation + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `ptr_offset_from` called on two different pointers where the memory range between them is not in-bounds of an allocation error[E0080]: evaluation of constant value failed --> $DIR/offset_from_ub.rs:66:14 | LL | unsafe { ptr_offset_from_unsigned(field_ptr, base_ptr) } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `ptr_offset_from_unsigned` called on pointers into different allocations + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `ptr_offset_from_unsigned` called on two different pointers that are not both derived from the same allocation error[E0080]: evaluation of constant value failed --> $DIR/offset_from_ub.rs:73:14 @@ -80,7 +80,7 @@ LL | unsafe { ptr_offset_from_unsigned(ptr2, ptr1) } error[E0080]: evaluation of constant value failed --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL | - = note: out-of-bounds `offset_from` origin: expected a pointer to $BYTES bytes of memory, but got a null pointer + = note: `ptr_offset_from` called on two different pointers that are not both derived from the same allocation | note: inside `std::ptr::const_ptr::::offset_from` --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL From 4d0cb4213b14457db5eb3ad21b1a65d5a91dd1ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= <39484203+jieyouxu@users.noreply.github.com> Date: Sun, 2 Feb 2025 22:16:48 +0800 Subject: [PATCH 03/10] compiletest: remove useless path join in `rustdoc_json` runtest logic --- src/tools/compiletest/src/runtest/rustdoc_json.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/tools/compiletest/src/runtest/rustdoc_json.rs b/src/tools/compiletest/src/runtest/rustdoc_json.rs index 31fdb0a5d13bd..bf7eb2e109a46 100644 --- a/src/tools/compiletest/src/runtest/rustdoc_json.rs +++ b/src/tools/compiletest/src/runtest/rustdoc_json.rs @@ -16,13 +16,12 @@ impl TestCx<'_> { self.fatal_proc_rec("rustdoc failed!", &proc_res); } - let root = self.config.find_rust_src_root().unwrap(); let mut json_out = out_dir.join(self.testpaths.file.file_stem().unwrap()); json_out.set_extension("json"); let res = self.run_command_to_procres( Command::new(self.config.jsondocck_path.as_ref().unwrap()) .arg("--doc-dir") - .arg(root.join(&out_dir)) + .arg(&out_dir) .arg("--template") .arg(&self.testpaths.file), ); From 17e4aec4492c23c27b17e3f58e6992aa9a559928 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 3 Feb 2025 09:02:34 +1100 Subject: [PATCH 04/10] `TypeVisitable` doesn't require `Clone`. `TypeFoldable` does, because it involves the production of new values. But `TypeVisitable` only involves the visiting of values. --- compiler/rustc_type_ir/src/fold.rs | 2 +- compiler/rustc_type_ir/src/visit.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_type_ir/src/fold.rs b/compiler/rustc_type_ir/src/fold.rs index d337a1a8ad9b7..711e42ff05581 100644 --- a/compiler/rustc_type_ir/src/fold.rs +++ b/compiler/rustc_type_ir/src/fold.rs @@ -73,7 +73,7 @@ type Never = std::convert::Infallible; /// which means in practice almost every foldable type needs to also be /// visitable. (However, there are some types that are visitable without being /// foldable.) -pub trait TypeFoldable: TypeVisitable { +pub trait TypeFoldable: TypeVisitable + Clone { /// The entry point for folding. To fold a value `t` with a folder `f` /// call: `t.try_fold_with(f)`. /// diff --git a/compiler/rustc_type_ir/src/visit.rs b/compiler/rustc_type_ir/src/visit.rs index 3213638afb258..0a07494217051 100644 --- a/compiler/rustc_type_ir/src/visit.rs +++ b/compiler/rustc_type_ir/src/visit.rs @@ -59,7 +59,7 @@ use crate::{self as ty, Interner, TypeFlags}; /// /// To implement this conveniently, use the derive macro located in /// `rustc_macros`. -pub trait TypeVisitable: fmt::Debug + Clone { +pub trait TypeVisitable: fmt::Debug { /// The entry point for visiting. To visit a value `t` with a visitor `v` /// call: `t.visit_with(v)`. /// From f0b6d660c9c13ab7b19da9e12aeb4dcab45e544b Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 3 Feb 2025 08:59:17 +1100 Subject: [PATCH 05/10] Derive `Clone` on fewer THIR types. Some of these were never necessary, and some were facilitated by the previous commit. --- compiler/rustc_middle/src/thir.rs | 44 +++++++++++++++---------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs index 86014c34b4584..89df9bab53a5c 100644 --- a/compiler/rustc_middle/src/thir.rs +++ b/compiler/rustc_middle/src/thir.rs @@ -18,7 +18,7 @@ use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_hir::{BindingMode, ByRef, HirId, MatchSource, RangeEnd}; use rustc_index::{IndexVec, newtype_index}; -use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeVisitable}; +use rustc_macros::{HashStable, TypeVisitable}; use rustc_middle::middle::region; use rustc_middle::mir::interpret::AllocId; use rustc_middle::mir::{self, BinOp, BorrowKind, FakeReadCause, UnOp}; @@ -53,7 +53,7 @@ macro_rules! thir_with_elements { /// A container for a THIR body. /// /// This can be indexed directly by any THIR index (e.g. [`ExprId`]). - #[derive(Debug, HashStable, Clone)] + #[derive(Debug, HashStable)] pub struct Thir<'tcx> { $( pub $field_name: $field_ty, @@ -98,14 +98,14 @@ thir_with_elements! { params: ParamId => Param<'tcx> => "p{}", } -#[derive(Debug, HashStable, Clone)] +#[derive(Debug, HashStable)] pub enum BodyTy<'tcx> { Const(Ty<'tcx>), Fn(FnSig<'tcx>), } /// Description of a type-checked function parameter. -#[derive(Clone, Debug, HashStable)] +#[derive(Debug, HashStable)] pub struct Param<'tcx> { /// The pattern that appears in the parameter list, or None for implicit parameters. pub pat: Option>>, @@ -125,7 +125,7 @@ pub enum LintLevel { Explicit(HirId), } -#[derive(Clone, Debug, HashStable)] +#[derive(Debug, HashStable)] pub struct Block { /// Whether the block itself has a label. Used by `label: {}` /// and `try` blocks. @@ -145,7 +145,7 @@ pub struct Block { type UserTy<'tcx> = Option>>; -#[derive(Clone, Debug, HashStable)] +#[derive(Debug, HashStable)] pub struct AdtExpr<'tcx> { /// The ADT we're constructing. pub adt_def: AdtDef<'tcx>, @@ -162,7 +162,7 @@ pub struct AdtExpr<'tcx> { pub base: AdtExprBase<'tcx>, } -#[derive(Clone, Debug, HashStable)] +#[derive(Debug, HashStable)] pub enum AdtExprBase<'tcx> { /// A struct expression where all the fields are explicitly enumerated: `Foo { a, b }`. None, @@ -175,7 +175,7 @@ pub enum AdtExprBase<'tcx> { DefaultFields(Box<[Ty<'tcx>]>), } -#[derive(Clone, Debug, HashStable)] +#[derive(Debug, HashStable)] pub struct ClosureExpr<'tcx> { pub closure_id: LocalDefId, pub args: UpvarArgs<'tcx>, @@ -184,7 +184,7 @@ pub struct ClosureExpr<'tcx> { pub fake_reads: Vec<(ExprId, FakeReadCause, HirId)>, } -#[derive(Clone, Debug, HashStable)] +#[derive(Debug, HashStable)] pub struct InlineAsmExpr<'tcx> { pub asm_macro: AsmMacro, pub template: &'tcx [InlineAsmTemplatePiece], @@ -202,12 +202,12 @@ pub enum BlockSafety { ExplicitUnsafe(HirId), } -#[derive(Clone, Debug, HashStable)] +#[derive(Debug, HashStable)] pub struct Stmt<'tcx> { pub kind: StmtKind<'tcx>, } -#[derive(Clone, Debug, HashStable)] +#[derive(Debug, HashStable)] pub enum StmtKind<'tcx> { /// An expression with a trailing semicolon. Expr { @@ -247,11 +247,11 @@ pub enum StmtKind<'tcx> { }, } -#[derive(Clone, Debug, Copy, PartialEq, Eq, Hash, HashStable, TyEncodable, TyDecodable)] +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, HashStable)] pub struct LocalVarId(pub HirId); /// A THIR expression. -#[derive(Clone, Debug, HashStable)] +#[derive(Debug, HashStable)] pub struct Expr<'tcx> { /// kind of expression pub kind: ExprKind<'tcx>, @@ -278,7 +278,7 @@ pub struct TempLifetime { pub backwards_incompatible: Option, } -#[derive(Clone, Debug, HashStable)] +#[derive(Debug, HashStable)] pub enum ExprKind<'tcx> { /// `Scope`s are used to explicitly mark destruction scopes, /// and to track the `HirId` of the expressions within the scope. @@ -543,20 +543,20 @@ pub enum ExprKind<'tcx> { /// Represents the association of a field identifier and an expression. /// /// This is used in struct constructors. -#[derive(Clone, Debug, HashStable)] +#[derive(Debug, HashStable)] pub struct FieldExpr { pub name: FieldIdx, pub expr: ExprId, } -#[derive(Clone, Debug, HashStable)] +#[derive(Debug, HashStable)] pub struct FruInfo<'tcx> { pub base: ExprId, pub field_types: Box<[Ty<'tcx>]>, } /// A `match` arm. -#[derive(Clone, Debug, HashStable)] +#[derive(Debug, HashStable)] pub struct Arm<'tcx> { pub pattern: Box>, pub guard: Option, @@ -574,7 +574,7 @@ pub enum LogicalOp { Or, } -#[derive(Clone, Debug, HashStable)] +#[derive(Debug, HashStable)] pub enum InlineAsmOperand<'tcx> { In { reg: InlineAsmRegOrRegClass, @@ -612,13 +612,13 @@ pub enum InlineAsmOperand<'tcx> { }, } -#[derive(Clone, Debug, HashStable, TypeVisitable)] +#[derive(Debug, HashStable, TypeVisitable)] pub struct FieldPat<'tcx> { pub field: FieldIdx, pub pattern: Box>, } -#[derive(Clone, Debug, HashStable, TypeVisitable)] +#[derive(Debug, HashStable, TypeVisitable)] pub struct Pat<'tcx> { pub ty: Ty<'tcx>, pub span: Span, @@ -726,7 +726,7 @@ impl<'tcx> Pat<'tcx> { } } -#[derive(Clone, Debug, HashStable, TypeVisitable)] +#[derive(Debug, HashStable, TypeVisitable)] pub struct Ascription<'tcx> { pub annotation: CanonicalUserTypeAnnotation<'tcx>, /// Variance to use when relating the `user_ty` to the **type of the value being @@ -750,7 +750,7 @@ pub struct Ascription<'tcx> { pub variance: ty::Variance, } -#[derive(Clone, Debug, HashStable, TypeVisitable)] +#[derive(Debug, HashStable, TypeVisitable)] pub enum PatKind<'tcx> { /// A wildcard pattern: `_`. Wild, From c371363650a580f9908f985af94e065e8beed0a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= Date: Sun, 2 Feb 2025 12:27:27 +0100 Subject: [PATCH 06/10] LTA: Check where-clauses for well-formedness at the def site --- .../rustc_hir_analysis/src/check/wfcheck.rs | 24 ++++++++++--------- .../def-site-param-defaults-wf.rs | 9 +++++++ .../def-site-param-defaults-wf.stderr | 20 ++++++++++++++++ .../lazy-type-alias/def-site-predicates-wf.rs | 13 ++++++++++ .../def-site-predicates-wf.stderr | 23 ++++++++++++++++++ 5 files changed, 78 insertions(+), 11 deletions(-) create mode 100644 tests/ui/lazy-type-alias/def-site-param-defaults-wf.rs create mode 100644 tests/ui/lazy-type-alias/def-site-param-defaults-wf.stderr create mode 100644 tests/ui/lazy-type-alias/def-site-predicates-wf.rs create mode 100644 tests/ui/lazy-type-alias/def-site-predicates-wf.stderr diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index c9837ca3716c6..121d23cd83d50 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -328,16 +328,20 @@ fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) -> Result<() hir::ItemKind::TraitAlias(..) => check_trait(tcx, item), // `ForeignItem`s are handled separately. hir::ItemKind::ForeignMod { .. } => Ok(()), - hir::ItemKind::TyAlias(hir_ty, hir_generics) => { - if tcx.type_alias_is_lazy(item.owner_id) { - // Bounds of lazy type aliases and of eager ones that contain opaque types are respected. - // E.g: `type X = impl Trait;`, `type X = (impl Trait, Y);`. - let res = check_item_type(tcx, def_id, hir_ty.span, UnsizedHandling::Allow); - check_variances_for_type_defn(tcx, item, hir_generics); - res - } else { + hir::ItemKind::TyAlias(hir_ty, hir_generics) if tcx.type_alias_is_lazy(item.owner_id) => { + let res = enter_wf_checking_ctxt(tcx, item.span, def_id, |wfcx| { + let ty = tcx.type_of(def_id).instantiate_identity(); + let item_ty = wfcx.normalize(hir_ty.span, Some(WellFormedLoc::Ty(def_id)), ty); + wfcx.register_wf_obligation( + hir_ty.span, + Some(WellFormedLoc::Ty(def_id)), + item_ty.into(), + ); + check_where_clauses(wfcx, item.span, def_id); Ok(()) - } + }); + check_variances_for_type_defn(tcx, item, hir_generics); + res } _ => Ok(()), }; @@ -1276,7 +1280,6 @@ fn check_item_fn( enum UnsizedHandling { Forbid, - Allow, AllowIfForeignTail, } @@ -1294,7 +1297,6 @@ fn check_item_type( let forbid_unsized = match unsized_handling { UnsizedHandling::Forbid => true, - UnsizedHandling::Allow => false, UnsizedHandling::AllowIfForeignTail => { let tail = tcx.struct_tail_for_codegen(item_ty, wfcx.infcx.typing_env(wfcx.param_env)); diff --git a/tests/ui/lazy-type-alias/def-site-param-defaults-wf.rs b/tests/ui/lazy-type-alias/def-site-param-defaults-wf.rs new file mode 100644 index 0000000000000..90bb0a294f810 --- /dev/null +++ b/tests/ui/lazy-type-alias/def-site-param-defaults-wf.rs @@ -0,0 +1,9 @@ +//! Ensure that we check generic parameter defaults for well-formedness at the definition site. +#![feature(lazy_type_alias)] +#![allow(incomplete_features)] + +type Alias, const N: usize = {0 - 1}> = T; +//~^ ERROR evaluation of constant value failed +//~| ERROR the size for values of type `str` cannot be known at compilation time + +fn main() {} diff --git a/tests/ui/lazy-type-alias/def-site-param-defaults-wf.stderr b/tests/ui/lazy-type-alias/def-site-param-defaults-wf.stderr new file mode 100644 index 0000000000000..da0021ccaf4d3 --- /dev/null +++ b/tests/ui/lazy-type-alias/def-site-param-defaults-wf.stderr @@ -0,0 +1,20 @@ +error[E0080]: evaluation of constant value failed + --> $DIR/def-site-param-defaults-wf.rs:5:44 + | +LL | type Alias, const N: usize = {0 - 1}> = T; + | ^^^^^ attempt to compute `0_usize - 1_usize`, which would overflow + +error[E0277]: the size for values of type `str` cannot be known at compilation time + --> $DIR/def-site-param-defaults-wf.rs:5:16 + | +LL | type Alias, const N: usize = {0 - 1}> = T; + | ^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `str` +note: required by an implicit `Sized` bound in `Vec` + --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0080, E0277. +For more information about an error, try `rustc --explain E0080`. diff --git a/tests/ui/lazy-type-alias/def-site-predicates-wf.rs b/tests/ui/lazy-type-alias/def-site-predicates-wf.rs new file mode 100644 index 0000000000000..5d9235347cb82 --- /dev/null +++ b/tests/ui/lazy-type-alias/def-site-predicates-wf.rs @@ -0,0 +1,13 @@ +//! Ensure that we check the predicates at the definition site for well-formedness. +#![feature(lazy_type_alias)] +#![allow(incomplete_features)] + +type Alias0 = () +where + Vec:; //~ ERROR the size for values of type `str` cannot be known at compilation time + +type Alias1 = () +where + Vec: Sized; //~ ERROR the size for values of type `str` cannot be known at compilation time + +fn main() {} diff --git a/tests/ui/lazy-type-alias/def-site-predicates-wf.stderr b/tests/ui/lazy-type-alias/def-site-predicates-wf.stderr new file mode 100644 index 0000000000000..b44e702c35cb4 --- /dev/null +++ b/tests/ui/lazy-type-alias/def-site-predicates-wf.stderr @@ -0,0 +1,23 @@ +error[E0277]: the size for values of type `str` cannot be known at compilation time + --> $DIR/def-site-predicates-wf.rs:7:5 + | +LL | Vec:; + | ^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `str` +note: required by an implicit `Sized` bound in `Vec` + --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL + +error[E0277]: the size for values of type `str` cannot be known at compilation time + --> $DIR/def-site-predicates-wf.rs:11:15 + | +LL | Vec: Sized; + | ^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `str` +note: required by an implicit `Sized` bound in `Vec` + --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. From baa1cdde2976dbdbe76b194c7032c388da444135 Mon Sep 17 00:00:00 2001 From: Laine Taffin Altman Date: Fri, 31 Jan 2025 07:10:15 -0800 Subject: [PATCH 07/10] Docs for f16 and f128: correct a typo and add details --- library/core/src/primitive_docs.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/library/core/src/primitive_docs.rs b/library/core/src/primitive_docs.rs index c5f029363e589..bbf5939fe1b05 100644 --- a/library/core/src/primitive_docs.rs +++ b/library/core/src/primitive_docs.rs @@ -1160,9 +1160,9 @@ impl (T,) {} /// /// Note that most common platforms will not support `f16` in hardware without enabling extra target /// features, with the notable exception of Apple Silicon (also known as M1, M2, etc.) processors. -/// Hardware support on x86-64 requires the avx512fp16 feature, while RISC-V requires Zhf. -/// Usually the fallback implementation will be to use `f32` hardware if it exists, and convert -/// between `f16` and `f32` when performing math. +/// Hardware support on x86/x86-64 requires the avx512fp16 or avx10.1 features, while RISC-V requires +/// Zfh, and Arm/AArch64 requires FEAT_FP16. Usually the fallback implementation will be to use `f32` +/// hardware if it exists, and convert between `f16` and `f32` when performing math. /// /// *[See also the `std::f16::consts` module](crate::f16::consts).* /// @@ -1344,10 +1344,10 @@ mod prim_f64 {} /// quad-precision values][wikipedia] for more information. /// /// Note that no platforms have hardware support for `f128` without enabling target specific features, -/// as for all instruction set architectures `f128` is considered an optional feature. -/// Only Power ISA ("PowerPC") and RISC-V specify it, and only certain microarchitectures -/// actually implement it. For x86-64 and AArch64, ISA support is not even specified, -/// so it will always be a software implementation significantly slower than `f64`. +/// as for all instruction set architectures `f128` is considered an optional feature. Only Power ISA +/// ("PowerPC") and RISC-V (via the Q extension) specify it, and only certain microarchitectures +/// actually implement it. For x86-64 and AArch64, ISA support is not even specified, so it will always +/// be a software implementation significantly slower than `f64`. /// /// _Note: `f128` support is incomplete. Many platforms will not be able to link math functions. On /// x86 in particular, these functions do link but their results are always incorrect._ From f88f0a8c0ea9cea48c6aba7381d5460619035e9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= Date: Sat, 1 Feb 2025 22:47:08 +0100 Subject: [PATCH 08/10] Remove a footgun-y feature / relic of the past from the compiletest DSL --- src/tools/compiletest/src/header.rs | 8 ---- tests/assembly/small_data_threshold.rs | 60 +++++++++++++------------- 2 files changed, 30 insertions(+), 38 deletions(-) diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs index 8c96554738e68..452a2e9a9d518 100644 --- a/src/tools/compiletest/src/header.rs +++ b/src/tools/compiletest/src/header.rs @@ -882,14 +882,6 @@ fn iter_header( } let ln = ln.trim(); - // Assume that any directives will be found before the first module or function. This - // doesn't seem to be an optimization with a warm page cache. Maybe with a cold one. - // FIXME(jieyouxu): this will cause `//@` directives in the rest of the test file to - // not be checked. - if ln.starts_with("fn") || ln.starts_with("mod") { - return; - } - let Some(directive_line) = line_directive(line_number, comment, ln) else { continue; }; diff --git a/tests/assembly/small_data_threshold.rs b/tests/assembly/small_data_threshold.rs index d3ba144600e83..bed515915b85d 100644 --- a/tests/assembly/small_data_threshold.rs +++ b/tests/assembly/small_data_threshold.rs @@ -58,35 +58,35 @@ static mut Z: u64 = 0; // Currently, only MIPS and RISCV successfully put any objects in the small data // sections so the U/V/W/X tests are skipped on Hexagon and M68K -//@ RISCV: .section .sdata -//@ RISCV-NOT: .section -//@ RISCV: U: -//@ RISCV: .section .sbss -//@ RISCV-NOT: .section -//@ RISCV: V: -//@ RISCV: .section .sdata -//@ RISCV-NOT: .section -//@ RISCV: W: -//@ RISCV: .section .sbss -//@ RISCV-NOT: .section -//@ RISCV: X: +// RISCV: .section .sdata +// RISCV-NOT: .section +// RISCV: U: +// RISCV: .section .sbss +// RISCV-NOT: .section +// RISCV: V: +// RISCV: .section .sdata +// RISCV-NOT: .section +// RISCV: W: +// RISCV: .section .sbss +// RISCV-NOT: .section +// RISCV: X: -//@ MIPS: .section .sdata -//@ MIPS-NOT: .section -//@ MIPS: U: -//@ MIPS: .section .sbss -//@ MIPS-NOT: .section -//@ MIPS: V: -//@ MIPS: .section .sdata -//@ MIPS-NOT: .section -//@ MIPS: W: -//@ MIPS: .section .sbss -//@ MIPS-NOT: .section -//@ MIPS: X: +// MIPS: .section .sdata +// MIPS-NOT: .section +// MIPS: U: +// MIPS: .section .sbss +// MIPS-NOT: .section +// MIPS: V: +// MIPS: .section .sdata +// MIPS-NOT: .section +// MIPS: W: +// MIPS: .section .sbss +// MIPS-NOT: .section +// MIPS: X: -//@ CHECK: .section .data.Y, -//@ CHECK-NOT: .section -//@ CHECK: Y: -//@ CHECK: .section .bss.Z, -//@ CHECK-NOT: .section -//@ CHECK: Z: +// CHECK: .section .data.Y, +// CHECK-NOT: .section +// CHECK: Y: +// CHECK: .section .bss.Z, +// CHECK-NOT: .section +// CHECK: Z: From e661514bda5a06d33f5b872a1a88bb72b47b064f Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 31 Jan 2025 16:52:39 +1100 Subject: [PATCH 09/10] Remove hook calling via `TyCtxtAt`. All hooks receive a `TyCtxtAt` argument. Currently hooks can be called through `TyCtxtAt` or `TyCtxt`. In the latter case, a `TyCtxtAt` is constructed with a dummy span and passed to the hook. However, in practice hooks are never called through `TyCtxtAt`, and always receive a dummy span. (I confirmed this via code inspection, and double-checked it by temporarily making the `TyCtxtAt` code path panic and running all the tests.) This commit removes all the `TyCtxtAt` machinery for hooks. All hooks now receive `TyCtxt` instead of `TyCtxtAt`. There are two existing hooks that use `TyCtxtAt::span`: `const_caller_location_provider` and `try_destructure_mir_constant_for_user_output`. For both hooks the span is always a dummy span, probably unintentionally. This dummy span use is now explicit. If a non-dummy span is needed for these two hooks it would be easy to add it as an extra argument because hooks are less constrained than queries. --- .../rustc_const_eval/src/const_eval/mod.rs | 9 +++++---- .../src/util/caller_location.rs | 9 ++++----- compiler/rustc_incremental/src/lib.rs | 2 +- .../src/rmeta/decoder/cstore_impl.rs | 6 +++--- compiler/rustc_middle/src/hooks/mod.rs | 20 +++---------------- .../rustc_mir_transform/src/coverage/query.rs | 4 +--- compiler/rustc_monomorphize/src/collector.rs | 4 ++-- compiler/rustc_query_impl/src/lib.rs | 5 ++--- 8 files changed, 21 insertions(+), 38 deletions(-) diff --git a/compiler/rustc_const_eval/src/const_eval/mod.rs b/compiler/rustc_const_eval/src/const_eval/mod.rs index 34f795bda7595..c0438fb3ff81a 100644 --- a/compiler/rustc_const_eval/src/const_eval/mod.rs +++ b/compiler/rustc_const_eval/src/const_eval/mod.rs @@ -1,7 +1,7 @@ // Not in interpret to make sure we do not use private implementation details use rustc_abi::VariantIdx; -use rustc_middle::query::{Key, TyCtxtAt}; +use rustc_middle::query::Key; use rustc_middle::ty::layout::LayoutOf; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_middle::{bug, mir}; @@ -35,16 +35,17 @@ pub(crate) type ValTreeCreationResult<'tcx> = Result, ValTreeC #[instrument(skip(tcx), level = "debug")] pub(crate) fn try_destructure_mir_constant_for_user_output<'tcx>( - tcx: TyCtxtAt<'tcx>, + tcx: TyCtxt<'tcx>, val: mir::ConstValue<'tcx>, ty: Ty<'tcx>, ) -> Option> { let typing_env = ty::TypingEnv::fully_monomorphized(); - let (ecx, op) = mk_eval_cx_for_const_val(tcx, typing_env, val, ty)?; + // FIXME: use a proper span here? + let (ecx, op) = mk_eval_cx_for_const_val(tcx.at(rustc_span::DUMMY_SP), typing_env, val, ty)?; // We go to `usize` as we cannot allocate anything bigger anyway. let (field_count, variant, down) = match ty.kind() { - ty::Array(_, len) => (len.try_to_target_usize(tcx.tcx)? as usize, None, op), + ty::Array(_, len) => (len.try_to_target_usize(tcx)? as usize, None, op), ty::Adt(def, _) if def.variants().is_empty() => { return None; } diff --git a/compiler/rustc_const_eval/src/util/caller_location.rs b/compiler/rustc_const_eval/src/util/caller_location.rs index 6dd9447cf5a5f..e926040e9ba15 100644 --- a/compiler/rustc_const_eval/src/util/caller_location.rs +++ b/compiler/rustc_const_eval/src/util/caller_location.rs @@ -1,7 +1,6 @@ use rustc_hir::LangItem; -use rustc_middle::query::TyCtxtAt; use rustc_middle::ty::layout::LayoutOf; -use rustc_middle::ty::{self}; +use rustc_middle::ty::{self, TyCtxt}; use rustc_middle::{bug, mir}; use rustc_span::Symbol; use tracing::trace; @@ -48,15 +47,15 @@ fn alloc_caller_location<'tcx>( } pub(crate) fn const_caller_location_provider( - tcx: TyCtxtAt<'_>, + tcx: TyCtxt<'_>, file: Symbol, line: u32, col: u32, ) -> mir::ConstValue<'_> { trace!("const_caller_location: {}:{}:{}", file, line, col); let mut ecx = mk_eval_cx_to_read_const_val( - tcx.tcx, - tcx.span, + tcx, + rustc_span::DUMMY_SP, // FIXME: use a proper span here? ty::TypingEnv::fully_monomorphized(), CanAccessMutGlobal::No, ); diff --git a/compiler/rustc_incremental/src/lib.rs b/compiler/rustc_incremental/src/lib.rs index 6dab6468870a5..563ed7614c609 100644 --- a/compiler/rustc_incremental/src/lib.rs +++ b/compiler/rustc_incremental/src/lib.rs @@ -24,7 +24,7 @@ use rustc_middle::util::Providers; #[allow(missing_docs)] pub fn provide(providers: &mut Providers) { providers.hooks.save_dep_graph = - |tcx| tcx.sess.time("serialize_dep_graph", || persist::save_dep_graph(tcx.tcx)); + |tcx| tcx.sess.time("serialize_dep_graph", || persist::save_dep_graph(tcx)); } rustc_fluent_macro::fluent_messages! { "../messages.ftl" } diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index da07ad8f6c074..d727602cbd531 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -689,7 +689,7 @@ fn provide_cstore_hooks(providers: &mut Providers) { providers.hooks.def_path_hash_to_def_id_extern = |tcx, hash, stable_crate_id| { // If this is a DefPathHash from an upstream crate, let the CrateStore map // it to a DefId. - let cstore = CStore::from_tcx(tcx.tcx); + let cstore = CStore::from_tcx(tcx); let cnum = *tcx .untracked() .stable_crate_ids @@ -702,11 +702,11 @@ fn provide_cstore_hooks(providers: &mut Providers) { }; providers.hooks.expn_hash_to_expn_id = |tcx, cnum, index_guess, hash| { - let cstore = CStore::from_tcx(tcx.tcx); + let cstore = CStore::from_tcx(tcx); cstore.get_crate_data(cnum).expn_hash_to_expn_id(tcx.sess, index_guess, hash) }; providers.hooks.import_source_files = |tcx, cnum| { - let cstore = CStore::from_tcx(tcx.tcx); + let cstore = CStore::from_tcx(tcx); let cdata = cstore.get_crate_data(cnum); for file_index in 0..cdata.root.source_map.size() { cdata.imported_source_file(file_index as u32, tcx.sess); diff --git a/compiler/rustc_middle/src/hooks/mod.rs b/compiler/rustc_middle/src/hooks/mod.rs index 2be242364c111..276a02b4e0feb 100644 --- a/compiler/rustc_middle/src/hooks/mod.rs +++ b/compiler/rustc_middle/src/hooks/mod.rs @@ -6,11 +6,9 @@ use rustc_hir::def_id::{DefId, DefPathHash}; use rustc_session::StableCrateId; use rustc_span::def_id::{CrateNum, LocalDefId}; -use rustc_span::{DUMMY_SP, ExpnHash, ExpnId}; -use tracing::instrument; +use rustc_span::{ExpnHash, ExpnId}; use crate::mir; -use crate::query::TyCtxtAt; use crate::ty::{Ty, TyCtxt}; macro_rules! declare_hooks { @@ -22,26 +20,14 @@ macro_rules! declare_hooks { #[inline(always)] pub fn $name(self, $($arg: $K,)*) -> $V { - self.at(DUMMY_SP).$name($($arg,)*) - } - )* - } - - impl<'tcx> TyCtxtAt<'tcx> { - $( - $(#[$attr])* - #[inline(always)] - #[instrument(level = "debug", skip(self), ret)] - pub fn $name(self, $($arg: $K,)*) -> $V - { - (self.tcx.hooks.$name)(self, $($arg,)*) + (self.hooks.$name)(self, $($arg,)*) } )* } pub struct Providers { $(pub $name: for<'tcx> fn( - TyCtxtAt<'tcx>, + TyCtxt<'tcx>, $($arg: $K,)* ) -> $V,)* } diff --git a/compiler/rustc_mir_transform/src/coverage/query.rs b/compiler/rustc_mir_transform/src/coverage/query.rs index 5e7b46182dcfb..a849ed4c3e27c 100644 --- a/compiler/rustc_mir_transform/src/coverage/query.rs +++ b/compiler/rustc_mir_transform/src/coverage/query.rs @@ -6,7 +6,6 @@ use rustc_middle::mir::coverage::{ FunctionCoverageInfo, MappingKind, Op, }; use rustc_middle::mir::{Body, Statement, StatementKind}; -use rustc_middle::query::TyCtxtAt; use rustc_middle::ty::{self, TyCtxt}; use rustc_middle::util::Providers; use rustc_span::def_id::LocalDefId; @@ -15,8 +14,7 @@ use tracing::trace; /// Registers query/hook implementations related to coverage. pub(crate) fn provide(providers: &mut Providers) { - providers.hooks.is_eligible_for_coverage = - |TyCtxtAt { tcx, .. }, def_id| is_eligible_for_coverage(tcx, def_id); + providers.hooks.is_eligible_for_coverage = is_eligible_for_coverage; providers.queries.coverage_attr_on = coverage_attr_on; providers.queries.coverage_ids_info = coverage_ids_info; } diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index 246faed50e369..745f020301f31 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -953,7 +953,7 @@ fn visit_instance_use<'tcx>( /// Returns `true` if we should codegen an instance in the local crate, or returns `false` if we /// can just link to the upstream crate and therefore don't need a mono item. -fn should_codegen_locally<'tcx>(tcx: TyCtxtAt<'tcx>, instance: Instance<'tcx>) -> bool { +fn should_codegen_locally<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) -> bool { let Some(def_id) = instance.def.def_id_if_not_guaranteed_local_codegen() else { return true; }; @@ -976,7 +976,7 @@ fn should_codegen_locally<'tcx>(tcx: TyCtxtAt<'tcx>, instance: Instance<'tcx>) - return true; } - if tcx.is_reachable_non_generic(def_id) || instance.upstream_monomorphization(*tcx).is_some() { + if tcx.is_reachable_non_generic(def_id) || instance.upstream_monomorphization(tcx).is_some() { // We can link to the item in question, no instance needed in this crate. return false; } diff --git a/compiler/rustc_query_impl/src/lib.rs b/compiler/rustc_query_impl/src/lib.rs index d2bb0b3f27719..bbc83cca99d86 100644 --- a/compiler/rustc_query_impl/src/lib.rs +++ b/compiler/rustc_query_impl/src/lib.rs @@ -224,7 +224,6 @@ pub fn query_system<'a>( rustc_middle::rustc_query_append! { define_queries! } pub fn provide(providers: &mut rustc_middle::util::Providers) { - providers.hooks.alloc_self_profile_query_strings = - |tcx| alloc_self_profile_query_strings(tcx.tcx); - providers.hooks.query_key_hash_verify_all = |tcx| query_key_hash_verify_all(tcx.tcx); + providers.hooks.alloc_self_profile_query_strings = alloc_self_profile_query_strings; + providers.hooks.query_key_hash_verify_all = query_key_hash_verify_all; } From 8c5e6a20d00a8b19a297b8b6eaccfab31a0dde65 Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Mon, 3 Feb 2025 06:53:58 +0000 Subject: [PATCH 10/10] override default config profile on tarballs This is the same logic used in the Python script https://github.com/rust-lang/rust/blob/613bdd49978298648ed05ace086bd1ecad54b44a/src/bootstrap/bootstrap.py#L1273-L1274 Signed-off-by: onur-ozkan --- src/bootstrap/src/core/config/config.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index 98490118f7d62..781d0e602c339 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -700,7 +700,7 @@ trait Merge { impl Merge for TomlConfig { fn merge( &mut self, - TomlConfig { build, install, llvm, rust, dist, target, profile: _, change_id }: Self, + TomlConfig { build, install, llvm, rust, dist, target, profile, change_id }: Self, replace: ReplaceOpt, ) { fn do_merge(x: &mut Option, y: Option, replace: ReplaceOpt) { @@ -712,7 +712,10 @@ impl Merge for TomlConfig { } } } + self.change_id.inner.merge(change_id.inner, replace); + self.profile.merge(profile, replace); + do_merge(&mut self.build, build, replace); do_merge(&mut self.install, install, replace); do_merge(&mut self.llvm, llvm, replace); @@ -1505,6 +1508,10 @@ impl Config { build.cargo = build.cargo.take().or(std::env::var_os("CARGO").map(|p| p.into())); } + if GitInfo::new(false, &config.src).is_from_tarball() && toml.profile.is_none() { + toml.profile = Some("dist".into()); + } + if let Some(include) = &toml.profile { // Allows creating alias for profile names, allowing // profiles to be renamed while maintaining back compatibility