From d4b194b1ce9b3d29b0d38de2933d2733b5721bba Mon Sep 17 00:00:00 2001 From: Roy Ammerschuber Date: Mon, 27 Oct 2025 18:57:49 +0100 Subject: [PATCH 01/17] adjust NodeAppArgs to expose entire tree simplify AccessRelatedness minor changes fix rel_pos... --- .../src/borrow_tracker/tree_borrows/perms.rs | 8 +- .../src/borrow_tracker/tree_borrows/tree.rs | 75 +++++++++---------- .../borrow_tracker/tree_borrows/tree/tests.rs | 12 +-- 3 files changed, 45 insertions(+), 50 deletions(-) diff --git a/src/tools/miri/src/borrow_tracker/tree_borrows/perms.rs b/src/tools/miri/src/borrow_tracker/tree_borrows/perms.rs index e21775c9f239f..968e4961a6355 100644 --- a/src/tools/miri/src/borrow_tracker/tree_borrows/perms.rs +++ b/src/tools/miri/src/borrow_tracker/tree_borrows/perms.rs @@ -640,7 +640,7 @@ mod propagation_optimization_checks { impl Exhaustive for AccessRelatedness { fn exhaustive() -> Box> { use AccessRelatedness::*; - Box::new(vec![This, StrictChildAccess, AncestorAccess, CousinAccess].into_iter()) + Box::new(vec![ForeignAccess, LocalAccess].into_iter()) } } @@ -716,13 +716,11 @@ mod propagation_optimization_checks { // We now assert it is idempotent, and never causes UB. // First, if the SIFA includes foreign reads, assert it is idempotent under foreign reads. if access >= IdempotentForeignAccess::Read { - // We use `CousinAccess` here. We could also use `AncestorAccess`, since `transition::perform_access` treats these the same. - // The only place they are treated differently is in protector end accesses, but these are not handled here. - assert_eq!(perm, transition::perform_access(AccessKind::Read, AccessRelatedness::CousinAccess, perm, prot).unwrap()); + assert_eq!(perm, transition::perform_access(AccessKind::Read, AccessRelatedness::ForeignAccess, perm, prot).unwrap()); } // Then, if the SIFA includes foreign writes, assert it is idempotent under foreign writes. if access >= IdempotentForeignAccess::Write { - assert_eq!(perm, transition::perform_access(AccessKind::Write, AccessRelatedness::CousinAccess, perm, prot).unwrap()); + assert_eq!(perm, transition::perform_access(AccessKind::Write, AccessRelatedness::ForeignAccess, perm, prot).unwrap()); } } } diff --git a/src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs b/src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs index c4345c63289f1..740483844e795 100644 --- a/src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs +++ b/src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs @@ -24,7 +24,7 @@ use crate::borrow_tracker::tree_borrows::diagnostics::{ }; use crate::borrow_tracker::tree_borrows::foreign_access_skipping::IdempotentForeignAccess; use crate::borrow_tracker::tree_borrows::perms::PermTransition; -use crate::borrow_tracker::tree_borrows::unimap::{UniEntry, UniIndex, UniKeyMap, UniValMap}; +use crate::borrow_tracker::tree_borrows::unimap::{UniIndex, UniKeyMap, UniValMap}; use crate::borrow_tracker::{GlobalState, ProtectorKind}; use crate::*; @@ -265,13 +265,15 @@ pub(super) struct Node { } /// Data given to the transition function -struct NodeAppArgs<'node> { - /// Node on which the transition is currently being applied - node: &'node mut Node, - /// Mutable access to its permissions - perm: UniEntry<'node, LocationState>, - /// Relative position of the access +struct NodeAppArgs<'visit> { + /// The index of the current node. + idx: UniIndex, + /// Relative position of the access. rel_pos: AccessRelatedness, + /// The node map of this tree. + nodes: &'visit mut UniValMap, + /// The permissions map of this tree. + perms: &'visit mut UniValMap, } /// Data given to the error handler struct ErrHandlerArgs<'node, InErr> { @@ -348,8 +350,7 @@ where idx: UniIndex, rel_pos: AccessRelatedness, ) -> ContinueTraversal { - let node = this.nodes.get_mut(idx).unwrap(); - let args = NodeAppArgs { node, perm: this.perms.entry(idx), rel_pos }; + let args = NodeAppArgs { idx, rel_pos, nodes: this.nodes, perms: this.perms }; (self.f_continue)(&args) } @@ -359,16 +360,14 @@ where idx: UniIndex, rel_pos: AccessRelatedness, ) -> Result<(), OutErr> { - let node = this.nodes.get_mut(idx).unwrap(); - (self.f_propagate)(NodeAppArgs { node, perm: this.perms.entry(idx), rel_pos }).map_err( - |error_kind| { + (self.f_propagate)(NodeAppArgs { idx, rel_pos, nodes: this.nodes, perms: this.perms }) + .map_err(|error_kind| { (self.err_builder)(ErrHandlerArgs { error_kind, conflicting_info: &this.nodes.get(idx).unwrap().debug_info, accessed_info: &this.nodes.get(self.initial).unwrap().debug_info, }) - }, - ) + }) } fn go_upwards_from_accessed( @@ -386,14 +385,14 @@ where // be handled differently here compared to the further parents // of `accesssed_node`. { - self.propagate_at(this, accessed_node, AccessRelatedness::This)?; + self.propagate_at(this, accessed_node, AccessRelatedness::LocalAccess)?; if matches!(visit_children, ChildrenVisitMode::VisitChildrenOfAccessed) { let accessed_node = this.nodes.get(accessed_node).unwrap(); // We `rev()` here because we reverse the entire stack later. for &child in accessed_node.children.iter().rev() { self.stack.push(( child, - AccessRelatedness::AncestorAccess, + AccessRelatedness::ForeignAccess, RecursionState::BeforeChildren, )); } @@ -404,7 +403,7 @@ where // not the subtree that contains the accessed node. let mut last_node = accessed_node; while let Some(current) = this.nodes.get(last_node).unwrap().parent { - self.propagate_at(this, current, AccessRelatedness::StrictChildAccess)?; + self.propagate_at(this, current, AccessRelatedness::LocalAccess)?; let node = this.nodes.get(current).unwrap(); // We `rev()` here because we reverse the entire stack later. for &child in node.children.iter().rev() { @@ -413,7 +412,7 @@ where } self.stack.push(( child, - AccessRelatedness::CousinAccess, + AccessRelatedness::ForeignAccess, RecursionState::BeforeChildren, )); } @@ -741,7 +740,9 @@ impl<'tcx> Tree { // visit all children, skipping none |_| ContinueTraversal::Recurse, |args: NodeAppArgs<'_>| -> Result<(), TransitionError> { - let NodeAppArgs { node, perm, .. } = args; + let node = args.nodes.get(args.idx).unwrap(); + let perm = args.perms.entry(args.idx); + let perm = perm.get().copied().unwrap_or_else(|| node.default_location_state()); if global.borrow().protected_tags.get(&node.tag) @@ -812,32 +813,34 @@ impl<'tcx> Tree { // `perms_range` is only for diagnostics (it is the range of // the `RangeMap` on which we are currently working). let node_skipper = |access_kind: AccessKind, args: &NodeAppArgs<'_>| -> ContinueTraversal { - let NodeAppArgs { node, perm, rel_pos } = args; + let node = args.nodes.get(args.idx).unwrap(); + let perm = args.perms.get(args.idx); - let old_state = perm.get().copied().unwrap_or_else(|| node.default_location_state()); - old_state.skip_if_known_noop(access_kind, *rel_pos) + let old_state = perm.copied().unwrap_or_else(|| node.default_location_state()); + old_state.skip_if_known_noop(access_kind, args.rel_pos) }; let node_app = |perms_range: Range, access_kind: AccessKind, access_cause: diagnostics::AccessCause, args: NodeAppArgs<'_>| -> Result<(), TransitionError> { - let NodeAppArgs { node, mut perm, rel_pos } = args; + let node = args.nodes.get_mut(args.idx).unwrap(); + let mut perm = args.perms.entry(args.idx); let old_state = perm.or_insert(node.default_location_state()); // Call this function now, which ensures it is only called when // `skip_if_known_noop` returns `Recurse`, due to the contract of // `traverse_this_parents_children_other`. - old_state.record_new_access(access_kind, rel_pos); + old_state.record_new_access(access_kind, args.rel_pos); let protected = global.borrow().protected_tags.contains_key(&node.tag); - let transition = old_state.perform_access(access_kind, rel_pos, protected)?; + let transition = old_state.perform_access(access_kind, args.rel_pos, protected)?; // Record the event as part of the history if !transition.is_noop() { node.debug_info.history.push(diagnostics::Event { transition, - is_foreign: rel_pos.is_foreign(), + is_foreign: args.rel_pos.is_foreign(), access_cause, access_range: access_range_and_kind.map(|x| x.0), transition_range: perms_range, @@ -1075,24 +1078,18 @@ impl VisitProvenance for Tree { /// Relative position of the access #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub enum AccessRelatedness { - /// The accessed pointer is the current one - This, - /// The accessed pointer is a (transitive) child of the current one. - // Current pointer is excluded (unlike in some other places of this module - // where "child" is inclusive). - StrictChildAccess, - /// The accessed pointer is a (transitive) parent of the current one. - // Current pointer is excluded. - AncestorAccess, - /// The accessed pointer is neither of the above. - // It's a cousin/uncle/etc., something in a side branch. - CousinAccess, + /// The access happened either through the node itself or one of + /// its transitive children. + LocalAccess, + /// The access happened through this nodes ancestor or through + /// a sibling/cousin/uncle/etc. + ForeignAccess, } impl AccessRelatedness { /// Check that access is either Ancestor or Distant, i.e. not /// a transitive child (initial pointer included). pub fn is_foreign(self) -> bool { - matches!(self, AccessRelatedness::AncestorAccess | AccessRelatedness::CousinAccess) + matches!(self, AccessRelatedness::ForeignAccess) } } diff --git a/src/tools/miri/src/borrow_tracker/tree_borrows/tree/tests.rs b/src/tools/miri/src/borrow_tracker/tree_borrows/tree/tests.rs index 189e48eca724a..0b83de2cedc09 100644 --- a/src/tools/miri/src/borrow_tracker/tree_borrows/tree/tests.rs +++ b/src/tools/miri/src/borrow_tracker/tree_borrows/tree/tests.rs @@ -263,15 +263,15 @@ mod spurious_read { match xy_rel { RelPosXY::MutuallyForeign => match self { - PtrSelector::X => (This, CousinAccess), - PtrSelector::Y => (CousinAccess, This), - PtrSelector::Other => (CousinAccess, CousinAccess), + PtrSelector::X => (LocalAccess, ForeignAccess), + PtrSelector::Y => (ForeignAccess, LocalAccess), + PtrSelector::Other => (ForeignAccess, ForeignAccess), }, RelPosXY::XChildY => match self { - PtrSelector::X => (This, StrictChildAccess), - PtrSelector::Y => (AncestorAccess, This), - PtrSelector::Other => (CousinAccess, CousinAccess), + PtrSelector::X => (LocalAccess, LocalAccess), + PtrSelector::Y => (ForeignAccess, LocalAccess), + PtrSelector::Other => (ForeignAccess, ForeignAccess), }, } } From b9133371848d979f4ddc3b50b27b10be644a41f4 Mon Sep 17 00:00:00 2001 From: The Miri Cronjob Bot Date: Mon, 3 Nov 2025 04:55:29 +0000 Subject: [PATCH 02/17] Prepare for merging from rust-lang/rust This updates the rust-version file to c5dabe8cf798123087d094f06417f5a767ca73e8. --- src/tools/miri/rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version index bf33c10dd0352..0e89b4ab6ac75 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -292be5c7c05138d753bbd4b30db7a3f1a5c914f7 +c5dabe8cf798123087d094f06417f5a767ca73e8 From c6a8c46b6c7678dcd965dcf523482a436218ff0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Wed, 22 Oct 2025 16:54:07 +0200 Subject: [PATCH 03/17] add test for duplicate warning on used deprecated unit structs Co-authored-by: Waffle Lapkin --- tests/ui/deprecation/unit_and_tuple_struct.rs | 50 +++++++++ .../deprecation/unit_and_tuple_struct.stderr | 104 ++++++++++++++++++ 2 files changed, 154 insertions(+) create mode 100644 tests/ui/deprecation/unit_and_tuple_struct.rs create mode 100644 tests/ui/deprecation/unit_and_tuple_struct.stderr diff --git a/tests/ui/deprecation/unit_and_tuple_struct.rs b/tests/ui/deprecation/unit_and_tuple_struct.rs new file mode 100644 index 0000000000000..c1f757d9547d7 --- /dev/null +++ b/tests/ui/deprecation/unit_and_tuple_struct.rs @@ -0,0 +1,50 @@ +#![deny(deprecated)] +#![allow(unused_imports)] + +#[deprecated] +pub mod a { + pub struct Foo; + pub struct Bar(); + pub struct Baz {} + + pub enum Enum { + VFoo, + VBar(), + VBaz {}, + } +} + + +use a::Foo; +//~^ ERROR use of deprecated struct `a::Foo` +//~| ERROR use of deprecated unit struct `a::Foo` +use a::Bar; +//~^ ERROR use of deprecated struct `a::Bar` +//~| ERROR use of deprecated tuple struct `a::Bar` +use a::Baz; +//~^ ERROR use of deprecated struct `a::Baz` + +use a::Enum::VFoo; +//~^ ERROR use of deprecated variant `a::Enum::VFoo` +//~| ERROR use of deprecated unit variant `a::Enum::VFoo` +use a::Enum::VBar; +//~^ ERROR use of deprecated variant `a::Enum::VBar` +//~| ERROR use of deprecated tuple variant `a::Enum::VBar` +use a::Enum::VBaz; +//~^ ERROR use of deprecated variant `a::Enum::VBaz` + +fn main() { + a::Foo; + //~^ ERROR use of deprecated unit struct `a::Foo` + a::Bar(); + //~^ ERROR use of deprecated tuple struct `a::Bar` + a::Baz {}; + //~^ ERROR use of deprecated struct `a::Baz` + + a::Enum::VFoo; + //~^ ERROR use of deprecated unit variant `a::Enum::VFoo` + a::Enum::VBar(); + //~^ ERROR use of deprecated tuple variant `a::Enum::VBar` + a::Enum::VBaz{}; + //~^ ERROR use of deprecated variant `a::Enum::VBaz` +} diff --git a/tests/ui/deprecation/unit_and_tuple_struct.stderr b/tests/ui/deprecation/unit_and_tuple_struct.stderr new file mode 100644 index 0000000000000..5d1c4dcb23c3f --- /dev/null +++ b/tests/ui/deprecation/unit_and_tuple_struct.stderr @@ -0,0 +1,104 @@ +error: use of deprecated struct `a::Foo` + --> $DIR/unit_and_tuple_struct.rs:18:8 + | +LL | use a::Foo; + | ^^^ + | +note: the lint level is defined here + --> $DIR/unit_and_tuple_struct.rs:1:9 + | +LL | #![deny(deprecated)] + | ^^^^^^^^^^ + +error: use of deprecated unit struct `a::Foo` + --> $DIR/unit_and_tuple_struct.rs:18:8 + | +LL | use a::Foo; + | ^^^ + +error: use of deprecated struct `a::Bar` + --> $DIR/unit_and_tuple_struct.rs:21:8 + | +LL | use a::Bar; + | ^^^ + +error: use of deprecated tuple struct `a::Bar` + --> $DIR/unit_and_tuple_struct.rs:21:8 + | +LL | use a::Bar; + | ^^^ + +error: use of deprecated struct `a::Baz` + --> $DIR/unit_and_tuple_struct.rs:24:8 + | +LL | use a::Baz; + | ^^^ + +error: use of deprecated variant `a::Enum::VFoo` + --> $DIR/unit_and_tuple_struct.rs:27:14 + | +LL | use a::Enum::VFoo; + | ^^^^ + +error: use of deprecated unit variant `a::Enum::VFoo` + --> $DIR/unit_and_tuple_struct.rs:27:14 + | +LL | use a::Enum::VFoo; + | ^^^^ + +error: use of deprecated variant `a::Enum::VBar` + --> $DIR/unit_and_tuple_struct.rs:30:14 + | +LL | use a::Enum::VBar; + | ^^^^ + +error: use of deprecated tuple variant `a::Enum::VBar` + --> $DIR/unit_and_tuple_struct.rs:30:14 + | +LL | use a::Enum::VBar; + | ^^^^ + +error: use of deprecated variant `a::Enum::VBaz` + --> $DIR/unit_and_tuple_struct.rs:33:14 + | +LL | use a::Enum::VBaz; + | ^^^^ + +error: use of deprecated unit struct `a::Foo` + --> $DIR/unit_and_tuple_struct.rs:37:6 + | +LL | a::Foo; + | ^^^ + +error: use of deprecated tuple struct `a::Bar` + --> $DIR/unit_and_tuple_struct.rs:39:6 + | +LL | a::Bar(); + | ^^^ + +error: use of deprecated struct `a::Baz` + --> $DIR/unit_and_tuple_struct.rs:41:6 + | +LL | a::Baz {}; + | ^^^ + +error: use of deprecated unit variant `a::Enum::VFoo` + --> $DIR/unit_and_tuple_struct.rs:44:12 + | +LL | a::Enum::VFoo; + | ^^^^ + +error: use of deprecated tuple variant `a::Enum::VBar` + --> $DIR/unit_and_tuple_struct.rs:46:12 + | +LL | a::Enum::VBar(); + | ^^^^ + +error: use of deprecated variant `a::Enum::VBaz` + --> $DIR/unit_and_tuple_struct.rs:48:12 + | +LL | a::Enum::VBaz{}; + | ^^^^ + +error: aborting due to 16 previous errors + From 1b00911b5b247c7da7089b140a0806269dca6905 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Tue, 28 Oct 2025 16:24:14 +0100 Subject: [PATCH 04/17] deduplicate warnings (attempt 2) --- compiler/rustc_passes/src/stability.rs | 33 +++++++++++- tests/ui/deprecation/unit_and_tuple_struct.rs | 13 ++--- .../deprecation/unit_and_tuple_struct.stderr | 52 +++++-------------- 3 files changed, 49 insertions(+), 49 deletions(-) diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs index 2ee1bd0dfd1ec..af78954ba1547 100644 --- a/compiler/rustc_passes/src/stability.rs +++ b/compiler/rustc_passes/src/stability.rs @@ -12,8 +12,8 @@ use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{CRATE_DEF_ID, LOCAL_CRATE, LocalDefId, LocalModDefId}; use rustc_hir::intravisit::{self, Visitor, VisitorExt}; use rustc_hir::{ - self as hir, AmbigArg, ConstStability, DefaultBodyStability, FieldDef, Item, ItemKind, - Stability, StabilityLevel, StableSince, TraitRef, Ty, TyKind, UnstableReason, + self as hir, AmbigArg, ConstStability, DefaultBodyStability, FieldDef, HirId, Item, ItemKind, + Path, Stability, StabilityLevel, StableSince, TraitRef, Ty, TyKind, UnstableReason, UsePath, VERSION_PLACEHOLDER, Variant, find_attr, }; use rustc_middle::hir::nested_filter; @@ -739,6 +739,35 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> { intravisit::walk_poly_trait_ref(self, t); } + fn visit_use(&mut self, path: &'tcx UsePath<'tcx>, hir_id: HirId) { + let res = path.res; + + // A use item can import something from two namespaces at the same time. + // For deprecation/stability we don't want to warn twice. + // This specifically happens with constructors for unit/tuple structs. + if let Some(ty_ns_res) = res.type_ns + && let Some(value_ns_res) = res.value_ns + && let Some(type_ns_did) = ty_ns_res.opt_def_id() + && let Some(value_ns_did) = value_ns_res.opt_def_id() + && let DefKind::Ctor(.., _) = self.tcx.def_kind(value_ns_did) + && self.tcx.parent(value_ns_did) == type_ns_did + { + // Only visit the value namespace path when we've detected a duplicate, + // not the type namespace path. + let UsePath { segments, res: _, span } = *path; + self.visit_path(&Path { segments, res: value_ns_res, span }, hir_id); + + // Though, visit the macro namespace if it exists, + // regardless of the checks above relating to constructors. + if let Some(res) = res.macro_ns { + self.visit_path(&Path { segments, res, span }, hir_id); + } + } else { + // if there's no duplicate, just walk as normal + intravisit::walk_use(self, path, hir_id) + } + } + fn visit_path(&mut self, path: &hir::Path<'tcx>, id: hir::HirId) { if let Some(def_id) = path.res.opt_def_id() { let method_span = path.segments.last().map(|s| s.ident.span); diff --git a/tests/ui/deprecation/unit_and_tuple_struct.rs b/tests/ui/deprecation/unit_and_tuple_struct.rs index c1f757d9547d7..5f1484e7431dc 100644 --- a/tests/ui/deprecation/unit_and_tuple_struct.rs +++ b/tests/ui/deprecation/unit_and_tuple_struct.rs @@ -1,5 +1,4 @@ #![deny(deprecated)] -#![allow(unused_imports)] #[deprecated] pub mod a { @@ -16,20 +15,16 @@ pub mod a { use a::Foo; -//~^ ERROR use of deprecated struct `a::Foo` -//~| ERROR use of deprecated unit struct `a::Foo` +//~^ ERROR use of deprecated unit struct `a::Foo` use a::Bar; -//~^ ERROR use of deprecated struct `a::Bar` -//~| ERROR use of deprecated tuple struct `a::Bar` +//~^ ERROR use of deprecated tuple struct `a::Bar` use a::Baz; //~^ ERROR use of deprecated struct `a::Baz` use a::Enum::VFoo; -//~^ ERROR use of deprecated variant `a::Enum::VFoo` -//~| ERROR use of deprecated unit variant `a::Enum::VFoo` +//~^ ERROR use of deprecated unit variant `a::Enum::VFoo` use a::Enum::VBar; -//~^ ERROR use of deprecated variant `a::Enum::VBar` -//~| ERROR use of deprecated tuple variant `a::Enum::VBar` +//~^ ERROR use of deprecated tuple variant `a::Enum::VBar` use a::Enum::VBaz; //~^ ERROR use of deprecated variant `a::Enum::VBaz` diff --git a/tests/ui/deprecation/unit_and_tuple_struct.stderr b/tests/ui/deprecation/unit_and_tuple_struct.stderr index 5d1c4dcb23c3f..4408eaefb81ef 100644 --- a/tests/ui/deprecation/unit_and_tuple_struct.stderr +++ b/tests/ui/deprecation/unit_and_tuple_struct.stderr @@ -1,5 +1,5 @@ -error: use of deprecated struct `a::Foo` - --> $DIR/unit_and_tuple_struct.rs:18:8 +error: use of deprecated unit struct `a::Foo` + --> $DIR/unit_and_tuple_struct.rs:17:8 | LL | use a::Foo; | ^^^ @@ -10,95 +10,71 @@ note: the lint level is defined here LL | #![deny(deprecated)] | ^^^^^^^^^^ -error: use of deprecated unit struct `a::Foo` - --> $DIR/unit_and_tuple_struct.rs:18:8 - | -LL | use a::Foo; - | ^^^ - -error: use of deprecated struct `a::Bar` - --> $DIR/unit_and_tuple_struct.rs:21:8 - | -LL | use a::Bar; - | ^^^ - error: use of deprecated tuple struct `a::Bar` - --> $DIR/unit_and_tuple_struct.rs:21:8 + --> $DIR/unit_and_tuple_struct.rs:19:8 | LL | use a::Bar; | ^^^ error: use of deprecated struct `a::Baz` - --> $DIR/unit_and_tuple_struct.rs:24:8 + --> $DIR/unit_and_tuple_struct.rs:21:8 | LL | use a::Baz; | ^^^ -error: use of deprecated variant `a::Enum::VFoo` - --> $DIR/unit_and_tuple_struct.rs:27:14 - | -LL | use a::Enum::VFoo; - | ^^^^ - error: use of deprecated unit variant `a::Enum::VFoo` - --> $DIR/unit_and_tuple_struct.rs:27:14 + --> $DIR/unit_and_tuple_struct.rs:24:14 | LL | use a::Enum::VFoo; | ^^^^ -error: use of deprecated variant `a::Enum::VBar` - --> $DIR/unit_and_tuple_struct.rs:30:14 - | -LL | use a::Enum::VBar; - | ^^^^ - error: use of deprecated tuple variant `a::Enum::VBar` - --> $DIR/unit_and_tuple_struct.rs:30:14 + --> $DIR/unit_and_tuple_struct.rs:26:14 | LL | use a::Enum::VBar; | ^^^^ error: use of deprecated variant `a::Enum::VBaz` - --> $DIR/unit_and_tuple_struct.rs:33:14 + --> $DIR/unit_and_tuple_struct.rs:28:14 | LL | use a::Enum::VBaz; | ^^^^ error: use of deprecated unit struct `a::Foo` - --> $DIR/unit_and_tuple_struct.rs:37:6 + --> $DIR/unit_and_tuple_struct.rs:32:6 | LL | a::Foo; | ^^^ error: use of deprecated tuple struct `a::Bar` - --> $DIR/unit_and_tuple_struct.rs:39:6 + --> $DIR/unit_and_tuple_struct.rs:34:6 | LL | a::Bar(); | ^^^ error: use of deprecated struct `a::Baz` - --> $DIR/unit_and_tuple_struct.rs:41:6 + --> $DIR/unit_and_tuple_struct.rs:36:6 | LL | a::Baz {}; | ^^^ error: use of deprecated unit variant `a::Enum::VFoo` - --> $DIR/unit_and_tuple_struct.rs:44:12 + --> $DIR/unit_and_tuple_struct.rs:39:12 | LL | a::Enum::VFoo; | ^^^^ error: use of deprecated tuple variant `a::Enum::VBar` - --> $DIR/unit_and_tuple_struct.rs:46:12 + --> $DIR/unit_and_tuple_struct.rs:41:12 | LL | a::Enum::VBar(); | ^^^^ error: use of deprecated variant `a::Enum::VBaz` - --> $DIR/unit_and_tuple_struct.rs:48:12 + --> $DIR/unit_and_tuple_struct.rs:43:12 | LL | a::Enum::VBaz{}; | ^^^^ -error: aborting due to 16 previous errors +error: aborting due to 12 previous errors From ec7c884a03df160ff1ad4bc8bf2d3448b0e2d13e Mon Sep 17 00:00:00 2001 From: Michalis Kokologiannakis Date: Mon, 3 Nov 2025 22:43:31 +0100 Subject: [PATCH 05/17] Use Github URL to fetch GenMC This commit also modifies MiriInterface.hpp so that it is compatible with GenMC's API. --- src/tools/miri/genmc-sys/build.rs | 4 ++-- src/tools/miri/genmc-sys/cpp/include/MiriInterface.hpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/tools/miri/genmc-sys/build.rs b/src/tools/miri/genmc-sys/build.rs index f10e151a3d0bc..1b4e064d1ba21 100644 --- a/src/tools/miri/genmc-sys/build.rs +++ b/src/tools/miri/genmc-sys/build.rs @@ -26,9 +26,9 @@ mod downloading { use super::GENMC_DOWNLOAD_PATH; /// The GenMC repository the we get our commit from. - pub(crate) const GENMC_GITHUB_URL: &str = "https://gitlab.inf.ethz.ch/public-plf/genmc.git"; + pub(crate) const GENMC_GITHUB_URL: &str = "https://github.com/MPI-SWS/genmc.git"; /// The GenMC commit we depend on. It must be available on the specified GenMC repository. - pub(crate) const GENMC_COMMIT: &str = "ce775ccd7866db820fa12ffca66463087a11dd96"; + pub(crate) const GENMC_COMMIT: &str = "d9527280bb99f1cef64326b1803ffd952e3880df"; /// Ensure that a local GenMC repo is present and set to the correct commit. /// Return the path of the GenMC repo and whether the checked out commit was changed. diff --git a/src/tools/miri/genmc-sys/cpp/include/MiriInterface.hpp b/src/tools/miri/genmc-sys/cpp/include/MiriInterface.hpp index b0bd397ab34b1..81644edddbfd7 100644 --- a/src/tools/miri/genmc-sys/cpp/include/MiriInterface.hpp +++ b/src/tools/miri/genmc-sys/cpp/include/MiriInterface.hpp @@ -269,7 +269,7 @@ inline GenmcScalar uninit() { inline GenmcScalar from_sval(SVal sval) { return GenmcScalar { .value = sval.get(), - .extra = sval.getExtra(), + .extra = sval.getProvenance(), .is_init = true, }; } From 3e0ea10fa0aaec5a61206f7949656aac5f5af61c Mon Sep 17 00:00:00 2001 From: The Miri Cronjob Bot Date: Tue, 4 Nov 2025 04:53:50 +0000 Subject: [PATCH 06/17] Prepare for merging from rust-lang/rust This updates the rust-version file to 5f9dd05862d2e4bceb3be1031b6c936e35671501. --- src/tools/miri/rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version index 0e89b4ab6ac75..036282b12f5de 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -c5dabe8cf798123087d094f06417f5a767ca73e8 +5f9dd05862d2e4bceb3be1031b6c936e35671501 From 459dae5df1f82cbbd51d32357ecc344f9cd06910 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 4 Nov 2025 08:34:42 +0100 Subject: [PATCH 07/17] wasi is too strange of a target, remove it for now --- src/tools/miri/README.md | 1 - src/tools/miri/ci/ci.sh | 1 - src/tools/miri/src/shims/env.rs | 2 +- src/tools/miri/src/shims/foreign_items.rs | 5 - src/tools/miri/src/shims/mod.rs | 1 - src/tools/miri/src/shims/tls.rs | 1 - .../miri/src/shims/wasi/foreign_items.rs | 110 ------------------ src/tools/miri/src/shims/wasi/mod.rs | 1 - 8 files changed, 1 insertion(+), 121 deletions(-) delete mode 100644 src/tools/miri/src/shims/wasi/foreign_items.rs delete mode 100644 src/tools/miri/src/shims/wasi/mod.rs diff --git a/src/tools/miri/README.md b/src/tools/miri/README.md index 0cbfe0e96a3fc..f6c675839e01f 100644 --- a/src/tools/miri/README.md +++ b/src/tools/miri/README.md @@ -220,7 +220,6 @@ degree documented below): - `solaris` / `illumos`: maintained by @devnexen. Supports the entire test suite. - `freebsd`: maintained by @YohDeadfall and @LorrensP-2158466. Supports the entire test suite. - `android`: **maintainer wanted**. Support very incomplete, but a basic "hello world" works. - - `wasi`: **maintainer wanted**. Support very incomplete, but a basic "hello world" works. - For targets on other operating systems, Miri might fail before even reaching the `main` function. However, even for targets that we do support, the degree of support for accessing platform APIs diff --git a/src/tools/miri/ci/ci.sh b/src/tools/miri/ci/ci.sh index bcc110f648b9b..2d27f02749991 100755 --- a/src/tools/miri/ci/ci.sh +++ b/src/tools/miri/ci/ci.sh @@ -153,7 +153,6 @@ case $HOST_TARGET in BASIC="empty_main integer heap_alloc libc-mem vec string btreemap" # ensures we have the basics: pre-main code, system allocator UNIX="hello panic/panic panic/unwind concurrency/simple atomic libc-mem libc-misc libc-random env num_cpus" # the things that are very similar across all Unixes, and hence easily supported there TEST_TARGET=aarch64-linux-android run_tests_minimal $BASIC $UNIX time hashmap random thread sync concurrency epoll eventfd - TEST_TARGET=wasm32-wasip2 run_tests_minimal $BASIC hello wasm TEST_TARGET=wasm32-unknown-unknown run_tests_minimal no_std empty_main wasm # this target doesn't really have std TEST_TARGET=thumbv7em-none-eabihf run_tests_minimal no_std ;; diff --git a/src/tools/miri/src/shims/env.rs b/src/tools/miri/src/shims/env.rs index 689cd3a7269cc..b9fb9192df4a8 100644 --- a/src/tools/miri/src/shims/env.rs +++ b/src/tools/miri/src/shims/env.rs @@ -51,7 +51,7 @@ impl<'tcx> EnvVars<'tcx> { } else if ecx.tcx.sess.target.os == "windows" { EnvVars::Windows(WindowsEnvVars::new(ecx, env_vars)?) } else { - // Used e.g. for wasi + // For "none" targets (i.e., without an OS). EnvVars::Uninit }; ecx.machine.env_vars = env_vars; diff --git a/src/tools/miri/src/shims/foreign_items.rs b/src/tools/miri/src/shims/foreign_items.rs index 74a1ac729e88f..54fe27382efd5 100644 --- a/src/tools/miri/src/shims/foreign_items.rs +++ b/src/tools/miri/src/shims/foreign_items.rs @@ -102,7 +102,6 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let this = self.eval_context_ref(); match this.tcx.sess.target.os.as_ref() { os if this.target_os_is_unix() => shims::unix::foreign_items::is_dyn_sym(name, os), - "wasi" => shims::wasi::foreign_items::is_dyn_sym(name), "windows" => shims::windows::foreign_items::is_dyn_sym(name), _ => false, } @@ -846,10 +845,6 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { shims::unix::foreign_items::EvalContextExt::emulate_foreign_item_inner( this, link_name, abi, args, dest, ), - "wasi" => - shims::wasi::foreign_items::EvalContextExt::emulate_foreign_item_inner( - this, link_name, abi, args, dest, - ), "windows" => shims::windows::foreign_items::EvalContextExt::emulate_foreign_item_inner( this, link_name, abi, args, dest, diff --git a/src/tools/miri/src/shims/mod.rs b/src/tools/miri/src/shims/mod.rs index 7f7bc3b1cf720..e51ace2fd9072 100644 --- a/src/tools/miri/src/shims/mod.rs +++ b/src/tools/miri/src/shims/mod.rs @@ -8,7 +8,6 @@ mod math; #[cfg(all(unix, feature = "native-lib"))] mod native_lib; mod unix; -mod wasi; mod windows; mod x86; diff --git a/src/tools/miri/src/shims/tls.rs b/src/tools/miri/src/shims/tls.rs index 1200029692dc3..9dc829d7a1eef 100644 --- a/src/tools/miri/src/shims/tls.rs +++ b/src/tools/miri/src/shims/tls.rs @@ -253,7 +253,6 @@ impl<'tcx> TlsDtorsState<'tcx> { } _ => { // No TLS dtor support. - // FIXME: should we do something on wasi? break 'new_state Done; } } diff --git a/src/tools/miri/src/shims/wasi/foreign_items.rs b/src/tools/miri/src/shims/wasi/foreign_items.rs deleted file mode 100644 index ffc02dc986f9a..0000000000000 --- a/src/tools/miri/src/shims/wasi/foreign_items.rs +++ /dev/null @@ -1,110 +0,0 @@ -use rustc_abi::CanonAbi; -use rustc_middle::ty::Ty; -use rustc_span::Symbol; -use rustc_target::callconv::FnAbi; - -use crate::shims::alloc::EvalContextExt as _; -use crate::*; - -pub fn is_dyn_sym(_name: &str) -> bool { - false -} - -impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {} -pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { - fn emulate_foreign_item_inner( - &mut self, - link_name: Symbol, - abi: &FnAbi<'tcx, Ty<'tcx>>, - args: &[OpTy<'tcx>], - dest: &MPlaceTy<'tcx>, - ) -> InterpResult<'tcx, EmulateItemResult> { - let this = self.eval_context_mut(); - match link_name.as_str() { - // Allocation - "posix_memalign" => { - let [memptr, align, size] = - this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; - let result = this.posix_memalign(memptr, align, size)?; - this.write_scalar(result, dest)?; - } - "aligned_alloc" => { - let [align, size] = - this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; - let res = this.aligned_alloc(align, size)?; - this.write_pointer(res, dest)?; - } - - // Standard input/output - // FIXME: These shims are hacks that just get basic stdout/stderr working. We can't - // constrain them to "std" since std itself uses the wasi crate for this. - "get-stdout" => { - let [] = - this.check_shim_sig(shim_sig!(extern "C" fn() -> i32), link_name, abi, args)?; - this.write_scalar(Scalar::from_i32(1), dest)?; // POSIX FD number for stdout - } - "get-stderr" => { - let [] = - this.check_shim_sig(shim_sig!(extern "C" fn() -> i32), link_name, abi, args)?; - this.write_scalar(Scalar::from_i32(2), dest)?; // POSIX FD number for stderr - } - "[resource-drop]output-stream" => { - let [handle] = - this.check_shim_sig(shim_sig!(extern "C" fn(i32) -> ()), link_name, abi, args)?; - let handle = this.read_scalar(handle)?.to_i32()?; - - if !(handle == 1 || handle == 2) { - throw_unsup_format!("wasm output-stream: unsupported handle"); - } - // We don't actually close these FDs, so this is a NOP. - } - "[method]output-stream.blocking-write-and-flush" => { - let [handle, buf, len, ret_area] = this.check_shim_sig( - shim_sig!(extern "C" fn(i32, *mut _, usize, *mut _) -> ()), - link_name, - abi, - args, - )?; - let handle = this.read_scalar(handle)?.to_i32()?; - let buf = this.read_pointer(buf)?; - let len = this.read_target_usize(len)?; - let ret_area = this.read_pointer(ret_area)?; - - if len > 4096 { - throw_unsup_format!( - "wasm output-stream.blocking-write-and-flush: buffer too big" - ); - } - let len = usize::try_from(len).unwrap(); - let Some(fd) = this.machine.fds.get(handle) else { - throw_unsup_format!( - "wasm output-stream.blocking-write-and-flush: unsupported handle" - ); - }; - fd.write( - this.machine.communicate(), - buf, - len, - this, - callback!( - @capture<'tcx> { - len: usize, - ret_area: Pointer, - } - |this, result: Result| { - if !matches!(result, Ok(l) if l == len) { - throw_unsup_format!("wasm output-stream.blocking-write-and-flush: returning errors is not supported"); - } - // 0 in the first byte of the ret_area indicates success. - let ret = this.ptr_to_mplace(ret_area, this.machine.layouts.u8); - this.write_null(&ret)?; - interp_ok(()) - }), - )?; - } - - _ => return interp_ok(EmulateItemResult::NotSupported), - } - interp_ok(EmulateItemResult::NeedsReturn) - } -} diff --git a/src/tools/miri/src/shims/wasi/mod.rs b/src/tools/miri/src/shims/wasi/mod.rs deleted file mode 100644 index 09c6507b24f84..0000000000000 --- a/src/tools/miri/src/shims/wasi/mod.rs +++ /dev/null @@ -1 +0,0 @@ -pub mod foreign_items; From a47726f10cdd8407c4c0da86f36367955788b6f0 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 4 Nov 2025 09:02:27 +0100 Subject: [PATCH 08/17] GenmcScalar: rename extra to provenance --- .../miri/genmc-sys/cpp/include/MiriInterface.hpp | 8 ++++---- src/tools/miri/genmc-sys/src/lib.rs | 11 ++++++----- src/tools/miri/src/concurrency/genmc/helper.rs | 15 ++++++++------- 3 files changed, 18 insertions(+), 16 deletions(-) diff --git a/src/tools/miri/genmc-sys/cpp/include/MiriInterface.hpp b/src/tools/miri/genmc-sys/cpp/include/MiriInterface.hpp index 81644edddbfd7..3a04edc013681 100644 --- a/src/tools/miri/genmc-sys/cpp/include/MiriInterface.hpp +++ b/src/tools/miri/genmc-sys/cpp/include/MiriInterface.hpp @@ -261,7 +261,7 @@ namespace GenmcScalarExt { inline GenmcScalar uninit() { return GenmcScalar { .value = 0, - .extra = 0, + .provenance = 0, .is_init = false, }; } @@ -269,19 +269,19 @@ inline GenmcScalar uninit() { inline GenmcScalar from_sval(SVal sval) { return GenmcScalar { .value = sval.get(), - .extra = sval.getProvenance(), + .provenance = sval.getProvenance(), .is_init = true, }; } inline SVal to_sval(GenmcScalar scalar) { ERROR_ON(!scalar.is_init, "Cannot convert an uninitialized `GenmcScalar` into an `SVal`\n"); - return SVal(scalar.value, scalar.extra); + return SVal(scalar.value, scalar.provenance); } inline std::optional try_to_sval(GenmcScalar scalar) { if (scalar.is_init) - return { SVal(scalar.value, scalar.extra) }; + return { SVal(scalar.value, scalar.provenance) }; return std::nullopt; } } // namespace GenmcScalarExt diff --git a/src/tools/miri/genmc-sys/src/lib.rs b/src/tools/miri/genmc-sys/src/lib.rs index a34c7f2b3a667..69aeca3ebc723 100644 --- a/src/tools/miri/genmc-sys/src/lib.rs +++ b/src/tools/miri/genmc-sys/src/lib.rs @@ -45,14 +45,14 @@ pub fn create_genmc_driver_handle( } impl GenmcScalar { - pub const UNINIT: Self = Self { value: 0, extra: 0, is_init: false }; + pub const UNINIT: Self = Self { value: 0, provenance: 0, is_init: false }; pub const fn from_u64(value: u64) -> Self { - Self { value, extra: 0, is_init: true } + Self { value, provenance: 0, is_init: true } } pub const fn has_provenance(&self) -> bool { - self.extra != 0 + self.provenance != 0 } } @@ -172,8 +172,9 @@ mod ffi { value: u64, /// This is zero for integer values. For pointers, this encodes the provenance by /// storing the base address of the allocation that this pointer belongs to. - /// Operations on `SVal` in GenMC (e.g., `fetch_add`) preserve the `extra` of the left argument (`left.fetch_add(right, ...)`). - extra: u64, + /// Operations on `SVal` in GenMC (e.g., `fetch_add`) preserve the `provenance` of the left + /// argument (`left.fetch_add(right, ...)`). + provenance: u64, /// Indicates whether this value is initialized. If this is `false`, the other fields do not matter. /// (Ideally we'd use `std::optional` but CXX does not support that.) is_init: bool, diff --git a/src/tools/miri/src/concurrency/genmc/helper.rs b/src/tools/miri/src/concurrency/genmc/helper.rs index b2e4b5aea5346..ae16898106d86 100644 --- a/src/tools/miri/src/concurrency/genmc/helper.rs +++ b/src/tools/miri/src/concurrency/genmc/helper.rs @@ -55,7 +55,7 @@ pub fn scalar_to_genmc_scalar<'tcx>( rustc_const_eval::interpret::Scalar::Int(scalar_int) => { // FIXME(genmc): Add u128 support once GenMC supports it. let value: u64 = scalar_int.to_uint(scalar_int.size()).try_into().unwrap(); - GenmcScalar { value, extra: 0, is_init: true } + GenmcScalar { value, provenance: 0, is_init: true } } rustc_const_eval::interpret::Scalar::Ptr(pointer, size) => { // FIXME(genmc,borrow tracking): Borrow tracking information is lost. @@ -69,7 +69,7 @@ pub fn scalar_to_genmc_scalar<'tcx>( let base_addr = ecx.addr_from_alloc_id(alloc_id, None)?; // Add the base_addr alloc_id pair to the map. genmc_ctx.exec_state.genmc_shared_allocs_map.borrow_mut().insert(base_addr, alloc_id); - GenmcScalar { value: addr.bytes(), extra: base_addr, is_init: true } + GenmcScalar { value: addr.bytes(), provenance: base_addr, is_init: true } } }) } @@ -84,16 +84,17 @@ pub fn genmc_scalar_to_scalar<'tcx>( scalar: GenmcScalar, size: Size, ) -> InterpResult<'tcx, Scalar> { - // If `extra` is zero, we have a regular integer. - if scalar.extra == 0 { + // If `provenance` is zero, we have a regular integer. + if scalar.provenance == 0 { // NOTE: GenMC always returns 64 bit values, and the upper bits are not yet truncated. // FIXME(genmc): GenMC should be doing the truncation, not Miri. let (value_scalar_int, _got_truncated) = ScalarInt::truncate_from_uint(scalar.value, size); return interp_ok(Scalar::from(value_scalar_int)); } - // `extra` is non-zero, we have a pointer. - // When we get a pointer from GenMC, then we must have sent it to GenMC before in the same execution (since the reads-from relation is always respected). - let alloc_id = genmc_ctx.exec_state.genmc_shared_allocs_map.borrow()[&scalar.extra]; + // `provenance` is non-zero, we have a pointer. + // When we get a pointer from GenMC, then we must have sent it to GenMC before in the same + // execution (since the reads-from relation is always respected). + let alloc_id = genmc_ctx.exec_state.genmc_shared_allocs_map.borrow()[&scalar.provenance]; // FIXME(genmc,borrow tracking): Borrow tracking not yet supported. let provenance = machine::Provenance::Concrete { alloc_id, tag: BorTag::default() }; let ptr = interpret::Pointer::new(provenance, Size::from_bytes(scalar.value)); From 100a870844c7038a8cc130b676c620fa3400cad9 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 27 Oct 2025 16:24:30 +0100 Subject: [PATCH 09/17] user-relevant span: if no frame is in a local crate, use topmost non-track_caller frame --- src/tools/miri/src/concurrency/thread.rs | 30 +++++++++---- src/tools/miri/src/diagnostics.rs | 20 ++++----- src/tools/miri/src/helpers.rs | 17 ++++--- src/tools/miri/src/machine.rs | 45 +++++++++---------- .../fail/panic/tls_macro_drop_panic.stderr | 1 + .../genmc/pass/std/arc.check_count.stderr | 33 ++++++++++---- .../genmc/pass/std/arc.try_upgrade.stderr | 33 ++++++++++---- .../tests/genmc/pass/std/empty_main.stderr | 33 ++++++++++---- .../genmc/pass/std/spawn_std_threads.stderr | 33 ++++++++++---- .../tests/genmc/pass/std/thread_locals.stderr | 33 ++++++++++---- 10 files changed, 186 insertions(+), 92 deletions(-) diff --git a/src/tools/miri/src/concurrency/thread.rs b/src/tools/miri/src/concurrency/thread.rs index dd2b0edcb896a..6178f87d78495 100644 --- a/src/tools/miri/src/concurrency/thread.rs +++ b/src/tools/miri/src/concurrency/thread.rs @@ -181,7 +181,6 @@ pub struct Thread<'tcx> { /// The index of the topmost user-relevant frame in `stack`. This field must contain /// the value produced by `get_top_user_relevant_frame`. - /// The `None` state here represents /// This field is a cache to reduce how often we call that method. The cache is manually /// maintained inside `MiriMachine::after_stack_push` and `MiriMachine::after_stack_pop`. top_user_relevant_frame: Option, @@ -232,12 +231,21 @@ impl<'tcx> Thread<'tcx> { /// justifying the optimization that only pushes of user-relevant frames require updating the /// `top_user_relevant_frame` field. fn compute_top_user_relevant_frame(&self, skip: usize) -> Option { - self.stack - .iter() - .enumerate() - .rev() - .skip(skip) - .find_map(|(idx, frame)| if frame.extra.is_user_relevant { Some(idx) } else { None }) + // We are search for the frame with maximum relevance. + let mut best = None; + for (idx, frame) in self.stack.iter().enumerate().rev().skip(skip) { + let relevance = frame.extra.user_relevance; + if relevance == u8::MAX { + // We can short-circuit this search. + return Some(idx); + } + if best.is_none_or(|(_best_idx, best_relevance)| best_relevance < relevance) { + // The previous best frame has strictly worse relevance, so despite us being lower + // in the stack, we win. + best = Some((idx, relevance)); + } + } + best.map(|(idx, _relevance)| idx) } /// Re-compute the top user-relevant frame from scratch. `skip` indicates how many top frames @@ -256,14 +264,20 @@ impl<'tcx> Thread<'tcx> { /// Returns the topmost frame that is considered user-relevant, or the /// top of the stack if there is no such frame, or `None` if the stack is empty. pub fn top_user_relevant_frame(&self) -> Option { - debug_assert_eq!(self.top_user_relevant_frame, self.compute_top_user_relevant_frame(0)); // This can be called upon creation of an allocation. We create allocations while setting up // parts of the Rust runtime when we do not have any stack frames yet, so we need to handle // empty stacks. self.top_user_relevant_frame.or_else(|| self.stack.len().checked_sub(1)) } + pub fn current_user_relevance(&self) -> u8 { + self.top_user_relevant_frame() + .map(|frame_idx| self.stack[frame_idx].extra.user_relevance) + .unwrap_or(0) + } + pub fn current_user_relevant_span(&self) -> Span { + debug_assert_eq!(self.top_user_relevant_frame, self.compute_top_user_relevant_frame(0)); self.top_user_relevant_frame() .map(|frame_idx| self.stack[frame_idx].current_span()) .unwrap_or(rustc_span::DUMMY_SP) diff --git a/src/tools/miri/src/diagnostics.rs b/src/tools/miri/src/diagnostics.rs index 0acdfdd3ffe54..d0cfb9c805e15 100644 --- a/src/tools/miri/src/diagnostics.rs +++ b/src/tools/miri/src/diagnostics.rs @@ -187,16 +187,14 @@ pub fn prune_stacktrace<'tcx>( } BacktraceStyle::Short => { let original_len = stacktrace.len(); - // Only prune frames if there is at least one local frame. This check ensures that if - // we get a backtrace that never makes it to the user code because it has detected a - // bug in the Rust runtime, we don't prune away every frame. - let has_local_frame = stacktrace.iter().any(|frame| machine.is_local(frame)); + // Remove all frames marked with `caller_location` -- that attribute indicates we + // usually want to point at the caller, not them. + stacktrace.retain(|frame| !frame.instance.def.requires_caller_location(machine.tcx)); + // Only prune further frames if there is at least one local frame. This check ensures + // that if we get a backtrace that never makes it to the user code because it has + // detected a bug in the Rust runtime, we don't prune away every frame. + let has_local_frame = stacktrace.iter().any(|frame| machine.is_local(frame.instance)); if has_local_frame { - // Remove all frames marked with `caller_location` -- that attribute indicates we - // usually want to point at the caller, not them. - stacktrace - .retain(|frame| !frame.instance.def.requires_caller_location(machine.tcx)); - // This is part of the logic that `std` uses to select the relevant part of a // backtrace. But here, we only look for __rust_begin_short_backtrace, not // __rust_end_short_backtrace because the end symbol comes from a call to the default @@ -216,7 +214,7 @@ pub fn prune_stacktrace<'tcx>( // This len check ensures that we don't somehow remove every frame, as doing so breaks // the primary error message. while stacktrace.len() > 1 - && stacktrace.last().is_some_and(|frame| !machine.is_local(frame)) + && stacktrace.last().is_some_and(|frame| !machine.is_local(frame.instance)) { stacktrace.pop(); } @@ -619,7 +617,7 @@ pub fn report_msg<'tcx>( write!(backtrace_title, ":").unwrap(); err.note(backtrace_title); for (idx, frame_info) in stacktrace.iter().enumerate() { - let is_local = machine.is_local(frame_info); + let is_local = machine.is_local(frame_info.instance); // No span for non-local frames and the first frame (which is the error site). if is_local && idx > 0 { err.subdiagnostic(frame_info.as_note(machine.tcx)); diff --git a/src/tools/miri/src/helpers.rs b/src/tools/miri/src/helpers.rs index 769e501c45333..7e1fdfa8cdf26 100644 --- a/src/tools/miri/src/helpers.rs +++ b/src/tools/miri/src/helpers.rs @@ -1088,11 +1088,18 @@ impl<'tcx> MiriMachine<'tcx> { self.threads.active_thread_ref().top_user_relevant_frame() } - /// This is the source of truth for the `is_user_relevant` flag in our `FrameExtra`. - pub fn is_user_relevant(&self, frame: &Frame<'tcx, Provenance>) -> bool { - let def_id = frame.instance().def_id(); - (def_id.is_local() || self.user_relevant_crates.contains(&def_id.krate)) - && !frame.instance().def.requires_caller_location(self.tcx) + /// This is the source of truth for the `user_relevance` flag in our `FrameExtra`. + pub fn user_relevance(&self, frame: &Frame<'tcx, Provenance>) -> u8 { + if frame.instance().def.requires_caller_location(self.tcx) { + return 0; + } + if self.is_local(frame.instance()) { + u8::MAX + } else { + // A non-relevant frame, but at least it doesn't require a caller location, so + // better than nothing. + 1 + } } } diff --git a/src/tools/miri/src/machine.rs b/src/tools/miri/src/machine.rs index 33f854bee23df..7ec00d82492e8 100644 --- a/src/tools/miri/src/machine.rs +++ b/src/tools/miri/src/machine.rs @@ -139,11 +139,10 @@ pub struct FrameExtra<'tcx> { /// we use this to register a completed event with `measureme`. pub timing: Option, - /// Indicates whether a `Frame` is part of a workspace-local crate and is also not - /// `#[track_caller]`. We compute this once on creation and store the result, as an - /// optimization. - /// This is used by `MiriMachine::current_span` and `MiriMachine::caller_span` - pub is_user_relevant: bool, + /// Indicates how user-relevant this frame is. `#[track_caller]` frames are never relevant. + /// Frames from user-relevant crates are maximally relevant; frames from other crates are less + /// relevant. + pub user_relevance: u8, /// Data race detector per-frame data. pub data_race: Option, @@ -152,12 +151,12 @@ pub struct FrameExtra<'tcx> { impl<'tcx> std::fmt::Debug for FrameExtra<'tcx> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { // Omitting `timing`, it does not support `Debug`. - let FrameExtra { borrow_tracker, catch_unwind, timing: _, is_user_relevant, data_race } = + let FrameExtra { borrow_tracker, catch_unwind, timing: _, user_relevance, data_race } = self; f.debug_struct("FrameData") .field("borrow_tracker", borrow_tracker) .field("catch_unwind", catch_unwind) - .field("is_user_relevant", is_user_relevant) + .field("user_relevance", user_relevance) .field("data_race", data_race) .finish() } @@ -165,13 +164,8 @@ impl<'tcx> std::fmt::Debug for FrameExtra<'tcx> { impl VisitProvenance for FrameExtra<'_> { fn visit_provenance(&self, visit: &mut VisitWith<'_>) { - let FrameExtra { - catch_unwind, - borrow_tracker, - timing: _, - is_user_relevant: _, - data_race: _, - } = self; + let FrameExtra { catch_unwind, borrow_tracker, timing: _, user_relevance: _, data_race: _ } = + self; catch_unwind.visit_provenance(visit); borrow_tracker.visit_provenance(visit); @@ -910,8 +904,8 @@ impl<'tcx> MiriMachine<'tcx> { } /// Check whether the stack frame that this `FrameInfo` refers to is part of a local crate. - pub(crate) fn is_local(&self, frame: &FrameInfo<'_>) -> bool { - let def_id = frame.instance.def_id(); + pub(crate) fn is_local(&self, instance: ty::Instance<'tcx>) -> bool { + let def_id = instance.def_id(); def_id.is_local() || self.user_relevant_crates.contains(&def_id.krate) } @@ -1702,7 +1696,7 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> { borrow_tracker: borrow_tracker.map(|bt| bt.borrow_mut().new_frame()), catch_unwind: None, timing, - is_user_relevant: ecx.machine.is_user_relevant(&frame), + user_relevance: ecx.machine.user_relevance(&frame), data_race: ecx .machine .data_race @@ -1758,9 +1752,9 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> { #[inline(always)] fn after_stack_push(ecx: &mut InterpCx<'tcx, Self>) -> InterpResult<'tcx> { - if ecx.frame().extra.is_user_relevant { - // We just pushed a local frame, so we know that the topmost local frame is the topmost - // frame. If we push a non-local frame, there's no need to do anything. + if ecx.frame().extra.user_relevance >= ecx.active_thread_ref().current_user_relevance() { + // We just pushed a frame that's at least as relevant as the so-far most relevant frame. + // That means we are now the most relevant frame. let stack_len = ecx.active_thread_stack().len(); ecx.active_thread_mut().set_top_user_relevant_frame(stack_len - 1); } @@ -1774,9 +1768,14 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> { if ecx.machine.borrow_tracker.is_some() { ecx.on_stack_pop(frame)?; } - if frame.extra.is_user_relevant { - // All that we store is whether or not the frame we just removed is local, so now we - // have no idea where the next topmost local frame is. So we recompute it. + if ecx + .active_thread_ref() + .top_user_relevant_frame() + .expect("there should always be a most relevant frame for a non-empty stack") + == ecx.frame_idx() + { + // We are popping the most relevant frame. We have no clue what the next relevant frame + // below that is, so we recompute that. // (If this ever becomes a bottleneck, we could have `push` store the previous // user-relevant frame and restore that here.) // We have to skip the frame that is just being popped. diff --git a/src/tools/miri/tests/fail/panic/tls_macro_drop_panic.stderr b/src/tools/miri/tests/fail/panic/tls_macro_drop_panic.stderr index 4fdaa97e1d0a2..39263a8d61cc9 100644 --- a/src/tools/miri/tests/fail/panic/tls_macro_drop_panic.stderr +++ b/src/tools/miri/tests/fail/panic/tls_macro_drop_panic.stderr @@ -4,5 +4,6 @@ ow fatal runtime error: thread local panicked on drop, aborting error: abnormal termination: the program aborted execution + error: aborting due to 1 previous error diff --git a/src/tools/miri/tests/genmc/pass/std/arc.check_count.stderr b/src/tools/miri/tests/genmc/pass/std/arc.check_count.stderr index 878077edb818e..695aa3f5aeaf8 100644 --- a/src/tools/miri/tests/genmc/pass/std/arc.check_count.stderr +++ b/src/tools/miri/tests/genmc/pass/std/arc.check_count.stderr @@ -1,9 +1,9 @@ Running GenMC Verification... warning: GenMC currently does not model spurious failures of `compare_exchange_weak`. Miri with GenMC might miss bugs related to spurious failures. - --> RUSTLIB/core/src/sync/atomic.rs:LL:CC + --> RUSTLIB/std/src/thread/mod.rs:LL:CC | -LL | intrinsics::atomic_cxchgweak::(dst, old, new) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code +LL | match COUNTER.compare_exchange_weak(last, id, Ordering::Relaxed, Ordering::Relaxed) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code | = note: BACKTRACE: = note: inside closure at RUSTLIB/std/src/thread/current.rs:LL:CC @@ -91,19 +91,34 @@ LL | handle.join().unwrap(); | ^^^^^^^^^^^^^ warning: GenMC currently does not model spurious failures of `compare_exchange_weak`. Miri with GenMC might miss bugs related to spurious failures. - --> RUSTLIB/core/src/sync/atomic.rs:LL:CC + --> RUSTLIB/std/src/rt.rs:LL:CC | -LL | intrinsics::atomic_cxchgweak::(dst, old, new) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code +LL | / CLEANUP.call_once(|| unsafe { +LL | | // Flush stdout and disable buffering. +LL | | crate::io::cleanup(); +... | +LL | | }); + | |______^ GenMC might miss possible behaviors of this code | = note: BACKTRACE: = note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC +warning: GenMC currently does not model spurious failures of `compare_exchange_weak`. Miri with GenMC might miss bugs related to spurious failures. + --> RUSTLIB/std/src/sync/once.rs:LL:CC + | +LL | self.inner.call(true, &mut |p| f.take().unwrap()(p)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code + | + = note: BACKTRACE: + = note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC + = note: inside closure at RUSTLIB/std/src/sync/once.rs:LL:CC + = note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC + warning: GenMC currently does not model the failure ordering for `compare_exchange`. Due to success ordering 'Acquire', the failure ordering 'Relaxed' is treated like 'Acquire'. Miri with GenMC might miss bugs related to this memory access. - --> RUSTLIB/core/src/sync/atomic.rs:LL:CC + --> RUSTLIB/std/src/sys/exit_guard.rs:LL:CC | -LL | intrinsics::atomic_cxchg::(dst, old, new) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code +LL | match EXITING_THREAD_ID.compare_exchange(ptr::null_mut(), this_thread_id, Acquire, Relaxed) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code | = note: BACKTRACE: = note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC diff --git a/src/tools/miri/tests/genmc/pass/std/arc.try_upgrade.stderr b/src/tools/miri/tests/genmc/pass/std/arc.try_upgrade.stderr index fc43c63135902..8609c2c5c8645 100644 --- a/src/tools/miri/tests/genmc/pass/std/arc.try_upgrade.stderr +++ b/src/tools/miri/tests/genmc/pass/std/arc.try_upgrade.stderr @@ -1,9 +1,9 @@ Running GenMC Verification... warning: GenMC currently does not model spurious failures of `compare_exchange_weak`. Miri with GenMC might miss bugs related to spurious failures. - --> RUSTLIB/core/src/sync/atomic.rs:LL:CC + --> RUSTLIB/std/src/thread/mod.rs:LL:CC | -LL | intrinsics::atomic_cxchgweak::(dst, old, new) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code +LL | match COUNTER.compare_exchange_weak(last, id, Ordering::Relaxed, Ordering::Relaxed) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code | = note: BACKTRACE: = note: inside closure at RUSTLIB/std/src/thread/current.rs:LL:CC @@ -91,19 +91,34 @@ LL | handle.join().unwrap(); | ^^^^^^^^^^^^^ warning: GenMC currently does not model spurious failures of `compare_exchange_weak`. Miri with GenMC might miss bugs related to spurious failures. - --> RUSTLIB/core/src/sync/atomic.rs:LL:CC + --> RUSTLIB/std/src/rt.rs:LL:CC | -LL | intrinsics::atomic_cxchgweak::(dst, old, new) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code +LL | / CLEANUP.call_once(|| unsafe { +LL | | // Flush stdout and disable buffering. +LL | | crate::io::cleanup(); +... | +LL | | }); + | |______^ GenMC might miss possible behaviors of this code | = note: BACKTRACE: = note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC +warning: GenMC currently does not model spurious failures of `compare_exchange_weak`. Miri with GenMC might miss bugs related to spurious failures. + --> RUSTLIB/std/src/sync/once.rs:LL:CC + | +LL | self.inner.call(true, &mut |p| f.take().unwrap()(p)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code + | + = note: BACKTRACE: + = note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC + = note: inside closure at RUSTLIB/std/src/sync/once.rs:LL:CC + = note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC + warning: GenMC currently does not model the failure ordering for `compare_exchange`. Due to success ordering 'Acquire', the failure ordering 'Relaxed' is treated like 'Acquire'. Miri with GenMC might miss bugs related to this memory access. - --> RUSTLIB/core/src/sync/atomic.rs:LL:CC + --> RUSTLIB/std/src/sys/exit_guard.rs:LL:CC | -LL | intrinsics::atomic_cxchg::(dst, old, new) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code +LL | match EXITING_THREAD_ID.compare_exchange(ptr::null_mut(), this_thread_id, Acquire, Relaxed) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code | = note: BACKTRACE: = note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC diff --git a/src/tools/miri/tests/genmc/pass/std/empty_main.stderr b/src/tools/miri/tests/genmc/pass/std/empty_main.stderr index 1b8712167d8a9..b1413ee6d574b 100644 --- a/src/tools/miri/tests/genmc/pass/std/empty_main.stderr +++ b/src/tools/miri/tests/genmc/pass/std/empty_main.stderr @@ -1,28 +1,43 @@ Running GenMC Verification... warning: GenMC currently does not model spurious failures of `compare_exchange_weak`. Miri with GenMC might miss bugs related to spurious failures. - --> RUSTLIB/core/src/sync/atomic.rs:LL:CC + --> RUSTLIB/std/src/thread/mod.rs:LL:CC | -LL | intrinsics::atomic_cxchgweak::(dst, old, new) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code +LL | match COUNTER.compare_exchange_weak(last, id, Ordering::Relaxed, Ordering::Relaxed) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code | = note: BACKTRACE: = note: inside closure at RUSTLIB/std/src/thread/current.rs:LL:CC = note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC warning: GenMC currently does not model spurious failures of `compare_exchange_weak`. Miri with GenMC might miss bugs related to spurious failures. - --> RUSTLIB/core/src/sync/atomic.rs:LL:CC + --> RUSTLIB/std/src/rt.rs:LL:CC | -LL | intrinsics::atomic_cxchgweak::(dst, old, new) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code +LL | / CLEANUP.call_once(|| unsafe { +LL | | // Flush stdout and disable buffering. +LL | | crate::io::cleanup(); +... | +LL | | }); + | |______^ GenMC might miss possible behaviors of this code | = note: BACKTRACE: = note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC +warning: GenMC currently does not model spurious failures of `compare_exchange_weak`. Miri with GenMC might miss bugs related to spurious failures. + --> RUSTLIB/std/src/sync/once.rs:LL:CC + | +LL | self.inner.call(true, &mut |p| f.take().unwrap()(p)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code + | + = note: BACKTRACE: + = note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC + = note: inside closure at RUSTLIB/std/src/sync/once.rs:LL:CC + = note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC + warning: GenMC currently does not model the failure ordering for `compare_exchange`. Due to success ordering 'Acquire', the failure ordering 'Relaxed' is treated like 'Acquire'. Miri with GenMC might miss bugs related to this memory access. - --> RUSTLIB/core/src/sync/atomic.rs:LL:CC + --> RUSTLIB/std/src/sys/exit_guard.rs:LL:CC | -LL | intrinsics::atomic_cxchg::(dst, old, new) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code +LL | match EXITING_THREAD_ID.compare_exchange(ptr::null_mut(), this_thread_id, Acquire, Relaxed) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code | = note: BACKTRACE: = note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC diff --git a/src/tools/miri/tests/genmc/pass/std/spawn_std_threads.stderr b/src/tools/miri/tests/genmc/pass/std/spawn_std_threads.stderr index b148c11e39b1f..87d3c60ef02e7 100644 --- a/src/tools/miri/tests/genmc/pass/std/spawn_std_threads.stderr +++ b/src/tools/miri/tests/genmc/pass/std/spawn_std_threads.stderr @@ -1,9 +1,9 @@ Running GenMC Verification... warning: GenMC currently does not model spurious failures of `compare_exchange_weak`. Miri with GenMC might miss bugs related to spurious failures. - --> RUSTLIB/core/src/sync/atomic.rs:LL:CC + --> RUSTLIB/std/src/thread/mod.rs:LL:CC | -LL | intrinsics::atomic_cxchgweak::(dst, old, new) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code +LL | match COUNTER.compare_exchange_weak(last, id, Ordering::Relaxed, Ordering::Relaxed) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code | = note: BACKTRACE: = note: inside closure at RUSTLIB/std/src/thread/current.rs:LL:CC @@ -95,19 +95,34 @@ LL | handles.into_iter().for_each(|handle| handle.join().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: GenMC currently does not model spurious failures of `compare_exchange_weak`. Miri with GenMC might miss bugs related to spurious failures. - --> RUSTLIB/core/src/sync/atomic.rs:LL:CC + --> RUSTLIB/std/src/rt.rs:LL:CC | -LL | intrinsics::atomic_cxchgweak::(dst, old, new) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code +LL | / CLEANUP.call_once(|| unsafe { +LL | | // Flush stdout and disable buffering. +LL | | crate::io::cleanup(); +... | +LL | | }); + | |______^ GenMC might miss possible behaviors of this code | = note: BACKTRACE: = note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC +warning: GenMC currently does not model spurious failures of `compare_exchange_weak`. Miri with GenMC might miss bugs related to spurious failures. + --> RUSTLIB/std/src/sync/once.rs:LL:CC + | +LL | self.inner.call(true, &mut |p| f.take().unwrap()(p)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code + | + = note: BACKTRACE: + = note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC + = note: inside closure at RUSTLIB/std/src/sync/once.rs:LL:CC + = note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC + warning: GenMC currently does not model the failure ordering for `compare_exchange`. Due to success ordering 'Acquire', the failure ordering 'Relaxed' is treated like 'Acquire'. Miri with GenMC might miss bugs related to this memory access. - --> RUSTLIB/core/src/sync/atomic.rs:LL:CC + --> RUSTLIB/std/src/sys/exit_guard.rs:LL:CC | -LL | intrinsics::atomic_cxchg::(dst, old, new) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code +LL | match EXITING_THREAD_ID.compare_exchange(ptr::null_mut(), this_thread_id, Acquire, Relaxed) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code | = note: BACKTRACE: = note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC diff --git a/src/tools/miri/tests/genmc/pass/std/thread_locals.stderr b/src/tools/miri/tests/genmc/pass/std/thread_locals.stderr index 208de4e37ffba..91d2f5daa146f 100644 --- a/src/tools/miri/tests/genmc/pass/std/thread_locals.stderr +++ b/src/tools/miri/tests/genmc/pass/std/thread_locals.stderr @@ -1,9 +1,9 @@ Running GenMC Verification... warning: GenMC currently does not model spurious failures of `compare_exchange_weak`. Miri with GenMC might miss bugs related to spurious failures. - --> RUSTLIB/core/src/sync/atomic.rs:LL:CC + --> RUSTLIB/std/src/thread/mod.rs:LL:CC | -LL | intrinsics::atomic_cxchgweak::(dst, old, new) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code +LL | match COUNTER.compare_exchange_weak(last, id, Ordering::Relaxed, Ordering::Relaxed) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code | = note: BACKTRACE: = note: inside closure at RUSTLIB/std/src/thread/current.rs:LL:CC @@ -78,19 +78,34 @@ LL | handles.into_iter().for_each(|handle| handle.join().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: GenMC currently does not model spurious failures of `compare_exchange_weak`. Miri with GenMC might miss bugs related to spurious failures. - --> RUSTLIB/core/src/sync/atomic.rs:LL:CC + --> RUSTLIB/std/src/rt.rs:LL:CC | -LL | intrinsics::atomic_cxchgweak::(dst, old, new) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code +LL | / CLEANUP.call_once(|| unsafe { +LL | | // Flush stdout and disable buffering. +LL | | crate::io::cleanup(); +... | +LL | | }); + | |______^ GenMC might miss possible behaviors of this code | = note: BACKTRACE: = note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC +warning: GenMC currently does not model spurious failures of `compare_exchange_weak`. Miri with GenMC might miss bugs related to spurious failures. + --> RUSTLIB/std/src/sync/once.rs:LL:CC + | +LL | self.inner.call(true, &mut |p| f.take().unwrap()(p)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code + | + = note: BACKTRACE: + = note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC + = note: inside closure at RUSTLIB/std/src/sync/once.rs:LL:CC + = note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC + warning: GenMC currently does not model the failure ordering for `compare_exchange`. Due to success ordering 'Acquire', the failure ordering 'Relaxed' is treated like 'Acquire'. Miri with GenMC might miss bugs related to this memory access. - --> RUSTLIB/core/src/sync/atomic.rs:LL:CC + --> RUSTLIB/std/src/sys/exit_guard.rs:LL:CC | -LL | intrinsics::atomic_cxchg::(dst, old, new) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code +LL | match EXITING_THREAD_ID.compare_exchange(ptr::null_mut(), this_thread_id, Acquire, Relaxed) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code | = note: BACKTRACE: = note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC From bddac3c3d4ce2793d10b84a8639c59c022e4bbed Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 4 Nov 2025 20:54:42 +0100 Subject: [PATCH 10/17] x86/rounding-error test: avoid rounding during error calculation --- .../tests/pass/shims/x86/rounding-error.rs | 36 ++++++++++--------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/src/tools/miri/tests/pass/shims/x86/rounding-error.rs b/src/tools/miri/tests/pass/shims/x86/rounding-error.rs index bf56111b2e496..aa9fd96861812 100644 --- a/src/tools/miri/tests/pass/shims/x86/rounding-error.rs +++ b/src/tools/miri/tests/pass/shims/x86/rounding-error.rs @@ -11,25 +11,27 @@ use std::arch::x86_64::*; use std::collections::HashSet; fn main() { + let a = unsafe { _mm_setr_ps(4.0, 4.0, 4.0, 4.0) }; + let exact = 0.5; + // max error: 2^-12. + let rel_error_bound = 1.0 / (1 << 12) as f32; + let mut vals = HashSet::new(); for _ in 0..50 { - unsafe { - // Compute the inverse square root of 4.0, four times. - let a = _mm_setr_ps(4.0, 4.0, 4.0, 4.0); - let exact = 0.5; - let r = _mm_rsqrt_ps(a); - let r: [f32; 4] = std::mem::transmute(r); - // Check the results. - for r in r { - vals.insert(r.to_bits()); - // Ensure the relative error is less than 2^-12. - let rel_error = (r - exact) / exact; - let log_error = rel_error.abs().log2(); - assert!( - rel_error == 0.0 || log_error < -12.0, - "got an error of {rel_error} = 2^{log_error}" - ); - } + // Compute the inverse square root of 4.0, four times. + let r = unsafe { _mm_rsqrt_ps(a) }; + let r: [f32; 4] = unsafe { std::mem::transmute(r) }; + // Check the results. + for r in r { + vals.insert(r.to_bits()); + // Ensure the relative error is no more than 2^-12. + let rel_error = (r - exact) / exact; + assert!( + rel_error.abs() <= rel_error_bound, + "correct result: {exact}, got: {r}\n\ + that's a relative error of {rel_error} (= 2^{log_error})", + log_error = rel_error.abs().log2() + ); } } // Ensure we saw a bunch of different results. From 389c3ce0f762bf4d6713ce6eb2b0f66945115065 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 30 Oct 2025 15:04:49 +0000 Subject: [PATCH 11/17] Remove no longer necessary lint allow --- library/panic_unwind/src/lib.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/library/panic_unwind/src/lib.rs b/library/panic_unwind/src/lib.rs index 83311f3238012..1be19913f260f 100644 --- a/library/panic_unwind/src/lib.rs +++ b/library/panic_unwind/src/lib.rs @@ -24,8 +24,6 @@ #![feature(rustc_attrs)] #![panic_runtime] #![feature(panic_runtime)] -// `real_imp` is unused with Miri, so silence warnings. -#![cfg_attr(miri, allow(dead_code))] #![allow(internal_features)] #![warn(unreachable_pub)] #![deny(unsafe_op_in_unsafe_fn)] From f7f0ca4b76c5a3beaed7b4f4823200cb20ea54b7 Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Tue, 4 Nov 2025 15:26:01 -0600 Subject: [PATCH 12/17] triagebot: Create Zulip topics for libs backports Take the configuration used by other teams to create Zulip topics for T-libs backports. --- triagebot.toml | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/triagebot.toml b/triagebot.toml index 5a96d96b346d4..325a62235c71c 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -794,6 +794,55 @@ zulip_stream = 474880 # #t-compiler/backports topic = "#{number}: stable-nominated" message_on_add = "PR #{number} has been **accepted** for **stable** backport." +[notify-zulip."beta-nominated".libs] +required_labels = ["T-libs"] +zulip_stream = 542373 # #t-libs/backports +topic = "#{number}: beta-nominated" +message_on_add = [ + """\ +@*T-libs* PR #{number} "{title}" has been nominated for beta backport. +""", + """\ +/poll Should #{number} be beta backported? +approve +decline +don't know +""", +] +message_on_remove = "PR #{number}'s beta-nomination has been removed." + +[notify-zulip."beta-accepted".libs] +required_labels = ["T-libs"] +zulip_stream = 542373 # #t-libs/backports +# Put it in the same Zulip topic as beta-nominated. +topic = "#{number}: beta-nominated" +message_on_add = "PR #{number} has been **accepted** for **beta** backport." + +[notify-zulip."stable-nominated".libs] +required_labels = ["T-libs"] +zulip_stream = 542373 # #t-libs/backports +topic = "#{number}: stable-nominated" +message_on_add = [ + """\ +@**channel** PR #{number} "{title}" has been nominated for stable backport. +""", + """\ +/poll Approve stable backport of #{number}? +approve +approve (but does not justify new dot release on its own) +decline +don't know +""", +] +message_on_remove = "PR #{number}'s stable-nomination has been removed." + +[notify-zulip."stable-accepted".libs] +required_labels = ["T-libs"] +zulip_stream = 542373 # #t-libs/backports +# Put it in the same thread as stable-nominated. +topic = "#{number}: stable-nominated" +message_on_add = "PR #{number} has been **accepted** for **stable** backport." + [notify-zulip."beta-nominated".bootstrap] required_labels = ["T-bootstrap"] From 72d94d10df294312c66da9c7bca0d2ea992c17fa Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 3 Nov 2025 13:59:50 +0100 Subject: [PATCH 13/17] [rustdoc search] Simplify itemTypes and filter "dependencies" --- src/librustdoc/html/static/js/search.js | 190 +++++++++++------------- 1 file changed, 88 insertions(+), 102 deletions(-) diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js index e281139ca38ff..e3829603072b0 100644 --- a/src/librustdoc/html/static/js/search.js +++ b/src/librustdoc/html/static/js/search.js @@ -91,54 +91,55 @@ if (!Promise.withResolvers) { // ==================== Core search logic begin ==================== // This mapping table should match the discriminants of // `rustdoc::formats::item_type::ItemType` type in Rust. -const itemTypes = [ - "keyword", - "primitive", - "mod", - "externcrate", - "import", - "struct", // 5 - "enum", - "fn", - "type", - "static", - "trait", // 10 - "impl", - "tymethod", - "method", - "structfield", - "variant", // 15 - "macro", - "associatedtype", - "constant", - "associatedconstant", - "union", // 20 - "foreigntype", - "existential", - "attr", - "derive", - "traitalias", // 25 - "generic", - "attribute", -]; +const itemTypes = Object.freeze({ + keyword: 0, + primitive: 1, + mod: 2, + externcrate: 3, + import: 4, + struct: 5, + enum: 6, + fn: 7, + type: 8, + static: 9, + trait: 10, + impl: 11, + tymethod: 12, + method: 13, + structfield: 14, + variant: 15, + macro: 16, + associatedtype: 17, + constant: 18, + associatedconstant: 19, + union: 20, + foreigntype: 21, + existential: 22, + attr: 23, + derive: 24, + traitalias: 25, + generic: 26, + attribute: 27, +}); +const itemTypesName = Array.from(Object.keys(itemTypes)); + +// When filtering, some types might be included as well. For example, when you filter on `constant`, +// we also include associated constant items. +// +// This map is built as follows: the first item of the array is the type to be included when the +// second type of the array is used as filter. +const itemParents = new Map([ + [itemTypes.associatedconstant, itemTypes.constant], + [itemTypes.method, itemTypes.fn], + [itemTypes.tymethod, itemTypes.fn], + [itemTypes.primitive, itemTypes.type], + [itemTypes.associatedtype, itemTypes.type], + [itemTypes.traitalias, itemTypes.trait], + [itemTypes.attr, itemTypes.macro], + [itemTypes.derive, itemTypes.macro], + [itemTypes.externcrate, itemTypes.import], +]); -// used for special search precedence -/** @type {rustdoc.ItemType} */ -const TY_PRIMITIVE = 1; -/** @type {rustdoc.ItemType} */ -const TY_GENERIC = 26; -/** @type {rustdoc.ItemType} */ -const TY_IMPORT = 4; -/** @type {rustdoc.ItemType} */ -const TY_TRAIT = 10; -/** @type {rustdoc.ItemType} */ -const TY_FN = 7; -/** @type {rustdoc.ItemType} */ -const TY_METHOD = 13; -/** @type {rustdoc.ItemType} */ -const TY_TYMETHOD = 12; -/** @type {rustdoc.ItemType} */ -const TY_ASSOCTYPE = 17; const ROOT_PATH = typeof window !== "undefined" ? window.rootPath : "../"; // Hard limit on how deep to recurse into generics when doing type-driven search. @@ -302,7 +303,7 @@ function isEndCharacter(c) { * @returns */ function isFnLikeTy(ty) { - return ty === TY_FN || ty === TY_METHOD || ty === TY_TYMETHOD; + return ty === itemTypes.fn || ty === itemTypes.method || ty === itemTypes.tymethod; } /** @@ -1205,8 +1206,9 @@ function itemTypeFromName(typename) { if (typename === null) { return NO_TYPE_FILTER; } - const index = itemTypes.findIndex(i => i === typename); - if (index < 0) { + // @ts-expect-error + const index = itemTypes[typename]; + if (index === undefined) { throw ["Unknown type filter ", typename]; } return index; @@ -1329,21 +1331,21 @@ class DocSearch { } return -1; }; - const typeNameIdOfOutput = await first(output, TY_ASSOCTYPE, ""); - const typeNameIdOfFnPtr = await first(fn, TY_PRIMITIVE, ""); - const typeNameIdOfFn = await first(fn, TY_TRAIT, "core::ops"); - const typeNameIdOfFnMut = await first(fnMut, TY_TRAIT, "core::ops"); - const typeNameIdOfFnOnce = await first(fnOnce, TY_TRAIT, "core::ops"); - const typeNameIdOfArray = await first(array, TY_PRIMITIVE, ""); - const typeNameIdOfSlice = await first(slice, TY_PRIMITIVE, ""); - const typeNameIdOfArrayOrSlice = await first(arrayOrSlice, TY_PRIMITIVE, ""); - const typeNameIdOfTuple = await first(tuple, TY_PRIMITIVE, ""); - const typeNameIdOfUnit = await first(unit, TY_PRIMITIVE, ""); - const typeNameIdOfTupleOrUnit = await first(tupleOrUnit, TY_PRIMITIVE, ""); - const typeNameIdOfReference = await first(reference, TY_PRIMITIVE, ""); - const typeNameIdOfPointer = await first(pointer, TY_PRIMITIVE, ""); - const typeNameIdOfHof = await first(hof, TY_PRIMITIVE, ""); - const typeNameIdOfNever = await first(never, TY_PRIMITIVE, ""); + const typeNameIdOfOutput = await first(output, itemTypes.associatedtype, ""); + const typeNameIdOfFnPtr = await first(fn, itemTypes.primitive, ""); + const typeNameIdOfFn = await first(fn, itemTypes.trait, "core::ops"); + const typeNameIdOfFnMut = await first(fnMut, itemTypes.trait, "core::ops"); + const typeNameIdOfFnOnce = await first(fnOnce, itemTypes.trait, "core::ops"); + const typeNameIdOfArray = await first(array, itemTypes.primitive, ""); + const typeNameIdOfSlice = await first(slice, itemTypes.primitive, ""); + const typeNameIdOfArrayOrSlice = await first(arrayOrSlice, itemTypes.primitive, ""); + const typeNameIdOfTuple = await first(tuple, itemTypes.primitive, ""); + const typeNameIdOfUnit = await first(unit, itemTypes.primitive, ""); + const typeNameIdOfTupleOrUnit = await first(tupleOrUnit, itemTypes.primitive, ""); + const typeNameIdOfReference = await first(reference, itemTypes.primitive, ""); + const typeNameIdOfPointer = await first(pointer, itemTypes.primitive, ""); + const typeNameIdOfHof = await first(hof, itemTypes.primitive, ""); + const typeNameIdOfNever = await first(never, itemTypes.primitive, ""); this.typeNameIds = { typeNameIdOfOutput, typeNameIdOfFnPtr, @@ -1520,7 +1522,7 @@ class DocSearch { /** @param {rustdoc.ParserQueryElement} elem */ const checkTypeFilter = elem => { const ty = itemTypeFromName(elem.typeFilter); - if (ty === TY_GENERIC && elem.generics.length !== 0) { + if (ty === itemTypes.generic && elem.generics.length !== 0) { throw [ "Generic type parameter ", elem.name, @@ -2033,7 +2035,7 @@ class DocSearch { result = { id, name: "", - ty: TY_GENERIC, + ty: itemTypes.generic, path: null, exactPath: null, generics, @@ -2045,7 +2047,7 @@ class DocSearch { result = { id: null, name: "", - ty: TY_GENERIC, + ty: itemTypes.generic, path: null, exactPath: null, generics, @@ -2062,7 +2064,7 @@ class DocSearch { return { id: null, name: "", - ty: TY_GENERIC, + ty: itemTypes.generic, path: null, exactPath: null, generics, @@ -2149,7 +2151,7 @@ class DocSearch { let displayPath; let href; let traitPath = null; - const type = itemTypes[item.ty]; + const type = itemTypesName[item.ty]; const name = item.name; let path = item.modulePath; let exactPath = item.exactModulePath; @@ -2173,7 +2175,7 @@ class DocSearch { } else if (item.parent) { const myparent = item.parent; let anchor = type + "." + name; - const parentType = itemTypes[myparent.path.ty]; + const parentType = itemTypesName[myparent.path.ty]; let pageType = parentType; let pageName = myparent.name; exactPath = `${myparent.path.exactModulePath}::${myparent.name}`; @@ -2520,11 +2522,11 @@ class DocSearch { whereClause.set(fnParamNames[-1 - fnType.id], where); } } else { - if (fnType.ty === TY_PRIMITIVE) { + if (fnType.ty === itemTypes.primitive) { if (await writeSpecialPrimitive(fnType, result)) { return; } - } else if (fnType.ty === TY_TRAIT && ( + } else if (fnType.ty === itemTypes.trait && ( fnType.id === typeNameIds.typeNameIdOfFn || fnType.id === typeNameIds.typeNameIdOfFnMut || fnType.id === typeNameIds.typeNameIdOfFnOnce || @@ -2691,8 +2693,8 @@ class DocSearch { // unlike other items, methods have a different ty when they are // in an impl block vs a trait. want to normalize this away. let ty = obj.item.ty; - if (ty === TY_TYMETHOD) { - ty = TY_METHOD; + if (ty === itemTypes.tymethod) { + ty = itemTypes.method; } // To be sure than it some items aren't considered as duplicate. obj.fullPath = res[2] + "|" + ty; @@ -2714,10 +2716,10 @@ class DocSearch { // Exports are specifically not shown if the items they point at // are already in the results. - if (obj.item.ty === TY_IMPORT && duplicates.has(res[2])) { + if (obj.item.ty === itemTypes.import && duplicates.has(res[2])) { continue; } - if (duplicates.has(res[2] + "|" + TY_IMPORT)) { + if (duplicates.has(res[2] + "|" + itemTypes.import)) { continue; } duplicates.add(obj.fullPath); @@ -3894,24 +3896,8 @@ class DocSearch { if (filter <= NO_TYPE_FILTER || filter === type) return true; // Match related items - const name = itemTypes[type]; - switch (itemTypes[filter]) { - case "constant": - return name === "associatedconstant"; - case "fn": - return name === "method" || name === "tymethod"; - case "type": - return name === "primitive" || name === "associatedtype"; - case "trait": - return name === "traitalias"; - case "macro": - return name === "attr" || name === "derive"; - case "import": - return name === "externcrate"; - } - - // No match - return false; + // @ts-expect-error + return filter === itemParents.get(type); } const innerRunNameQuery = @@ -4246,7 +4232,7 @@ class DocSearch { * ]>[]} * */ const typePromises = []; - if (typeFilter !== TY_GENERIC && searchResults) { + if (typeFilter !== itemTypes.generic && searchResults) { for (const id of searchResults.matches().entries()) { typePromises.push(Promise.all([ this.getName(id), @@ -4262,7 +4248,7 @@ class DocSearch { ty && !ty[polarity].every(bitmap => { return bitmap.isEmpty(); }) && - path && path.ty !== TY_ASSOCTYPE && + path && path.ty !== itemTypes.associatedtype && (elem.pathWithoutLast.length === 0 || checkPath( elem.pathWithoutLast, @@ -4270,14 +4256,14 @@ class DocSearch { ) === 0), ); if (types.length === 0) { - const areGenericsAllowed = typeFilter === TY_GENERIC || ( + const areGenericsAllowed = typeFilter === itemTypes.generic || ( typeFilter === -1 && (parsedQuery.totalElems > 1 || parsedQuery.hasReturnArrow) && elem.pathWithoutLast.length === 0 && elem.generics.length === 0 && elem.bindings.size === 0 ); - if (typeFilter !== TY_GENERIC && + if (typeFilter !== itemTypes.generic && (elem.name.length >= 3 || !areGenericsAllowed) ) { /** @type {string|null} */ @@ -4301,7 +4287,7 @@ class DocSearch { !ty[polarity].every(bitmap => { return bitmap.isEmpty(); }) && - path.ty !== TY_ASSOCTYPE + path.ty !== itemTypes.associatedtype ) { let dist = editDistance( name, @@ -4363,7 +4349,7 @@ class DocSearch { queryElem: { name: elem.name, id: (-genericId) - 1, - typeFilter: TY_GENERIC, + typeFilter: itemTypes.generic, generics: [], bindings: EMPTY_BINDINGS_MAP, fullPath: elem.fullPath, @@ -4930,7 +4916,7 @@ async function addTab(results, query, display, finishedCallback, isTypeSearch) { count += 1; const name = obj.item.name; - const type = itemTypes[obj.item.ty]; + const type = itemTypesName[obj.item.ty]; const longType = longItemTypes[obj.item.ty]; const typeName = longType.length !== 0 ? `${longType}` : "?"; From 973c7527b41f5b39ee84c705f61c0e7b8a712fff Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 5 Nov 2025 10:16:39 +0000 Subject: [PATCH 14/17] Unify the configuration of the compiler docs Previously it was rather inconsistent which crates got the rust logo and which didn't and setting html_root_url was forgotten in many cases. --- compiler/rustc_abi/src/lib.rs | 2 -- compiler/rustc_arena/src/lib.rs | 7 +------ compiler/rustc_ast/src/lib.rs | 8 +------- compiler/rustc_ast_lowering/src/lib.rs | 3 --- compiler/rustc_ast_passes/src/lib.rs | 3 --- compiler/rustc_ast_pretty/src/lib.rs | 3 --- compiler/rustc_attr_parsing/src/lib.rs | 3 --- compiler/rustc_baked_icu_data/src/lib.rs | 3 --- compiler/rustc_borrowck/src/lib.rs | 2 -- compiler/rustc_builtin_macros/src/lib.rs | 3 --- compiler/rustc_codegen_cranelift/src/lib.rs | 3 --- compiler/rustc_codegen_gcc/src/lib.rs | 3 --- compiler/rustc_codegen_llvm/src/lib.rs | 4 ---- compiler/rustc_codegen_ssa/src/lib.rs | 4 ---- compiler/rustc_const_eval/src/lib.rs | 3 --- compiler/rustc_data_structures/src/lib.rs | 3 --- compiler/rustc_driver/src/lib.rs | 6 ------ compiler/rustc_driver_impl/src/lib.rs | 4 ---- compiler/rustc_error_codes/src/lib.rs | 3 --- compiler/rustc_error_messages/src/lib.rs | 2 -- compiler/rustc_errors/src/lib.rs | 3 --- compiler/rustc_expand/src/lib.rs | 2 -- compiler/rustc_feature/src/lib.rs | 6 ------ compiler/rustc_fluent_macro/src/lib.rs | 4 ---- compiler/rustc_graphviz/src/lib.rs | 8 +------- compiler/rustc_hir_analysis/src/lib.rs | 4 ---- compiler/rustc_incremental/src/lib.rs | 4 ---- compiler/rustc_index/src/lib.rs | 1 - compiler/rustc_infer/src/lib.rs | 4 ---- compiler/rustc_lint/src/lib.rs | 3 --- compiler/rustc_llvm/src/lib.rs | 4 ---- compiler/rustc_metadata/src/lib.rs | 3 --- compiler/rustc_middle/src/lib.rs | 3 --- compiler/rustc_parse_format/src/lib.rs | 6 +----- compiler/rustc_passes/src/lib.rs | 4 ---- compiler/rustc_privacy/src/lib.rs | 4 ---- compiler/rustc_public/src/lib.rs | 5 +---- compiler/rustc_public_bridge/src/lib.rs | 8 +------- compiler/rustc_query_impl/src/lib.rs | 3 --- compiler/rustc_resolve/src/lib.rs | 3 --- compiler/rustc_serialize/src/lib.rs | 8 +------- compiler/rustc_span/src/lib.rs | 3 --- compiler/rustc_symbol_mangling/src/lib.rs | 4 ---- compiler/rustc_target/src/lib.rs | 4 ---- compiler/rustc_trait_selection/src/lib.rs | 4 ---- compiler/rustc_ty_utils/src/lib.rs | 4 ---- src/bootstrap/src/bin/rustdoc.rs | 15 +++++++++++++++ 47 files changed, 22 insertions(+), 174 deletions(-) diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs index 1dc4441f039aa..cd85efb2753ae 100644 --- a/compiler/rustc_abi/src/lib.rs +++ b/compiler/rustc_abi/src/lib.rs @@ -1,9 +1,7 @@ // tidy-alphabetical-start #![cfg_attr(feature = "nightly", allow(internal_features))] -#![cfg_attr(feature = "nightly", doc(rust_logo))] #![cfg_attr(feature = "nightly", feature(assert_matches))] #![cfg_attr(feature = "nightly", feature(rustc_attrs))] -#![cfg_attr(feature = "nightly", feature(rustdoc_internals))] #![cfg_attr(feature = "nightly", feature(step_trait))] // tidy-alphabetical-end diff --git a/compiler/rustc_arena/src/lib.rs b/compiler/rustc_arena/src/lib.rs index d3b7e679d171b..40d0d3735de01 100644 --- a/compiler/rustc_arena/src/lib.rs +++ b/compiler/rustc_arena/src/lib.rs @@ -12,18 +12,13 @@ #![allow(internal_features)] #![cfg_attr(test, feature(test))] #![deny(unsafe_op_in_unsafe_fn)] -#![doc( - html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/", - test(no_crate_inject, attr(deny(warnings))) -)] -#![doc(rust_logo)] +#![doc(test(no_crate_inject, attr(deny(warnings))))] #![feature(core_intrinsics)] #![feature(decl_macro)] #![feature(dropck_eyepatch)] #![feature(maybe_uninit_slice)] #![feature(never_type)] #![feature(rustc_attrs)] -#![feature(rustdoc_internals)] #![feature(unwrap_infallible)] // tidy-alphabetical-end diff --git a/compiler/rustc_ast/src/lib.rs b/compiler/rustc_ast/src/lib.rs index 5fe218776e539..f42b70f43abaf 100644 --- a/compiler/rustc_ast/src/lib.rs +++ b/compiler/rustc_ast/src/lib.rs @@ -5,19 +5,13 @@ //! This API is completely unstable and subject to change. // tidy-alphabetical-start -#![allow(internal_features)] -#![doc( - html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/", - test(attr(deny(warnings))) -)] -#![doc(rust_logo)] +#![doc(test(attr(deny(warnings))))] #![feature(array_windows)] #![feature(associated_type_defaults)] #![feature(box_patterns)] #![feature(if_let_guard)] #![feature(iter_order_by)] #![feature(macro_metavar_expr)] -#![feature(rustdoc_internals)] #![recursion_limit = "256"] // tidy-alphabetical-end diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index dd458ab1ea70f..2a2091a26f0d5 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -31,11 +31,8 @@ //! in the HIR, especially for multiple identifiers. // tidy-alphabetical-start -#![allow(internal_features)] -#![doc(rust_logo)] #![feature(box_patterns)] #![feature(if_let_guard)] -#![feature(rustdoc_internals)] // tidy-alphabetical-end use std::sync::Arc; diff --git a/compiler/rustc_ast_passes/src/lib.rs b/compiler/rustc_ast_passes/src/lib.rs index 6517fdb55bd3f..06795a6be81ef 100644 --- a/compiler/rustc_ast_passes/src/lib.rs +++ b/compiler/rustc_ast_passes/src/lib.rs @@ -3,12 +3,9 @@ //! by `rustc_ast_lowering`. // tidy-alphabetical-start -#![allow(internal_features)] -#![doc(rust_logo)] #![feature(box_patterns)] #![feature(if_let_guard)] #![feature(iter_is_partitioned)] -#![feature(rustdoc_internals)] // tidy-alphabetical-end pub mod ast_validation; diff --git a/compiler/rustc_ast_pretty/src/lib.rs b/compiler/rustc_ast_pretty/src/lib.rs index 1079ccccb03e7..a7d9f89fb3df5 100644 --- a/compiler/rustc_ast_pretty/src/lib.rs +++ b/compiler/rustc_ast_pretty/src/lib.rs @@ -1,9 +1,6 @@ // tidy-alphabetical-start -#![allow(internal_features)] -#![doc(rust_logo)] #![feature(box_patterns)] #![feature(negative_impls)] -#![feature(rustdoc_internals)] // tidy-alphabetical-end mod helpers; diff --git a/compiler/rustc_attr_parsing/src/lib.rs b/compiler/rustc_attr_parsing/src/lib.rs index 2e0c5be587bba..473935abdcd50 100644 --- a/compiler/rustc_attr_parsing/src/lib.rs +++ b/compiler/rustc_attr_parsing/src/lib.rs @@ -77,10 +77,7 @@ //! containing both `C` and `packed` annotations. // tidy-alphabetical-start -#![allow(internal_features)] -#![doc(rust_logo)] #![feature(decl_macro)] -#![feature(rustdoc_internals)] #![recursion_limit = "256"] // tidy-alphabetical-end diff --git a/compiler/rustc_baked_icu_data/src/lib.rs b/compiler/rustc_baked_icu_data/src/lib.rs index ea4c8242c6290..75fe473ef999a 100644 --- a/compiler/rustc_baked_icu_data/src/lib.rs +++ b/compiler/rustc_baked_icu_data/src/lib.rs @@ -21,10 +21,7 @@ // tidy-alphabetical-start #![allow(elided_lifetimes_in_paths)] -#![allow(internal_features)] #![allow(unreachable_pub)] // because this crate is mostly generated code -#![doc(rust_logo)] -#![feature(rustdoc_internals)] // #![warn(unreachable_pub)] // don't use because this crate is mostly generated code // tidy-alphabetical-end diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 4a85859c2f05c..0ac3baaa197f0 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -2,7 +2,6 @@ // tidy-alphabetical-start #![allow(internal_features)] -#![doc(rust_logo)] #![feature(assert_matches)] #![feature(box_patterns)] #![feature(file_buffered)] @@ -10,7 +9,6 @@ #![feature(negative_impls)] #![feature(never_type)] #![feature(rustc_attrs)] -#![feature(rustdoc_internals)] #![feature(stmt_expr_attributes)] #![feature(try_blocks)] // tidy-alphabetical-end diff --git a/compiler/rustc_builtin_macros/src/lib.rs b/compiler/rustc_builtin_macros/src/lib.rs index 57cf62ea61212..221e7c3d553ad 100644 --- a/compiler/rustc_builtin_macros/src/lib.rs +++ b/compiler/rustc_builtin_macros/src/lib.rs @@ -5,8 +5,6 @@ #![allow(internal_features)] #![allow(rustc::diagnostic_outside_of_impl)] #![allow(rustc::untranslatable_diagnostic)] -#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] -#![doc(rust_logo)] #![feature(assert_matches)] #![feature(box_patterns)] #![feature(decl_macro)] @@ -14,7 +12,6 @@ #![feature(iter_order_by)] #![feature(proc_macro_internals)] #![feature(proc_macro_quote)] -#![feature(rustdoc_internals)] #![feature(try_blocks)] #![recursion_limit = "256"] // tidy-alphabetical-end diff --git a/compiler/rustc_codegen_cranelift/src/lib.rs b/compiler/rustc_codegen_cranelift/src/lib.rs index 5c23cd02e0d3a..b63773053d3fd 100644 --- a/compiler/rustc_codegen_cranelift/src/lib.rs +++ b/compiler/rustc_codegen_cranelift/src/lib.rs @@ -1,9 +1,6 @@ // tidy-alphabetical-start #![allow(rustc::diagnostic_outside_of_impl)] #![allow(rustc::untranslatable_diagnostic)] -#![cfg_attr(doc, allow(internal_features))] -#![cfg_attr(doc, doc(rust_logo))] -#![cfg_attr(doc, feature(rustdoc_internals))] // Note: please avoid adding other feature gates where possible #![feature(rustc_private)] // Only used to define intrinsics in `compiler_builtins.rs`. diff --git a/compiler/rustc_codegen_gcc/src/lib.rs b/compiler/rustc_codegen_gcc/src/lib.rs index 9f5b03c02a092..c3fa570fb5ccc 100644 --- a/compiler/rustc_codegen_gcc/src/lib.rs +++ b/compiler/rustc_codegen_gcc/src/lib.rs @@ -13,9 +13,6 @@ * TODO(antoyo): remove the patches. */ -#![allow(internal_features)] -#![doc(rust_logo)] -#![feature(rustdoc_internals)] #![feature(rustc_private)] #![recursion_limit = "256"] #![warn(rust_2018_idioms)] diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index c8ad8f0c10d0d..7e837343bf1d7 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -5,9 +5,6 @@ //! This API is completely unstable and subject to change. // tidy-alphabetical-start -#![allow(internal_features)] -#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] -#![doc(rust_logo)] #![feature(assert_matches)] #![feature(extern_types)] #![feature(file_buffered)] @@ -15,7 +12,6 @@ #![feature(impl_trait_in_assoc_type)] #![feature(iter_intersperse)] #![feature(macro_derive)] -#![feature(rustdoc_internals)] #![feature(slice_as_array)] #![feature(trim_prefix_suffix)] #![feature(try_blocks)] diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs index baba8f9ca3e8b..db8706d02ae1f 100644 --- a/compiler/rustc_codegen_ssa/src/lib.rs +++ b/compiler/rustc_codegen_ssa/src/lib.rs @@ -1,15 +1,11 @@ // tidy-alphabetical-start -#![allow(internal_features)] #![allow(rustc::diagnostic_outside_of_impl)] #![allow(rustc::untranslatable_diagnostic)] -#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] -#![doc(rust_logo)] #![feature(assert_matches)] #![feature(box_patterns)] #![feature(file_buffered)] #![feature(if_let_guard)] #![feature(negative_impls)] -#![feature(rustdoc_internals)] #![feature(string_from_utf8_lossy_owned)] #![feature(trait_alias)] #![feature(try_blocks)] diff --git a/compiler/rustc_const_eval/src/lib.rs b/compiler/rustc_const_eval/src/lib.rs index 9c0ec4e51a0c3..2fce4b8c0566e 100644 --- a/compiler/rustc_const_eval/src/lib.rs +++ b/compiler/rustc_const_eval/src/lib.rs @@ -1,14 +1,11 @@ // tidy-alphabetical-start -#![allow(internal_features)] #![allow(rustc::diagnostic_outside_of_impl)] -#![doc(rust_logo)] #![feature(array_try_map)] #![feature(assert_matches)] #![feature(box_patterns)] #![feature(decl_macro)] #![feature(if_let_guard)] #![feature(never_type)] -#![feature(rustdoc_internals)] #![feature(slice_ptr_get)] #![feature(trait_alias)] #![feature(try_blocks)] diff --git a/compiler/rustc_data_structures/src/lib.rs b/compiler/rustc_data_structures/src/lib.rs index 132f04b05100f..b4031973fbc25 100644 --- a/compiler/rustc_data_structures/src/lib.rs +++ b/compiler/rustc_data_structures/src/lib.rs @@ -11,8 +11,6 @@ #![allow(rustc::default_hash_types)] #![allow(rustc::potential_query_instability)] #![deny(unsafe_op_in_unsafe_fn)] -#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] -#![doc(rust_logo)] #![feature(allocator_api)] #![feature(array_windows)] #![feature(ascii_char)] @@ -30,7 +28,6 @@ #![feature(never_type)] #![feature(ptr_alignment_type)] #![feature(rustc_attrs)] -#![feature(rustdoc_internals)] #![feature(sized_hierarchy)] #![feature(test)] #![feature(thread_id_value)] diff --git a/compiler/rustc_driver/src/lib.rs b/compiler/rustc_driver/src/lib.rs index a03834c519d59..0cd0b51b6ad49 100644 --- a/compiler/rustc_driver/src/lib.rs +++ b/compiler/rustc_driver/src/lib.rs @@ -1,10 +1,4 @@ // This crate is intentionally empty and a re-export of `rustc_driver_impl` to allow the code in // `rustc_driver_impl` to be compiled in parallel with other crates. -// tidy-alphabetical-start -#![allow(internal_features)] -#![doc(rust_logo)] -#![feature(rustdoc_internals)] -// tidy-alphabetical-end - pub use rustc_driver_impl::*; diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index 8353aac74fd91..9a3d7cc506cf7 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -5,14 +5,10 @@ //! This API is completely unstable and subject to change. // tidy-alphabetical-start -#![allow(internal_features)] #![allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable -#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] -#![doc(rust_logo)] #![feature(decl_macro)] #![feature(panic_backtrace_config)] #![feature(panic_update_hook)] -#![feature(rustdoc_internals)] #![feature(trim_prefix_suffix)] #![feature(try_blocks)] // tidy-alphabetical-end diff --git a/compiler/rustc_error_codes/src/lib.rs b/compiler/rustc_error_codes/src/lib.rs index 0aff1c06e0a8c..f63f89748884f 100644 --- a/compiler/rustc_error_codes/src/lib.rs +++ b/compiler/rustc_error_codes/src/lib.rs @@ -2,10 +2,7 @@ //! their maintenance easier. // tidy-alphabetical-start -#![allow(internal_features)] #![deny(rustdoc::invalid_codeblock_attributes)] -#![doc(rust_logo)] -#![feature(rustdoc_internals)] // tidy-alphabetical-end // This higher-order macro defines the error codes that are in use. It is used diff --git a/compiler/rustc_error_messages/src/lib.rs b/compiler/rustc_error_messages/src/lib.rs index 7b7843f6cf319..64dcf3c1f72d8 100644 --- a/compiler/rustc_error_messages/src/lib.rs +++ b/compiler/rustc_error_messages/src/lib.rs @@ -1,8 +1,6 @@ // tidy-alphabetical-start #![allow(internal_features)] -#![doc(rust_logo)] #![feature(rustc_attrs)] -#![feature(rustdoc_internals)] // tidy-alphabetical-end use std::borrow::Cow; diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 17cd466f96b87..2f88e587ae9f7 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -7,8 +7,6 @@ #![allow(rustc::diagnostic_outside_of_impl)] #![allow(rustc::direct_use_of_rustc_type_ir)] #![allow(rustc::untranslatable_diagnostic)] -#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] -#![doc(rust_logo)] #![feature(array_windows)] #![feature(assert_matches)] #![feature(associated_type_defaults)] @@ -18,7 +16,6 @@ #![feature(negative_impls)] #![feature(never_type)] #![feature(rustc_attrs)] -#![feature(rustdoc_internals)] #![feature(try_blocks)] #![feature(yeet_expr)] // tidy-alphabetical-end diff --git a/compiler/rustc_expand/src/lib.rs b/compiler/rustc_expand/src/lib.rs index b54dabbb8e26f..e76fca92c5861 100644 --- a/compiler/rustc_expand/src/lib.rs +++ b/compiler/rustc_expand/src/lib.rs @@ -1,14 +1,12 @@ // tidy-alphabetical-start #![allow(internal_features)] #![allow(rustc::diagnostic_outside_of_impl)] -#![doc(rust_logo)] #![feature(array_windows)] #![feature(associated_type_defaults)] #![feature(if_let_guard)] #![feature(macro_metavar_expr)] #![feature(proc_macro_diagnostic)] #![feature(proc_macro_internals)] -#![feature(rustdoc_internals)] #![feature(try_blocks)] #![feature(yeet_expr)] // tidy-alphabetical-end diff --git a/compiler/rustc_feature/src/lib.rs b/compiler/rustc_feature/src/lib.rs index dbc0daa3d8383..855c78293acce 100644 --- a/compiler/rustc_feature/src/lib.rs +++ b/compiler/rustc_feature/src/lib.rs @@ -11,12 +11,6 @@ //! even if it is stabilized or removed, *do not remove it*. Instead, move the //! symbol to the `accepted` or `removed` modules respectively. -// tidy-alphabetical-start -#![allow(internal_features)] -#![doc(rust_logo)] -#![feature(rustdoc_internals)] -// tidy-alphabetical-end - mod accepted; mod builtin_attrs; mod removed; diff --git a/compiler/rustc_fluent_macro/src/lib.rs b/compiler/rustc_fluent_macro/src/lib.rs index 6f85e05f29aa4..c2f49de31c237 100644 --- a/compiler/rustc_fluent_macro/src/lib.rs +++ b/compiler/rustc_fluent_macro/src/lib.rs @@ -1,10 +1,6 @@ // tidy-alphabetical-start -#![allow(internal_features)] #![allow(rustc::default_hash_types)] -#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] -#![doc(rust_logo)] #![feature(proc_macro_diagnostic)] -#![feature(rustdoc_internals)] #![feature(track_path)] // tidy-alphabetical-end diff --git a/compiler/rustc_graphviz/src/lib.rs b/compiler/rustc_graphviz/src/lib.rs index c8f8fd5be0237..56adee70465dd 100644 --- a/compiler/rustc_graphviz/src/lib.rs +++ b/compiler/rustc_graphviz/src/lib.rs @@ -270,13 +270,7 @@ //! * [DOT language](https://www.graphviz.org/doc/info/lang.html) // tidy-alphabetical-start -#![allow(internal_features)] -#![doc( - html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/", - test(attr(allow(unused_variables), deny(warnings))) -)] -#![doc(rust_logo)] -#![feature(rustdoc_internals)] +#![doc(test(attr(allow(unused_variables), deny(warnings))))] // tidy-alphabetical-end use std::borrow::Cow; diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index 56c0f4e7cee48..eeb783b300c7e 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs @@ -56,18 +56,14 @@ This API is completely unstable and subject to change. */ // tidy-alphabetical-start -#![allow(internal_features)] #![allow(rustc::diagnostic_outside_of_impl)] #![allow(rustc::untranslatable_diagnostic)] #![cfg_attr(bootstrap, feature(debug_closure_helpers))] -#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] -#![doc(rust_logo)] #![feature(assert_matches)] #![feature(gen_blocks)] #![feature(if_let_guard)] #![feature(iter_intersperse)] #![feature(never_type)] -#![feature(rustdoc_internals)] #![feature(slice_partition_dedup)] #![feature(try_blocks)] #![feature(unwrap_infallible)] diff --git a/compiler/rustc_incremental/src/lib.rs b/compiler/rustc_incremental/src/lib.rs index 299ee4876389c..e750810c01193 100644 --- a/compiler/rustc_incremental/src/lib.rs +++ b/compiler/rustc_incremental/src/lib.rs @@ -1,12 +1,8 @@ //! Support for serializing the dep-graph and reloading it. // tidy-alphabetical-start -#![allow(internal_features)] #![deny(missing_docs)] -#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] -#![doc(rust_logo)] #![feature(file_buffered)] -#![feature(rustdoc_internals)] // tidy-alphabetical-end mod assert_dep_graph; diff --git a/compiler/rustc_index/src/lib.rs b/compiler/rustc_index/src/lib.rs index 42d2849384688..7fb9deaa1697b 100644 --- a/compiler/rustc_index/src/lib.rs +++ b/compiler/rustc_index/src/lib.rs @@ -1,6 +1,5 @@ // tidy-alphabetical-start #![cfg_attr(all(feature = "nightly", test), feature(stmt_expr_attributes))] -#![cfg_attr(feature = "nightly", allow(internal_features))] #![cfg_attr(feature = "nightly", feature(extend_one, step_trait, test))] #![cfg_attr(feature = "nightly", feature(new_range_api))] // tidy-alphabetical-end diff --git a/compiler/rustc_infer/src/lib.rs b/compiler/rustc_infer/src/lib.rs index e562c58331340..05ea0f813818d 100644 --- a/compiler/rustc_infer/src/lib.rs +++ b/compiler/rustc_infer/src/lib.rs @@ -13,13 +13,9 @@ //! This API is completely unstable and subject to change. // tidy-alphabetical-start -#![allow(internal_features)] #![allow(rustc::direct_use_of_rustc_type_ir)] -#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] -#![doc(rust_logo)] #![feature(assert_matches)] #![feature(extend_one)] -#![feature(rustdoc_internals)] #![recursion_limit = "512"] // For rustdoc // tidy-alphabetical-end diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index faaeb7706e399..8a83434e10c15 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -21,15 +21,12 @@ // tidy-alphabetical-start #![allow(internal_features)] -#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] -#![doc(rust_logo)] #![feature(array_windows)] #![feature(assert_matches)] #![feature(box_patterns)] #![feature(if_let_guard)] #![feature(iter_order_by)] #![feature(rustc_attrs)] -#![feature(rustdoc_internals)] #![feature(try_blocks)] // tidy-alphabetical-end diff --git a/compiler/rustc_llvm/src/lib.rs b/compiler/rustc_llvm/src/lib.rs index 14e94121d1cb8..a565e1feeb5e5 100644 --- a/compiler/rustc_llvm/src/lib.rs +++ b/compiler/rustc_llvm/src/lib.rs @@ -1,9 +1,5 @@ // tidy-alphabetical-start -#![allow(internal_features)] -#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] -#![doc(rust_logo)] #![feature(extern_types)] -#![feature(rustdoc_internals)] // tidy-alphabetical-end use std::cell::RefCell; diff --git a/compiler/rustc_metadata/src/lib.rs b/compiler/rustc_metadata/src/lib.rs index 3e50689b5accb..01060eb7e32c1 100644 --- a/compiler/rustc_metadata/src/lib.rs +++ b/compiler/rustc_metadata/src/lib.rs @@ -1,7 +1,5 @@ // tidy-alphabetical-start #![allow(internal_features)] -#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] -#![doc(rust_logo)] #![feature(decl_macro)] #![feature(error_iter)] #![feature(file_buffered)] @@ -11,7 +9,6 @@ #![feature(min_specialization)] #![feature(never_type)] #![feature(proc_macro_internals)] -#![feature(rustdoc_internals)] #![feature(trusted_len)] // tidy-alphabetical-end diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs index 754a258eef93d..72786931ff8a0 100644 --- a/compiler/rustc_middle/src/lib.rs +++ b/compiler/rustc_middle/src/lib.rs @@ -29,8 +29,6 @@ #![allow(rustc::diagnostic_outside_of_impl)] #![allow(rustc::direct_use_of_rustc_type_ir)] #![allow(rustc::untranslatable_diagnostic)] -#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] -#![doc(rust_logo)] #![feature(allocator_api)] #![feature(array_windows)] #![feature(assert_matches)] @@ -52,7 +50,6 @@ #![feature(never_type)] #![feature(ptr_alignment_type)] #![feature(rustc_attrs)] -#![feature(rustdoc_internals)] #![feature(sized_hierarchy)] #![feature(try_blocks)] #![feature(try_trait_v2)] diff --git a/compiler/rustc_parse_format/src/lib.rs b/compiler/rustc_parse_format/src/lib.rs index 5cda0b813d233..201722b26edbe 100644 --- a/compiler/rustc_parse_format/src/lib.rs +++ b/compiler/rustc_parse_format/src/lib.rs @@ -8,11 +8,7 @@ // We want to be able to build this crate with a stable compiler, // so no `#![feature]` attributes should be added. #![deny(unstable_features)] -#![doc( - html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/", - html_playground_url = "https://play.rust-lang.org/", - test(attr(deny(warnings))) -)] +#![doc(test(attr(deny(warnings))))] // tidy-alphabetical-end use std::ops::Range; diff --git a/compiler/rustc_passes/src/lib.rs b/compiler/rustc_passes/src/lib.rs index c98e971185795..149714f943a73 100644 --- a/compiler/rustc_passes/src/lib.rs +++ b/compiler/rustc_passes/src/lib.rs @@ -5,12 +5,8 @@ //! This API is completely unstable and subject to change. // tidy-alphabetical-start -#![allow(internal_features)] -#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] -#![doc(rust_logo)] #![feature(if_let_guard)] #![feature(map_try_insert)] -#![feature(rustdoc_internals)] // tidy-alphabetical-end use rustc_middle::util::Providers; diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index bfa0f01d1192e..8656ec6e39aed 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -1,9 +1,5 @@ // tidy-alphabetical-start -#![allow(internal_features)] -#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] -#![doc(rust_logo)] #![feature(associated_type_defaults)] -#![feature(rustdoc_internals)] #![feature(try_blocks)] // tidy-alphabetical-end diff --git a/compiler/rustc_public/src/lib.rs b/compiler/rustc_public/src/lib.rs index 958b3b2647889..14f246cebbf6e 100644 --- a/compiler/rustc_public/src/lib.rs +++ b/compiler/rustc_public/src/lib.rs @@ -7,10 +7,7 @@ //! This API is still completely unstable and subject to change. #![allow(rustc::usage_of_ty_tykind)] -#![doc( - html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/", - test(attr(allow(unused_variables), deny(warnings))) -)] +#![doc(test(attr(allow(unused_variables), deny(warnings))))] #![feature(sized_hierarchy)] //! //! This crate shall contain all type definitions and APIs that we expect third-party tools to invoke to diff --git a/compiler/rustc_public_bridge/src/lib.rs b/compiler/rustc_public_bridge/src/lib.rs index d0b417c550dc9..a74b460a912ce 100644 --- a/compiler/rustc_public_bridge/src/lib.rs +++ b/compiler/rustc_public_bridge/src/lib.rs @@ -12,14 +12,8 @@ //! This API is still completely unstable and subject to change. // tidy-alphabetical-start -#![allow(internal_features)] #![allow(rustc::usage_of_ty_tykind)] -#![doc( - html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/", - test(attr(allow(unused_variables), deny(warnings))) -)] -#![doc(rust_logo)] -#![feature(rustdoc_internals)] +#![doc(test(attr(allow(unused_variables), deny(warnings))))] #![feature(sized_hierarchy)] #![feature(trait_alias)] // tidy-alphabetical-end diff --git a/compiler/rustc_query_impl/src/lib.rs b/compiler/rustc_query_impl/src/lib.rs index e499e08c82b9a..6904af771f0cc 100644 --- a/compiler/rustc_query_impl/src/lib.rs +++ b/compiler/rustc_query_impl/src/lib.rs @@ -2,11 +2,8 @@ // tidy-alphabetical-start #![allow(internal_features)] -#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] -#![doc(rust_logo)] #![feature(min_specialization)] #![feature(rustc_attrs)] -#![feature(rustdoc_internals)] // tidy-alphabetical-end use rustc_data_structures::stable_hasher::HashStable; diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 9f68b93520d29..7ce70ee9af8d4 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -10,8 +10,6 @@ #![allow(internal_features)] #![allow(rustc::diagnostic_outside_of_impl)] #![allow(rustc::untranslatable_diagnostic)] -#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] -#![doc(rust_logo)] #![feature(arbitrary_self_types)] #![feature(assert_matches)] #![feature(box_patterns)] @@ -21,7 +19,6 @@ #![feature(iter_intersperse)] #![feature(ptr_as_ref_unchecked)] #![feature(rustc_attrs)] -#![feature(rustdoc_internals)] #![feature(trim_prefix_suffix)] #![recursion_limit = "256"] // tidy-alphabetical-end diff --git a/compiler/rustc_serialize/src/lib.rs b/compiler/rustc_serialize/src/lib.rs index 806d880b19c5a..88ecb1ffe1f1c 100644 --- a/compiler/rustc_serialize/src/lib.rs +++ b/compiler/rustc_serialize/src/lib.rs @@ -4,16 +4,10 @@ #![allow(internal_features)] #![allow(rustc::internal)] #![cfg_attr(test, feature(test))] -#![doc( - html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/", - html_playground_url = "https://play.rust-lang.org/", - test(attr(allow(unused_variables), deny(warnings))) -)] -#![doc(rust_logo)] +#![doc(test(attr(allow(unused_variables), deny(warnings))))] #![feature(core_intrinsics)] #![feature(min_specialization)] #![feature(never_type)] -#![feature(rustdoc_internals)] #![feature(sized_hierarchy)] // tidy-alphabetical-end diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs index ededbea57e966..afd4564f1b6fd 100644 --- a/compiler/rustc_span/src/lib.rs +++ b/compiler/rustc_span/src/lib.rs @@ -18,8 +18,6 @@ // tidy-alphabetical-start #![allow(internal_features)] #![cfg_attr(target_arch = "loongarch64", feature(stdarch_loongarch))] -#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] -#![doc(rust_logo)] #![feature(array_windows)] #![feature(cfg_select)] #![feature(core_io_borrowed_buf)] @@ -28,7 +26,6 @@ #![feature(negative_impls)] #![feature(read_buf)] #![feature(rustc_attrs)] -#![feature(rustdoc_internals)] // tidy-alphabetical-end // The code produced by the `Encodable`/`Decodable` derive macros refer to diff --git a/compiler/rustc_symbol_mangling/src/lib.rs b/compiler/rustc_symbol_mangling/src/lib.rs index b5716b51a91c4..71dc81f0139e7 100644 --- a/compiler/rustc_symbol_mangling/src/lib.rs +++ b/compiler/rustc_symbol_mangling/src/lib.rs @@ -88,11 +88,7 @@ //! DefPaths which are much more robust in the face of changes to the code base. // tidy-alphabetical-start -#![allow(internal_features)] -#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] -#![doc(rust_logo)] #![feature(assert_matches)] -#![feature(rustdoc_internals)] // tidy-alphabetical-end use rustc_hir::def::DefKind; diff --git a/compiler/rustc_target/src/lib.rs b/compiler/rustc_target/src/lib.rs index b38ce20e60957..2d83caa07676a 100644 --- a/compiler/rustc_target/src/lib.rs +++ b/compiler/rustc_target/src/lib.rs @@ -8,12 +8,8 @@ //! LLVM. // tidy-alphabetical-start -#![allow(internal_features)] #![cfg_attr(bootstrap, feature(debug_closure_helpers))] -#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] -#![doc(rust_logo)] #![feature(iter_intersperse)] -#![feature(rustdoc_internals)] // tidy-alphabetical-end use std::path::{Path, PathBuf}; diff --git a/compiler/rustc_trait_selection/src/lib.rs b/compiler/rustc_trait_selection/src/lib.rs index fc0cf8f140a70..c5dfaa2a60d87 100644 --- a/compiler/rustc_trait_selection/src/lib.rs +++ b/compiler/rustc_trait_selection/src/lib.rs @@ -11,11 +11,8 @@ //! This API is completely unstable and subject to change. // tidy-alphabetical-start -#![allow(internal_features)] #![allow(rustc::diagnostic_outside_of_impl)] #![allow(rustc::untranslatable_diagnostic)] -#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] -#![doc(rust_logo)] #![feature(assert_matches)] #![feature(associated_type_defaults)] #![feature(box_patterns)] @@ -24,7 +21,6 @@ #![feature(iter_intersperse)] #![feature(iterator_try_reduce)] #![feature(never_type)] -#![feature(rustdoc_internals)] #![feature(try_blocks)] #![feature(unwrap_infallible)] #![feature(yeet_expr)] diff --git a/compiler/rustc_ty_utils/src/lib.rs b/compiler/rustc_ty_utils/src/lib.rs index 929cc074bdac7..d8b50b2d2e42f 100644 --- a/compiler/rustc_ty_utils/src/lib.rs +++ b/compiler/rustc_ty_utils/src/lib.rs @@ -5,16 +5,12 @@ //! This API is completely unstable and subject to change. // tidy-alphabetical-start -#![allow(internal_features)] -#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] -#![doc(rust_logo)] #![feature(assert_matches)] #![feature(associated_type_defaults)] #![feature(box_patterns)] #![feature(if_let_guard)] #![feature(iterator_try_collect)] #![feature(never_type)] -#![feature(rustdoc_internals)] // tidy-alphabetical-end use rustc_middle::query::Providers; diff --git a/src/bootstrap/src/bin/rustdoc.rs b/src/bootstrap/src/bin/rustdoc.rs index efb51bdce1e0e..784041985b720 100644 --- a/src/bootstrap/src/bin/rustdoc.rs +++ b/src/bootstrap/src/bin/rustdoc.rs @@ -60,6 +60,21 @@ fn main() { cmd.arg("--cfg=bootstrap"); } + if let Some(crate_name) = parse_value_from_args(&args, "--crate-name") { + // Add rust logo and set html root for all rustc crates. + if crate_name.starts_with("rustc_") { + cmd.arg("-Ainternal_features") + .arg("-Zcrate-attr=doc(rust_logo)") + .arg("-Zcrate-attr=doc(html_root_url = \"https://doc.rust-lang.org/nightly/nightly-rustc/\")"); + + // rustc_proc_macro is another build of library/proc_macro which already enables this + // feature + if crate_name != "rustc_proc_macro" { + cmd.arg("-Zcrate-attr=feature(rustdoc_internals)"); + } + } + } + maybe_dump(format!("stage{}-rustdoc", stage + 1), &cmd); if verbose > 1 { From 222480dcb94c5a27fb10768aae7ccc99da0d805c Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 5 Nov 2025 11:13:23 +0000 Subject: [PATCH 15/17] Allow internal_features lint in doc tests Rustdoc forwards -Zcrate-attr=feature(rustdoc_internals) to doc tests, but deny(warnings) overrides the -Ainternal_features. --- compiler/rustc_arena/src/lib.rs | 2 +- compiler/rustc_ast/src/lib.rs | 2 +- compiler/rustc_graphviz/src/lib.rs | 2 +- compiler/rustc_parse_format/src/lib.rs | 2 +- compiler/rustc_public/src/lib.rs | 2 +- compiler/rustc_public_bridge/src/lib.rs | 2 +- compiler/rustc_serialize/src/lib.rs | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_arena/src/lib.rs b/compiler/rustc_arena/src/lib.rs index 40d0d3735de01..a821d9e7fa23e 100644 --- a/compiler/rustc_arena/src/lib.rs +++ b/compiler/rustc_arena/src/lib.rs @@ -12,7 +12,7 @@ #![allow(internal_features)] #![cfg_attr(test, feature(test))] #![deny(unsafe_op_in_unsafe_fn)] -#![doc(test(no_crate_inject, attr(deny(warnings))))] +#![doc(test(no_crate_inject, attr(deny(warnings), allow(internal_features))))] #![feature(core_intrinsics)] #![feature(decl_macro)] #![feature(dropck_eyepatch)] diff --git a/compiler/rustc_ast/src/lib.rs b/compiler/rustc_ast/src/lib.rs index f42b70f43abaf..e19dccbce02ae 100644 --- a/compiler/rustc_ast/src/lib.rs +++ b/compiler/rustc_ast/src/lib.rs @@ -5,7 +5,7 @@ //! This API is completely unstable and subject to change. // tidy-alphabetical-start -#![doc(test(attr(deny(warnings))))] +#![doc(test(attr(deny(warnings), allow(internal_features))))] #![feature(array_windows)] #![feature(associated_type_defaults)] #![feature(box_patterns)] diff --git a/compiler/rustc_graphviz/src/lib.rs b/compiler/rustc_graphviz/src/lib.rs index 56adee70465dd..9f75578aa636c 100644 --- a/compiler/rustc_graphviz/src/lib.rs +++ b/compiler/rustc_graphviz/src/lib.rs @@ -270,7 +270,7 @@ //! * [DOT language](https://www.graphviz.org/doc/info/lang.html) // tidy-alphabetical-start -#![doc(test(attr(allow(unused_variables), deny(warnings))))] +#![doc(test(attr(allow(unused_variables), deny(warnings), allow(internal_features))))] // tidy-alphabetical-end use std::borrow::Cow; diff --git a/compiler/rustc_parse_format/src/lib.rs b/compiler/rustc_parse_format/src/lib.rs index 201722b26edbe..86326fc6536cd 100644 --- a/compiler/rustc_parse_format/src/lib.rs +++ b/compiler/rustc_parse_format/src/lib.rs @@ -8,7 +8,7 @@ // We want to be able to build this crate with a stable compiler, // so no `#![feature]` attributes should be added. #![deny(unstable_features)] -#![doc(test(attr(deny(warnings))))] +#![doc(test(attr(deny(warnings), allow(internal_features))))] // tidy-alphabetical-end use std::ops::Range; diff --git a/compiler/rustc_public/src/lib.rs b/compiler/rustc_public/src/lib.rs index 14f246cebbf6e..66fa4607edcc1 100644 --- a/compiler/rustc_public/src/lib.rs +++ b/compiler/rustc_public/src/lib.rs @@ -7,7 +7,7 @@ //! This API is still completely unstable and subject to change. #![allow(rustc::usage_of_ty_tykind)] -#![doc(test(attr(allow(unused_variables), deny(warnings))))] +#![doc(test(attr(allow(unused_variables), deny(warnings), allow(internal_features))))] #![feature(sized_hierarchy)] //! //! This crate shall contain all type definitions and APIs that we expect third-party tools to invoke to diff --git a/compiler/rustc_public_bridge/src/lib.rs b/compiler/rustc_public_bridge/src/lib.rs index a74b460a912ce..025ec0e7a8c85 100644 --- a/compiler/rustc_public_bridge/src/lib.rs +++ b/compiler/rustc_public_bridge/src/lib.rs @@ -13,7 +13,7 @@ // tidy-alphabetical-start #![allow(rustc::usage_of_ty_tykind)] -#![doc(test(attr(allow(unused_variables), deny(warnings))))] +#![doc(test(attr(allow(unused_variables), deny(warnings), allow(internal_features))))] #![feature(sized_hierarchy)] #![feature(trait_alias)] // tidy-alphabetical-end diff --git a/compiler/rustc_serialize/src/lib.rs b/compiler/rustc_serialize/src/lib.rs index 88ecb1ffe1f1c..842068a4fc046 100644 --- a/compiler/rustc_serialize/src/lib.rs +++ b/compiler/rustc_serialize/src/lib.rs @@ -4,7 +4,7 @@ #![allow(internal_features)] #![allow(rustc::internal)] #![cfg_attr(test, feature(test))] -#![doc(test(attr(allow(unused_variables), deny(warnings))))] +#![doc(test(attr(allow(unused_variables), deny(warnings), allow(internal_features))))] #![feature(core_intrinsics)] #![feature(min_specialization)] #![feature(never_type)] From eaf979e8dd98f006767632f0910cd2fdecf8541d Mon Sep 17 00:00:00 2001 From: yukang Date: Wed, 5 Nov 2025 20:24:20 +0800 Subject: [PATCH 16/17] Fix ICE from lit_to_mir_constant caused by type error --- .../src/error_reporting/traits/mod.rs | 41 ++++++++++--------- .../ice-from-type-error-issue-148515.rs | 18 ++++++++ .../ice-from-type-error-issue-148515.stderr | 24 +++++++++++ 3 files changed, 63 insertions(+), 20 deletions(-) create mode 100644 tests/ui/enum-discriminant/ice-from-type-error-issue-148515.rs create mode 100644 tests/ui/enum-discriminant/ice-from-type-error-issue-148515.stderr diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs index b98547c42789d..1825719a30774 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs @@ -250,29 +250,30 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { } let mut reported = None; - for from_expansion in [false, true] { for (error, suppressed) in iter::zip(&errors, &is_suppressed) { - if !suppressed - && error.obligation.cause.span.from_expansion() == from_expansion - && !error.references_error() - { - let guar = self.report_fulfillment_error(error); - self.infcx.set_tainted_by_errors(guar); - reported = Some(guar); - // We want to ignore desugarings here: spans are equivalent even - // if one is the result of a desugaring and the other is not. - let mut span = error.obligation.cause.span; - let expn_data = span.ctxt().outer_expn_data(); - if let ExpnKind::Desugaring(_) = expn_data.kind { - span = expn_data.call_site; + if !suppressed && error.obligation.cause.span.from_expansion() == from_expansion { + if !error.references_error() { + let guar = self.report_fulfillment_error(error); + self.infcx.set_tainted_by_errors(guar); + reported = Some(guar); + // We want to ignore desugarings here: spans are equivalent even + // if one is the result of a desugaring and the other is not. + let mut span = error.obligation.cause.span; + let expn_data = span.ctxt().outer_expn_data(); + if let ExpnKind::Desugaring(_) = expn_data.kind { + span = expn_data.call_site; + } + self.reported_trait_errors + .borrow_mut() + .entry(span) + .or_insert_with(|| (vec![], guar)) + .0 + .push(error.obligation.as_goal()); + } + if let Some(guar) = self.dcx().has_errors() { + self.infcx.set_tainted_by_errors(guar); } - self.reported_trait_errors - .borrow_mut() - .entry(span) - .or_insert_with(|| (vec![], guar)) - .0 - .push(error.obligation.as_goal()); } } } diff --git a/tests/ui/enum-discriminant/ice-from-type-error-issue-148515.rs b/tests/ui/enum-discriminant/ice-from-type-error-issue-148515.rs new file mode 100644 index 0000000000000..e9ba69307c404 --- /dev/null +++ b/tests/ui/enum-discriminant/ice-from-type-error-issue-148515.rs @@ -0,0 +1,18 @@ +//@ edition: 2024 + +enum Test { + Value = -5 >> 1_usize, +} + +fn test1(x: impl Iterator) { + //~^ ERROR cannot find type `Foo` in this scope + assert_eq!(Test::Value as u8, -3); +} + +fn test2(_: impl Iterator) { + //~^ ERROR cannot find type `Foo` in this scope + 0u8 == -3; + //~^ ERROR cannot apply unary operator `-` to type `u8` +} + +fn main() {} diff --git a/tests/ui/enum-discriminant/ice-from-type-error-issue-148515.stderr b/tests/ui/enum-discriminant/ice-from-type-error-issue-148515.stderr new file mode 100644 index 0000000000000..d9f40c7c0f738 --- /dev/null +++ b/tests/ui/enum-discriminant/ice-from-type-error-issue-148515.stderr @@ -0,0 +1,24 @@ +error[E0412]: cannot find type `Foo` in this scope + --> $DIR/ice-from-type-error-issue-148515.rs:7:34 + | +LL | fn test1(x: impl Iterator) { + | ^^^ not found in this scope + +error[E0412]: cannot find type `Foo` in this scope + --> $DIR/ice-from-type-error-issue-148515.rs:12:34 + | +LL | fn test2(_: impl Iterator) { + | ^^^ not found in this scope + +error[E0600]: cannot apply unary operator `-` to type `u8` + --> $DIR/ice-from-type-error-issue-148515.rs:14:12 + | +LL | 0u8 == -3; + | ^^ cannot apply unary operator `-` + | + = note: unsigned values cannot be negated + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0412, E0600. +For more information about an error, try `rustc --explain E0412`. From 32c93ccc89394a317ad272864d3970420bd4dc81 Mon Sep 17 00:00:00 2001 From: Waffle Lapkin Date: Wed, 5 Nov 2025 17:01:21 +0100 Subject: [PATCH 17/17] Merge `Vec::push{,_mut}_within_capacity` --- library/alloc/src/vec/mod.rs | 50 ++++++++++++------------------------ 1 file changed, 16 insertions(+), 34 deletions(-) diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index 45d6c28e186e4..dc610d7b46741 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -2564,8 +2564,8 @@ impl Vec { let _ = self.push_mut(value); } - /// Appends an element if there is sufficient spare capacity, otherwise an error is returned - /// with the element. + /// Appends an element and returns a reference to it if there is sufficient spare capacity, + /// otherwise an error is returned with the element. /// /// Unlike [`push`] this method will not reallocate when there's insufficient capacity. /// The caller should use [`reserve`] or [`try_reserve`] to ensure that there is enough capacity. @@ -2601,8 +2601,20 @@ impl Vec { /// Takes *O*(1) time. #[inline] #[unstable(feature = "vec_push_within_capacity", issue = "100486")] - pub fn push_within_capacity(&mut self, value: T) -> Result<(), T> { - self.push_mut_within_capacity(value).map(|_| ()) + // #[unstable(feature = "push_mut", issue = "135974")] + pub fn push_within_capacity(&mut self, value: T) -> Result<&mut T, T> { + if self.len == self.buf.capacity() { + return Err(value); + } + + unsafe { + let end = self.as_mut_ptr().add(self.len); + ptr::write(end, value); + self.len += 1; + + // SAFETY: We just wrote a value to the pointer that will live the lifetime of the reference. + Ok(&mut *end) + } } /// Appends an element to the back of a collection, returning a reference to it. @@ -2654,36 +2666,6 @@ impl Vec { } } - /// Appends an element and returns a reference to it if there is sufficient spare capacity, - /// otherwise an error is returned with the element. - /// - /// Unlike [`push_mut`] this method will not reallocate when there's insufficient capacity. - /// The caller should use [`reserve`] or [`try_reserve`] to ensure that there is enough capacity. - /// - /// [`push_mut`]: Vec::push_mut - /// [`reserve`]: Vec::reserve - /// [`try_reserve`]: Vec::try_reserve - /// - /// # Time complexity - /// - /// Takes *O*(1) time. - #[unstable(feature = "push_mut", issue = "135974")] - // #[unstable(feature = "vec_push_within_capacity", issue = "100486")] - #[inline] - #[must_use = "if you don't need a reference to the value, use `Vec::push_within_capacity` instead"] - pub fn push_mut_within_capacity(&mut self, value: T) -> Result<&mut T, T> { - if self.len == self.buf.capacity() { - return Err(value); - } - unsafe { - let end = self.as_mut_ptr().add(self.len); - ptr::write(end, value); - self.len += 1; - // SAFETY: We just wrote a value to the pointer that will live the lifetime of the reference. - Ok(&mut *end) - } - } - /// Removes the last element from a vector and returns it, or [`None`] if it /// is empty. ///