Skip to content
Closed
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
4 changes: 2 additions & 2 deletions compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ impl<S: Stage> SingleAttributeParser<S> for RustcObjcClassParser {
return None;
};
let Some(classname) = nv.value_as_str() else {
// `#[rustc_objc_class = ...]` is expected to be used as an implementatioin detail
// `#[rustc_objc_class = ...]` is expected to be used as an implementation detail
// inside a standard library macro, but `cx.expected_string_literal` exposes too much.
// Use a custom error message instead.
cx.emit_err(ObjcClassExpectedStringLiteral { span: nv.value_span });
Expand Down Expand Up @@ -201,7 +201,7 @@ impl<S: Stage> SingleAttributeParser<S> for RustcObjcSelectorParser {
return None;
};
let Some(methname) = nv.value_as_str() else {
// `#[rustc_objc_selector = ...]` is expected to be used as an implementatioin detail
// `#[rustc_objc_selector = ...]` is expected to be used as an implementation detail
// inside a standard library macro, but `cx.expected_string_literal` exposes too much.
// Use a custom error message instead.
cx.emit_err(ObjcSelectorExpectedStringLiteral { span: nv.value_span });
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ Date: Sun, 15 Feb 2026 14:06:49 +0000
Subject: [PATCH] Disable f16 math tests for cranelift

---
coretests/tests/floats/mod.rs | 26 +++++++++++++-------------
coretests/tests/num/floats.rs | 26 +++++++++++++-------------
1 file changed, 13 insertions(+), 13 deletions(-)

diff --git a/coretests/tests/floats/mod.rs b/coretests/tests/floats/mod.rs
index c61961f8584..d7b4fa20322 100644
--- a/coretests/tests/floats/mod.rs
+++ b/coretests/tests/floats/mod.rs
--- a/coretests/tests/num/floats.rs
+++ b/coretests/tests/num/floats.rs
@@ -1534,7 +1534,7 @@ fn s_nan() -> Float {
name: powf,
attrs: {
Expand Down Expand Up @@ -128,6 +128,5 @@ index c61961f8584..d7b4fa20322 100644
f128: #[cfg(all(not(miri), target_has_reliable_f128_math))],
},
test {
--
--
2.50.1

2 changes: 1 addition & 1 deletion compiler/rustc_codegen_ssa/src/mir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -437,7 +437,7 @@ fn arg_local_refs<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
assert_eq!(
None,
num_untupled.replace(tupled_arg_tys.len()),
"Replaced existing num_tupled"
"Replaced existing num_untupled"
);

return LocalRef::Place(place);
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir/src/def.rs
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ pub enum DefKind {
/// These are all represented with the same `ExprKind::Closure` in the AST and HIR,
/// which makes it difficult to distinguish these during def collection. Therefore,
/// we treat them all the same, and code which needs to distinguish them can match
/// or `hir::ClosureKind` or `type_of`.
/// on `hir::ClosureKind` or `type_of`.
Closure,
/// The definition of a synthetic coroutine body created by the lowering of a
/// coroutine-closure, such as an async closure.
Expand Down
6 changes: 1 addition & 5 deletions compiler/rustc_hir/src/target.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
//! This module implements some validity checks for attributes.
//! In particular it verifies that `#[inline]` and `#[repr]` attributes are
//! attached to items that actually support them and if there are
//! conflicts between multiple such attributes attached to the same
//! item.
//! This module lists attribute targets, with conversions from other types.

use std::fmt::{self, Display};

Expand Down
22 changes: 21 additions & 1 deletion compiler/rustc_public/src/compiler_interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ use crate::ty::{
AdtDef, AdtKind, Allocation, ClosureDef, ClosureKind, CoroutineDef, Discr, FieldDef, FnDef,
ForeignDef, ForeignItemKind, ForeignModule, ForeignModuleDef, GenericArgs, GenericPredicates,
Generics, ImplDef, ImplTrait, IntrinsicDef, LineInfo, MirConst, PolyFnSig, RigidTy, Span,
TraitDecl, TraitDef, Ty, TyConst, TyConstId, TyKind, UintTy, VariantDef, VariantIdx,
TraitDecl, TraitDef, TraitRef, Ty, TyConst, TyConstId, TyKind, UintTy, VariantDef, VariantIdx,
VtblEntry,
};
use crate::unstable::{RustcInternal, Stable, new_item_kind};
use crate::{
Expand Down Expand Up @@ -838,6 +839,25 @@ impl<'tcx> CompilerInterface<'tcx> {
let did = tables[def_id];
cx.associated_items(did).iter().map(|assoc| assoc.stable(&mut *tables, cx)).collect()
}

/// Get all vtable entries of a trait.
pub(crate) fn vtable_entries(&self, trait_ref: &TraitRef) -> Vec<VtblEntry> {
let mut tables = self.tables.borrow_mut();
let cx = &*self.cx.borrow();
cx.vtable_entries(trait_ref.internal(&mut *tables, cx.tcx))
.iter()
.map(|v| v.stable(&mut *tables, cx))
.collect()
}

/// Returns the vtable entry at the given index.
///
/// Returns `None` if the index is out of bounds.
pub(crate) fn vtable_entry(&self, trait_ref: &TraitRef, idx: usize) -> Option<VtblEntry> {
let mut tables = self.tables.borrow_mut();
let cx = &*self.cx.borrow();
cx.vtable_entry(trait_ref.internal(&mut *tables, cx.tcx), idx).stable(&mut *tables, cx)
}
}

// A thread local variable that stores a pointer to [`CompilerInterface`].
Expand Down
30 changes: 29 additions & 1 deletion compiler/rustc_public/src/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use super::{DefId, Error, Symbol, with};
use crate::abi::{FnAbi, Layout};
use crate::crate_def::{CrateDef, CrateDefType};
use crate::mir::alloc::{AllocId, read_target_int, read_target_uint};
use crate::mir::mono::StaticDef;
use crate::mir::mono::{Instance, StaticDef};
use crate::target::MachineInfo;
use crate::{AssocItems, Filename, IndexedVal, Opaque, ThreadLocalIndex};

Expand Down Expand Up @@ -1440,6 +1440,18 @@ impl TraitRef {
};
self_ty
}

/// Retrieve all vtable entries.
pub fn vtable_entries(&self) -> Vec<VtblEntry> {
with(|cx| cx.vtable_entries(self))
}

/// Returns the vtable entry at the given index.
///
/// Returns `None` if the index is out of bounds.
pub fn vtable_entry(&self, idx: usize) -> Option<VtblEntry> {
with(|cx| cx.vtable_entry(self, idx))
}
}

#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
Expand Down Expand Up @@ -1656,3 +1668,19 @@ impl AssocItem {
matches!(self.kind, AssocKind::Type { data: AssocTypeData::Rpitit(_) })
}
}

#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub enum VtblEntry {
/// destructor of this type (used in vtable header)
MetadataDropInPlace,
/// layout size of this type (used in vtable header)
MetadataSize,
/// layout align of this type (used in vtable header)
MetadataAlign,
/// non-dispatchable associated function that is excluded from trait object
Vacant,
/// dispatchable associated function
Method(Instance),
/// pointer to a separate supertrait vtable, can be used by trait upcasting coercion
TraitVPtr(TraitRef),
}
22 changes: 22 additions & 0 deletions compiler/rustc_public/src/unstable/convert/stable/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1139,3 +1139,25 @@ impl<'tcx> Stable<'tcx> for rustc_middle::ty::util::Discr<'tcx> {
crate::ty::Discr { val: self.val, ty: self.ty.stable(tables, cx) }
}
}

