From 8d7ec96c00994e3e4da652201792ae2040c979c1 Mon Sep 17 00:00:00 2001 From: Nathaniel McCallum Date: Fri, 12 Sep 2025 18:35:21 -0400 Subject: [PATCH 1/6] add `[const] PartialEq` bound to `PartialOrd` This change is included for discussion purposes. The PartialOrd bound on PartialEq is not strictly necessary. It is, rather, logical: anything which is orderable should by definition have equality. Is the same true for constness? Should every type which is const orderable also have const equality? --- library/core/src/cmp.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/library/core/src/cmp.rs b/library/core/src/cmp.rs index 95896ab144187..7f369d19c3d12 100644 --- a/library/core/src/cmp.rs +++ b/library/core/src/cmp.rs @@ -1351,7 +1351,9 @@ pub macro Ord($item:item) { #[rustc_diagnostic_item = "PartialOrd"] #[allow(multiple_supertrait_upcastable)] // FIXME(sized_hierarchy): remove this #[rustc_const_unstable(feature = "const_cmp", issue = "143800")] -pub const trait PartialOrd: PartialEq + PointeeSized { +pub const trait PartialOrd: + [const] PartialEq + PointeeSized +{ /// This method returns an ordering between `self` and `other` values if one exists. /// /// # Examples From e500dd820bc703b5b727e691e89a8f879522a90f Mon Sep 17 00:00:00 2001 From: Marijn Schouten Date: Fri, 19 Sep 2025 14:46:12 +0000 Subject: [PATCH 2/6] fixes for numerous clippy warnings --- .../rustc_hir_typeck/src/method/suggest.rs | 42 ++++++++----------- compiler/rustc_hir_typeck/src/op.rs | 8 ++-- 2 files changed, 22 insertions(+), 28 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index a39ac0fcb6e3e..024b9ee08c222 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -2194,7 +2194,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { fn suggest_associated_call_syntax( &self, err: &mut Diag<'_>, - static_candidates: &Vec, + static_candidates: &[CandidateSource], rcvr_ty: Ty<'tcx>, source: SelfSource<'tcx>, item_name: Ident, @@ -2422,7 +2422,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let span_included = match parent_expr.kind { hir::ExprKind::Struct(_, eps, _) => { - eps.len() > 0 && eps.last().is_some_and(|ep| ep.span.contains(span)) + eps.last().is_some_and(|ep| ep.span.contains(span)) } // `..=` desugars into `::std::ops::RangeInclusive::new(...)`. hir::ExprKind::Call(func, ..) => func.span.contains(span), @@ -2484,7 +2484,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { simplify_type(tcx, ty, TreatParams::InstantiateWithInfer) .and_then(|simp| { tcx.incoherent_impls(simp) - .into_iter() + .iter() .find_map(|&id| self.associated_value(id, item_name)) }) .is_some() @@ -2617,7 +2617,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if let Node::Expr(call_expr) = self.tcx.parent_hir_node(seg1.hir_id) && let ControlFlow::Break(Some(expr)) = - (LetVisitor { ident_name: seg1.ident.name }).visit_body(&body) + (LetVisitor { ident_name: seg1.ident.name }).visit_body(body) && let Some(self_ty) = self.node_ty_opt(expr.hir_id) { let probe = self.lookup_probe_for_diagnostic( @@ -2960,14 +2960,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .collect::>() .into(); for pred in &local_preds { - match pred.self_ty().kind() { - ty::Adt(def, _) => { - local_spans.push_span_label( - self.tcx.def_span(def.did()), - format!("must implement `{}`", pred.trait_ref.print_trait_sugared()), - ); - } - _ => {} + if let ty::Adt(def, _) = pred.self_ty().kind() { + local_spans.push_span_label( + self.tcx.def_span(def.did()), + format!("must implement `{}`", pred.trait_ref.print_trait_sugared()), + ); } } if local_spans.primary_span().is_some() { @@ -3006,14 +3003,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .collect::>() .into(); for pred in &foreign_preds { - match pred.self_ty().kind() { - ty::Adt(def, _) => { - foreign_spans.push_span_label( - self.tcx.def_span(def.did()), - format!("not implement `{}`", pred.trait_ref.print_trait_sugared()), - ); - } - _ => {} + if let ty::Adt(def, _) = pred.self_ty().kind() { + foreign_spans.push_span_label( + self.tcx.def_span(def.did()), + format!("not implement `{}`", pred.trait_ref.print_trait_sugared()), + ); } } if foreign_spans.primary_span().is_some() { @@ -3595,7 +3589,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // would take care of them. && !skippable.contains(&Some(pick.item.container_id(self.tcx))) // Do not suggest pinning when the method is directly on `Pin`. - && pick.item.impl_container(self.tcx).map_or(true, |did| { + && pick.item.impl_container(self.tcx).is_none_or(|did| { match self.tcx.type_of(did).skip_binder().kind() { ty::Adt(def, _) => Some(def.did()) != self.tcx.lang_items().pin_type(), _ => true, @@ -3653,7 +3647,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { vec![ ( rcvr.span.shrink_to_lo(), - format!("let mut pinned = std::pin::pin!("), + "let mut pinned = std::pin::pin!(".to_string(), ), ( rcvr.span.shrink_to_hi(), @@ -4128,7 +4122,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ); let trait_span = self.tcx.def_span(trait_def_id); let mut multi_span: MultiSpan = trait_span.into(); - multi_span.push_span_label(trait_span, format!("this is the trait that is needed")); + multi_span.push_span_label(trait_span, "this is the trait that is needed".to_string()); let descr = self.tcx.associated_item(item_def_id).descr(); let rcvr_ty = rcvr_ty.map(|t| format!("`{t}`")).unwrap_or_else(|| "the receiver".to_string()); @@ -4146,7 +4140,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } multi_span.push_span_label( self.tcx.def_span(def_id), - format!("this is the trait that was imported"), + "this is the trait that was imported".to_string(), ); } err.span_note(multi_span, msg); diff --git a/compiler/rustc_hir_typeck/src/op.rs b/compiler/rustc_hir_typeck/src/op.rs index 054435379434c..a8e8582c51c49 100644 --- a/compiler/rustc_hir_typeck/src/op.rs +++ b/compiler/rustc_hir_typeck/src/op.rs @@ -566,7 +566,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { rhs_ty, lhs_expr, lhs_ty, - |lhs_ty, rhs_ty| is_compatible_after_call(lhs_ty, rhs_ty), + is_compatible_after_call, ) { // Cool } @@ -1170,8 +1170,8 @@ fn deref_ty_if_possible(ty: Ty<'_>) -> Ty<'_> { } } -/// Returns `true` if this is a built-in arithmetic operation (e.g., u32 -/// + u32, i16x4 == i16x4) and false if these types would have to be +/// Returns `true` if this is a built-in arithmetic operation (e.g., +/// u32 + u32, i16x4 == i16x4) and false if these types would have to be /// overloaded to be legal. There are two reasons that we distinguish /// builtin operations from overloaded ones (vs trying to drive /// everything uniformly through the trait system and intrinsics or @@ -1191,7 +1191,7 @@ fn is_builtin_binop<'tcx>(lhs: Ty<'tcx>, rhs: Ty<'tcx>, category: BinOpCategory) // (See https://github.com/rust-lang/rust/issues/57447.) let (lhs, rhs) = (deref_ty_if_possible(lhs), deref_ty_if_possible(rhs)); - match category.into() { + match category { BinOpCategory::Shortcircuit => true, BinOpCategory::Shift => { lhs.references_error() From 04f6b8f99242eb61756fe294dd9d46536c1c8571 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 19 Sep 2025 16:48:05 +0200 Subject: [PATCH 3/6] fix ./x readdir logic when CDPATH is set --- x | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x b/x index 551cfe6efbf33..4fce0be219e7c 100755 --- a/x +++ b/x @@ -15,7 +15,8 @@ realpath() { if [ -L "$path" ]; then readlink -f "$path" elif [ -d "$path" ]; then - (cd -P "$path" && pwd) + # "cd" is not always silent (e.g. when CDPATH is set), so discard its output. + (cd -P "$path" >/dev/null && pwd) else echo "$(realpath "$(dirname "$path")")/$(basename "$path")" fi From 3ab89abac41443b125f2440b8f525f56536d8ffc Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Fri, 19 Sep 2025 23:06:44 +0800 Subject: [PATCH 4/6] mbe: Fix feature gate for `macro_derive` --- compiler/rustc_expand/src/mbe/macro_rules.rs | 2 +- tests/ui/feature-gates/feature-gate-macro-derive.stderr | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_expand/src/mbe/macro_rules.rs b/compiler/rustc_expand/src/mbe/macro_rules.rs index 946265eba8bdb..1d147a0385c68 100644 --- a/compiler/rustc_expand/src/mbe/macro_rules.rs +++ b/compiler/rustc_expand/src/mbe/macro_rules.rs @@ -702,7 +702,7 @@ pub fn compile_declarative_macro( kinds |= MacroKinds::DERIVE; let derive_keyword_span = p.prev_token.span; if !features.macro_derive() { - feature_err(sess, sym::macro_attr, span, "`macro_rules!` derives are unstable") + feature_err(sess, sym::macro_derive, span, "`macro_rules!` derives are unstable") .emit(); } if let Some(guar) = check_no_eof(sess, &p, "expected `()` after `derive`") { diff --git a/tests/ui/feature-gates/feature-gate-macro-derive.stderr b/tests/ui/feature-gates/feature-gate-macro-derive.stderr index b7ca6717bd51f..177518edafb38 100644 --- a/tests/ui/feature-gates/feature-gate-macro-derive.stderr +++ b/tests/ui/feature-gates/feature-gate-macro-derive.stderr @@ -4,8 +4,8 @@ error[E0658]: `macro_rules!` derives are unstable LL | macro_rules! MyDerive { derive() {} => {} } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: see issue #83527 for more information - = help: add `#![feature(macro_attr)]` to the crate attributes to enable + = note: see issue #143549 for more information + = help: add `#![feature(macro_derive)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error: aborting due to 1 previous error From e2de670558111dc6ce46d764aed6cb3dc4222794 Mon Sep 17 00:00:00 2001 From: Marijn Schouten Date: Fri, 19 Sep 2025 17:21:55 +0000 Subject: [PATCH 5/6] btree: safety comments for init and new --- library/alloc/src/collections/btree/node.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/library/alloc/src/collections/btree/node.rs b/library/alloc/src/collections/btree/node.rs index 37f784a322cad..b233e1740b7b7 100644 --- a/library/alloc/src/collections/btree/node.rs +++ b/library/alloc/src/collections/btree/node.rs @@ -67,6 +67,10 @@ struct LeafNode { impl LeafNode { /// Initializes a new `LeafNode` in-place. + /// + /// # Safety + /// + /// The caller must ensure that `this` points to a (possibly uninitialized) `LeafNode` unsafe fn init(this: *mut Self) { // As a general policy, we leave fields uninitialized if they can be, as this should // be both slightly faster and easier to track in Valgrind. @@ -79,9 +83,11 @@ impl LeafNode { /// Creates a new boxed `LeafNode`. fn new(alloc: A) -> Box { + let mut leaf = Box::new_uninit_in(alloc); unsafe { - let mut leaf = Box::new_uninit_in(alloc); + // SAFETY: `leaf` points to a `LeafNode` LeafNode::init(leaf.as_mut_ptr()); + // SAFETY: `leaf` was just initialized leaf.assume_init() } } From 696add0d477a65d6a79d97c6b8e0f4ab9268bb89 Mon Sep 17 00:00:00 2001 From: sysrex <769991+sysrex@users.noreply.github.com> Date: Fri, 19 Sep 2025 19:04:48 +0100 Subject: [PATCH 6/6] chore: fixes #146756 --- CONTRIBUTING.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index aadc7c48ea839..5b52c3dfff61d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -31,8 +31,8 @@ bootstrapping, the compiler architecture, source code representation, and more. ## [Getting help](https://rustc-dev-guide.rust-lang.org/getting-started.html#asking-questions) -There are many ways you can get help when you're stuck. Rust has many platforms for this: -[internals], [rust-zulip], and [rust-discord]. It is recommended to ask for help on +There are many ways you can get help when you're stuck. Rust has two platforms for this: +[internals] and [rust-zulip]. It is recommended to ask for help on the [rust-zulip], but any of these platforms are great ways to seek help and even find a mentor! You can learn more about asking questions and getting help in the [Asking Questions](https://rustc-dev-guide.rust-lang.org/getting-started.html#asking-questions) chapter of the [rustc-dev-guide].