From cf91330b6ba45e3111264e9d376217701912ec03 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Fri, 28 Nov 2025 23:14:33 -0500 Subject: [PATCH 1/3] collapse `constness` query `match` logic We already have the HIR node data, so no need for asking `def_kind` again. --- .../src/const_eval/fn_queries.rs | 73 +++++++++---------- tests/crashes/137187.rs | 5 +- 2 files changed, 37 insertions(+), 41 deletions(-) diff --git a/compiler/rustc_const_eval/src/const_eval/fn_queries.rs b/compiler/rustc_const_eval/src/const_eval/fn_queries.rs index 3e11541aace97..cdf0dcff381fc 100644 --- a/compiler/rustc_const_eval/src/const_eval/fn_queries.rs +++ b/compiler/rustc_const_eval/src/const_eval/fn_queries.rs @@ -1,53 +1,48 @@ -use rustc_hir as hir; -use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LocalDefId}; +use rustc_hir::{ + Constness, ExprKind, ForeignItemKind, ImplItem, ImplItemImplKind, ImplItemKind, Item, ItemKind, + Node, TraitItem, TraitItemKind, VariantData, +}; use rustc_middle::query::Providers; use rustc_middle::ty::TyCtxt; -fn parent_impl_or_trait_constness(tcx: TyCtxt<'_>, def_id: LocalDefId) -> hir::Constness { - let parent_id = tcx.local_parent(def_id); - match tcx.def_kind(parent_id) { - DefKind::Impl { of_trait: true } => tcx.impl_trait_header(parent_id).constness, - DefKind::Impl { of_trait: false } => tcx.constness(parent_id), - DefKind::Trait => { - if tcx.is_const_trait(parent_id.into()) { - hir::Constness::Const - } else { - hir::Constness::NotConst - } - } - _ => hir::Constness::NotConst, - } -} - -/// Checks whether a function-like definition is considered to be `const`. -fn constness(tcx: TyCtxt<'_>, def_id: LocalDefId) -> hir::Constness { +/// Checks whether a function-like definition is considered to be `const`. Also stores constness of inherent impls. +fn constness(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Constness { let node = tcx.hir_node_by_def_id(def_id); match node { - hir::Node::Ctor(hir::VariantData::Tuple(..)) => hir::Constness::Const, - hir::Node::ForeignItem(item) if let hir::ForeignItemKind::Fn(..) = item.kind => { + Node::Ctor(VariantData::Tuple(..)) => Constness::Const, + Node::ForeignItem(item) if let ForeignItemKind::Fn(..) = item.kind => { // Foreign functions cannot be evaluated at compile-time. - hir::Constness::NotConst + Constness::NotConst } - hir::Node::Expr(e) if let hir::ExprKind::Closure(c) = e.kind => c.constness, - hir::Node::Item(i) if let hir::ItemKind::Impl(impl_) = i.kind => impl_.constness, - _ => { - if let Some(fn_kind) = node.fn_kind() { - if fn_kind.constness() == hir::Constness::Const { - return hir::Constness::Const; - } - - // If the function itself is not annotated with `const`, it may still be a `const fn` - // if it resides in a const trait impl. - parent_impl_or_trait_constness(tcx, def_id) - } else { - tcx.dcx().span_bug( - tcx.def_span(def_id), - format!("should not be requesting the constness of items that can't be const: {node:#?}: {:?}", tcx.def_kind(def_id)) - ) + Node::Expr(e) if let ExprKind::Closure(c) = e.kind => c.constness, + // FIXME(fee1-dead): extract this one out and rename this query to `fn_constness` so we don't need `is_const_fn` anymore. + Node::Item(i) if let ItemKind::Impl(impl_) = i.kind => impl_.constness, + Node::Item(Item { kind: ItemKind::Fn { sig, .. }, .. }) => sig.header.constness, + Node::ImplItem(ImplItem { + impl_kind: ImplItemImplKind::Trait { .. }, + kind: ImplItemKind::Fn(..), + .. + }) => tcx.impl_trait_header(tcx.local_parent(def_id)).constness, + Node::ImplItem(ImplItem { + impl_kind: ImplItemImplKind::Inherent { .. }, + kind: ImplItemKind::Fn(sig, _), + .. + }) => { + match sig.header.constness { + Constness::Const => Constness::Const, + // inherent impl could be const + Constness::NotConst => tcx.constness(tcx.local_parent(def_id)), } } + Node::TraitItem(TraitItem { kind: TraitItemKind::Fn(..), .. }) => tcx.trait_def(tcx.local_parent(def_id)).constness, + _ => { + tcx.dcx().span_bug( + tcx.def_span(def_id), + format!("should not be requesting the constness of items that can't be const: {node:#?}: {:?}", tcx.def_kind(def_id)) + ) + } } } diff --git a/tests/crashes/137187.rs b/tests/crashes/137187.rs index 05cfb2b10e109..f63b459de9d03 100644 --- a/tests/crashes/137187.rs +++ b/tests/crashes/137187.rs @@ -1,9 +1,10 @@ //@ known-bug: #137187 use std::ops::Add; -trait A where + +const trait A where *const Self: Add, { - const fn b(c: *const Self) -> <*const Self as Add>::Output { + fn b(c: *const Self) -> <*const Self as Add>::Output { c + c } } From 5d8f2b8ebed329268229f1c700fe88c08d454e2d Mon Sep 17 00:00:00 2001 From: tison Date: Sun, 23 Nov 2025 19:24:50 +0800 Subject: [PATCH 2/3] Clarify edge cases for Barrier::new --- library/std/src/sync/barrier.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/std/src/sync/barrier.rs b/library/std/src/sync/barrier.rs index c2c18889dde7d..6a5cc9b69f82c 100644 --- a/library/std/src/sync/barrier.rs +++ b/library/std/src/sync/barrier.rs @@ -65,8 +65,8 @@ impl fmt::Debug for Barrier { impl Barrier { /// Creates a new barrier that can block a given number of threads. /// - /// A barrier will block `n`-1 threads which call [`wait()`] and then wake - /// up all threads at once when the `n`th thread calls [`wait()`]. + /// A barrier will block all threads which call [`wait()`] until the `n`th thread calls [`wait()`], + /// and then wake up all threads at once. /// /// [`wait()`]: Barrier::wait /// From 3287178d1f15d81e1f32c484eda86e264d27e037 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 30 Nov 2025 11:03:24 +0100 Subject: [PATCH 3/3] float::min/max: reference NaN bit pattern rules --- library/core/src/num/f128.rs | 18 ++++++++++++------ library/core/src/num/f16.rs | 18 ++++++++++++------ library/core/src/num/f32.rs | 18 ++++++++++++------ library/core/src/num/f64.rs | 18 ++++++++++++------ 4 files changed, 48 insertions(+), 24 deletions(-) diff --git a/library/core/src/num/f128.rs b/library/core/src/num/f128.rs index bfe3a501f4537..e6e258d283939 100644 --- a/library/core/src/num/f128.rs +++ b/library/core/src/num/f128.rs @@ -694,11 +694,14 @@ impl f128 { /// Returns the maximum of the two numbers, ignoring NaN. /// - /// If one of the arguments is NaN, then the other argument is returned. + /// If exactly one of the arguments is NaN, then the other argument is returned. If both + /// arguments are NaN, the return value is NaN, with the bit pattern picked using the usual + /// [rules for arithmetic operations](f32#nan-bit-patterns). If the inputs compare equal (such + /// as for the case of `+0.0` and `-0.0`), either input may be returned non-deterministically. + /// /// This follows the IEEE 754-2008 semantics for `maxNum`, except for handling of signaling NaNs; /// this function handles all NaNs the same way and avoids `maxNum`'s problems with associativity. - /// This also matches the behavior of libm’s fmax. In particular, if the inputs compare equal - /// (such as for the case of `+0.0` and `-0.0`), either input may be returned non-deterministically. + /// This also matches the behavior of libm’s `fmax`. /// /// ``` /// #![feature(f128)] @@ -722,11 +725,14 @@ impl f128 { /// Returns the minimum of the two numbers, ignoring NaN. /// - /// If one of the arguments is NaN, then the other argument is returned. + /// If exactly one of the arguments is NaN, then the other argument is returned. If both + /// arguments are NaN, the return value is NaN, with the bit pattern picked using the usual + /// [rules for arithmetic operations](f32#nan-bit-patterns). If the inputs compare equal (such + /// as for the case of `+0.0` and `-0.0`), either input may be returned non-deterministically. + /// /// This follows the IEEE 754-2008 semantics for `minNum`, except for handling of signaling NaNs; /// this function handles all NaNs the same way and avoids `minNum`'s problems with associativity. - /// This also matches the behavior of libm’s fmin. In particular, if the inputs compare equal - /// (such as for the case of `+0.0` and `-0.0`), either input may be returned non-deterministically. + /// This also matches the behavior of libm’s `fmin`. /// /// ``` /// #![feature(f128)] diff --git a/library/core/src/num/f16.rs b/library/core/src/num/f16.rs index d3a12e94c800c..4739b798e5d38 100644 --- a/library/core/src/num/f16.rs +++ b/library/core/src/num/f16.rs @@ -687,11 +687,14 @@ impl f16 { /// Returns the maximum of the two numbers, ignoring NaN. /// - /// If one of the arguments is NaN, then the other argument is returned. + /// If exactly one of the arguments is NaN, then the other argument is returned. If both + /// arguments are NaN, the return value is NaN, with the bit pattern picked using the usual + /// [rules for arithmetic operations](f32#nan-bit-patterns). If the inputs compare equal (such + /// as for the case of `+0.0` and `-0.0`), either input may be returned non-deterministically. + /// /// This follows the IEEE 754-2008 semantics for `maxNum`, except for handling of signaling NaNs; /// this function handles all NaNs the same way and avoids `maxNum`'s problems with associativity. - /// This also matches the behavior of libm’s fmax. In particular, if the inputs compare equal - /// (such as for the case of `+0.0` and `-0.0`), either input may be returned non-deterministically. + /// This also matches the behavior of libm’s `fmax`. /// /// ``` /// #![feature(f16)] @@ -714,11 +717,14 @@ impl f16 { /// Returns the minimum of the two numbers, ignoring NaN. /// - /// If one of the arguments is NaN, then the other argument is returned. + /// If exactly one of the arguments is NaN, then the other argument is returned. If both + /// arguments are NaN, the return value is NaN, with the bit pattern picked using the usual + /// [rules for arithmetic operations](f32#nan-bit-patterns). If the inputs compare equal (such + /// as for the case of `+0.0` and `-0.0`), either input may be returned non-deterministically. + /// /// This follows the IEEE 754-2008 semantics for `minNum`, except for handling of signaling NaNs; /// this function handles all NaNs the same way and avoids `minNum`'s problems with associativity. - /// This also matches the behavior of libm’s fmin. In particular, if the inputs compare equal - /// (such as for the case of `+0.0` and `-0.0`), either input may be returned non-deterministically. + /// This also matches the behavior of libm’s `fmin`. /// /// ``` /// #![feature(f16)] diff --git a/library/core/src/num/f32.rs b/library/core/src/num/f32.rs index 7e6a757e5e297..3cbff38f281a4 100644 --- a/library/core/src/num/f32.rs +++ b/library/core/src/num/f32.rs @@ -897,11 +897,14 @@ impl f32 { /// Returns the maximum of the two numbers, ignoring NaN. /// - /// If one of the arguments is NaN, then the other argument is returned. + /// If exactly one of the arguments is NaN, then the other argument is returned. If both + /// arguments are NaN, the return value is NaN, with the bit pattern picked using the usual + /// [rules for arithmetic operations](f32#nan-bit-patterns). If the inputs compare equal (such + /// as for the case of `+0.0` and `-0.0`), either input may be returned non-deterministically. + /// /// This follows the IEEE 754-2008 semantics for `maxNum`, except for handling of signaling NaNs; /// this function handles all NaNs the same way and avoids `maxNum`'s problems with associativity. - /// This also matches the behavior of libm’s fmax. In particular, if the inputs compare equal - /// (such as for the case of `+0.0` and `-0.0`), either input may be returned non-deterministically. + /// This also matches the behavior of libm’s `fmax`. /// /// ``` /// let x = 1.0f32; @@ -920,11 +923,14 @@ impl f32 { /// Returns the minimum of the two numbers, ignoring NaN. /// - /// If one of the arguments is NaN, then the other argument is returned. + /// If exactly one of the arguments is NaN, then the other argument is returned. If both + /// arguments are NaN, the return value is NaN, with the bit pattern picked using the usual + /// [rules for arithmetic operations](f32#nan-bit-patterns). If the inputs compare equal (such + /// as for the case of `+0.0` and `-0.0`), either input may be returned non-deterministically. + /// /// This follows the IEEE 754-2008 semantics for `minNum`, except for handling of signaling NaNs; /// this function handles all NaNs the same way and avoids `minNum`'s problems with associativity. - /// This also matches the behavior of libm’s fmin. In particular, if the inputs compare equal - /// (such as for the case of `+0.0` and `-0.0`), either input may be returned non-deterministically. + /// This also matches the behavior of libm’s `fmin`. /// /// ``` /// let x = 1.0f32; diff --git a/library/core/src/num/f64.rs b/library/core/src/num/f64.rs index 854bdcf39d09e..60ceff0369b81 100644 --- a/library/core/src/num/f64.rs +++ b/library/core/src/num/f64.rs @@ -915,11 +915,14 @@ impl f64 { /// Returns the maximum of the two numbers, ignoring NaN. /// - /// If one of the arguments is NaN, then the other argument is returned. + /// If exactly one of the arguments is NaN, then the other argument is returned. If both + /// arguments are NaN, the return value is NaN, with the bit pattern picked using the usual + /// [rules for arithmetic operations](f32#nan-bit-patterns). If the inputs compare equal (such + /// as for the case of `+0.0` and `-0.0`), either input may be returned non-deterministically. + /// /// This follows the IEEE 754-2008 semantics for `maxNum`, except for handling of signaling NaNs; /// this function handles all NaNs the same way and avoids `maxNum`'s problems with associativity. - /// This also matches the behavior of libm’s fmax. In particular, if the inputs compare equal - /// (such as for the case of `+0.0` and `-0.0`), either input may be returned non-deterministically. + /// This also matches the behavior of libm’s `fmax`. /// /// ``` /// let x = 1.0_f64; @@ -938,11 +941,14 @@ impl f64 { /// Returns the minimum of the two numbers, ignoring NaN. /// - /// If one of the arguments is NaN, then the other argument is returned. + /// If exactly one of the arguments is NaN, then the other argument is returned. If both + /// arguments are NaN, the return value is NaN, with the bit pattern picked using the usual + /// [rules for arithmetic operations](f32#nan-bit-patterns). If the inputs compare equal (such + /// as for the case of `+0.0` and `-0.0`), either input may be returned non-deterministically. + /// /// This follows the IEEE 754-2008 semantics for `minNum`, except for handling of signaling NaNs; /// this function handles all NaNs the same way and avoids `minNum`'s problems with associativity. - /// This also matches the behavior of libm’s fmin. In particular, if the inputs compare equal - /// (such as for the case of `+0.0` and `-0.0`), either input may be returned non-deterministically. + /// This also matches the behavior of libm’s `fmin`. /// /// ``` /// let x = 1.0_f64;