impl<'tcx> Stable<'tcx> for rustc_middle::ty::VtblEntry<'tcx> {
type T = crate::ty::VtblEntry;

fn stable<'cx>(
&self,
tables: &mut Tables<'cx, BridgeTys>,
cx: &CompilerCtxt<'cx, BridgeTys>,
) -> Self::T {
use crate::ty::VtblEntry;
match self {
ty::VtblEntry::MetadataDropInPlace => VtblEntry::MetadataDropInPlace,
ty::VtblEntry::MetadataSize => VtblEntry::MetadataSize,
ty::VtblEntry::MetadataAlign => VtblEntry::MetadataAlign,
ty::VtblEntry::Vacant => VtblEntry::Vacant,
ty::VtblEntry::Method(instance) => VtblEntry::Method(instance.stable(tables, cx)),
ty::VtblEntry::TraitVPtr(trait_ref) => {
VtblEntry::TraitVPtr(trait_ref.stable(tables, cx))
}
}
}
}
14 changes: 13 additions & 1 deletion compiler/rustc_public_bridge/src/context/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use rustc_middle::ty::{
AdtDef, AdtKind, AssocItem, Binder, ClosureKind, CoroutineArgsExt, EarlyBinder,
ExistentialTraitRef, FnSig, GenericArgsRef, Instance, InstanceKind, IntrinsicDef, List,
PolyFnSig, ScalarInt, TraitDef, TraitRef, Ty, TyCtxt, TyKind, TypeVisitableExt, UintTy,
ValTree, VariantDef,
ValTree, VariantDef, VtblEntry,
};
use rustc_middle::{mir, ty};
use rustc_session::cstore::ForeignModule;
Expand Down Expand Up @@ -757,4 +757,16 @@ impl<'tcx, B: Bridge> CompilerCtxt<'tcx, B> {
};
assoc_items
}

