Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 34 additions & 39 deletions compiler/rustc_const_eval/src/const_eval/fn_queries.rs
Original file line number Diff line number Diff line change
@@ -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))
)
}
}
}

Expand Down
18 changes: 12 additions & 6 deletions library/core/src/num/f128.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand All @@ -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)]
Expand Down
18 changes: 12 additions & 6 deletions library/core/src/num/f16.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand All @@ -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)]
Expand Down
18 changes: 12 additions & 6 deletions library/core/src/num/f32.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down
18 changes: 12 additions & 6 deletions library/core/src/num/f64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down
4 changes: 2 additions & 2 deletions library/std/src/sync/barrier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
///
Expand Down
5 changes: 3 additions & 2 deletions tests/crashes/137187.rs
Original file line number Diff line number Diff line change
@@ -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
}
}
Loading