/// Get all vtable entries of a trait.
pub fn vtable_entries(&self, trait_ref: TraitRef<'tcx>) -> Vec<VtblEntry<'tcx>> {
self.tcx.vtable_entries(trait_ref).to_vec()
}

/// Returns the vtable entry at the given index.
///
/// Returns `None` if the index is out of bounds.
pub fn vtable_entry(&self, trait_ref: TraitRef<'tcx>, idx: usize) -> Option<VtblEntry<'tcx>> {
self.vtable_entries(trait_ref).get(idx).copied()
}
}
1 change: 0 additions & 1 deletion library/coretests/tests/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,6 @@ mod cmp;
mod const_ptr;
mod convert;
mod ffi;
mod floats;
mod fmt;
mod future;
mod hash;
Expand Down
166 changes: 166 additions & 0 deletions library/coretests/tests/num/float_ieee754_flt2dec_dec2flt.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
//! IEEE 754 floating point compliance tests
//!
//! To understand IEEE 754's requirements on a programming language, one must understand that the
//! requirements of IEEE 754 rest on the total programming environment, and not entirely on any
//! one component. That means the hardware, language, and even libraries are considered part of
//! conforming floating point support in a programming environment.
//!
//! A programming language's duty, accordingly, is:
//! 1. offer access to the hardware where the hardware offers support
//! 2. provide operations that fulfill the remaining requirements of the standard
//! 3. provide the ability to write additional software that can fulfill those requirements
//!
//! This may be fulfilled in any combination that the language sees fit. However, to claim that
//! a language supports IEEE 754 is to suggest that it has fulfilled requirements 1 and 2, without
//! deferring minimum requirements to libraries. This is because support for IEEE 754 is defined
//! as complete support for at least one specified floating point type as an "arithmetic" and
//! "interchange" format, plus specified type conversions to "external character sequences" and
//! integer types.
//!
//! For our purposes,
//! "interchange format" => f16, f32, f64, f128
//! "arithmetic format" => f16, f32, f64, f128, and any "soft floats"
//! "external character sequence" => str from any float
//! "integer format" => {i,u}{8,16,32,64,128}
//!
//! None of these tests are against Rust's own implementation. They are only tests against the
//! standard. That is why they accept wildly diverse inputs or may seem to duplicate other tests.
//! Please consider this carefully when adding, removing, or reorganizing these tests. They are
//! here so that it is clear what tests are required by the standard and what can be changed.

use core::fmt;
use core::str::FromStr;

use crate::num::{assert_biteq, float_test};

/// ToString uses the default fmt::Display impl without special concerns, and bypasses other parts
/// of the formatting infrastructure, which makes it ideal for testing here.
#[track_caller]
fn string_roundtrip<T>(x: T) -> T
where
T: FromStr<Err: fmt::Debug> + fmt::Display,
{
x.to_string().parse::<T>().unwrap()
}

// FIXME(f128): Tests are disabled while we don't have parsing / printing

// We must preserve signs on all numbers. That includes zero.
// -0 and 0 are == normally, so test bit equality.
float_test! {
name: preserve_signed_zero,
attrs: {
const: #[cfg(false)],
f16: #[cfg(any(miri, target_has_reliable_f16))],
f128: #[cfg(false)],
},
test {
let neg0 = flt(-0.0);
let pos0 = flt(0.0);
assert_biteq!(neg0, string_roundtrip(neg0));
assert_biteq!(pos0, string_roundtrip(pos0));
assert_ne!(neg0.to_bits(), pos0.to_bits());
}
}

float_test! {
name: preserve_signed_infinity,
attrs: {
const: #[cfg(false)],
f16: #[cfg(any(miri, target_has_reliable_f16))],
f128: #[cfg(false)],
},
test {
let neg_inf = Float::NEG_INFINITY;
let pos_inf = Float::INFINITY;
assert_biteq!(neg_inf, string_roundtrip(neg_inf));
assert_biteq!(pos_inf, string_roundtrip(pos_inf));
assert_ne!(neg_inf.to_bits(), pos_inf.to_bits());
}
}

float_test! {
name: infinity_to_str,
attrs: {
const: #[cfg(false)],
f16: #[cfg(any(miri, target_has_reliable_f16))],
f128: #[cfg(false)],
},
test {
assert!(
match Float::INFINITY.to_string().to_lowercase().as_str() {
"+infinity" | "infinity" => true,
"+inf" | "inf" => true,
_ => false,
},
"Infinity must write to a string as some casing of inf or infinity, with an optional +."
);
assert!(
match Float::NEG_INFINITY.to_string().to_lowercase().as_str() {
"-infinity" | "-inf" => true,
_ => false,
},
"Negative Infinity must write to a string as some casing of -inf or -infinity"
);
}
}

float_test! {
name: nan_to_str,
attrs: {
const: #[cfg(false)],
f16: #[cfg(any(miri, target_has_reliable_f16))],
f128: #[cfg(false)],
},
test {
assert!(
match Float::NAN.to_string().to_lowercase().as_str() {
"nan" | "+nan" | "-nan" => true,
_ => false,
},
"NaNs must write to a string as some casing of nan."
)
}
}

float_test! {
name: infinity_from_str,
attrs: {
const: #[cfg(false)],
f16: #[cfg(any(miri, target_has_reliable_f16))],
f128: #[cfg(false)],
},
test {
// "+"?("inf"|"infinity") in any case => Infinity
assert_biteq!(Float::INFINITY, Float::from_str("infinity").unwrap());
assert_biteq!(Float::INFINITY, Float::from_str("inf").unwrap());
assert_biteq!(Float::INFINITY, Float::from_str("+infinity").unwrap());
assert_biteq!(Float::INFINITY, Float::from_str("+inf").unwrap());
// yes! this means you are weLcOmE tO mY iNfInItElY tWiStEd MiNd
assert_biteq!(Float::INFINITY, Float::from_str("+iNfInItY").unwrap());

// "-inf"|"-infinity" in any case => Negative Infinity
assert_biteq!(Float::NEG_INFINITY, Float::from_str("-infinity").unwrap());
assert_biteq!(Float::NEG_INFINITY, Float::from_str("-inf").unwrap());
assert_biteq!(Float::NEG_INFINITY, Float::from_str("-INF").unwrap());
assert_biteq!(Float::NEG_INFINITY, Float::from_str("-INFinity").unwrap());

}
}

float_test! {
name: qnan_from_str,
attrs: {
const: #[cfg(false)],
f16: #[cfg(any(miri, target_has_reliable_f16))],
f128: #[cfg(false)],
},
test {
// ("+"|"-"")?"s"?"nan" in any case => qNaN
assert!("nan".parse::<Float>().unwrap().is_nan());
assert!("-nan".parse::<Float>().unwrap().is_nan());
assert!("+nan".parse::<Float>().unwrap().is_nan());
assert!("+NAN".parse::<Float>().unwrap().is_nan());
assert!("-NaN".parse::<Float>().unwrap().is_nan());
}
}
Loading
Loading