Skip to content

Commit ca08c23

Browse files
committed
Auto merge of rust-lang#120666 - matthiaskrgr:rollup-z3ixwov, r=matthiaskrgr
Rollup of 9 pull requests Successful merges: - rust-lang#113833 (`std::error::Error` -> Trait Implementations: lifetimes consistency improvement) - rust-lang#115386 (PartialEq, PartialOrd: update and synchronize handling of transitive chains) - rust-lang#116284 (make matching on NaN a hard error, and remove the rest of illegal_floating_point_literal_pattern) - rust-lang#118960 (Add LocalWaker and ContextBuilder types to core, and LocalWake trait to alloc.) - rust-lang#120384 (Use `<T, U>` for array/slice equality `impl`s) - rust-lang#120518 (riscv only supports split_debuginfo=off for now) - rust-lang#120619 (Assert that params with the same *index* have the same *name*) - rust-lang#120657 (Remove unused struct) - rust-lang#120661 (target: default to the medium code model on LoongArch targets) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 8c0b4f6 + 2a23f5f commit ca08c23

File tree

57 files changed

+1039
-610
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

57 files changed

+1039
-610
lines changed

compiler/rustc_hir_analysis/src/check/intrinsic.rs

+21-4
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use rustc_errors::{codes::*, struct_span_code_err, DiagnosticMessage};
1212
use rustc_hir as hir;
1313
use rustc_middle::traits::{ObligationCause, ObligationCauseCode};
1414
use rustc_middle::ty::{self, Ty, TyCtxt};
15-
use rustc_span::symbol::{kw, sym, Symbol};
15+
use rustc_span::symbol::{kw, sym};
1616
use rustc_target::spec::abi::Abi;
1717

1818
fn equate_intrinsic_type<'tcx>(
@@ -132,7 +132,17 @@ pub fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: DefId) -> hir
132132
/// Remember to add all intrinsics here, in `compiler/rustc_codegen_llvm/src/intrinsic.rs`,
133133
/// and in `library/core/src/intrinsics.rs`.
134134
pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
135-
let param = |n| Ty::new_param(tcx, n, Symbol::intern(&format!("P{n}")));
135+
let generics = tcx.generics_of(it.owner_id);
136+
let param = |n| {
137+
if let Some(&ty::GenericParamDef {
138+
name, kind: ty::GenericParamDefKind::Type { .. }, ..
139+
}) = generics.opt_param_at(n as usize, tcx)
140+
{
141+
Ty::new_param(tcx, n, name)
142+
} else {
143+
Ty::new_error_with_message(tcx, tcx.def_span(it.owner_id), "expected param")
144+
}
145+
};
136146
let intrinsic_id = it.owner_id.to_def_id();
137147
let intrinsic_name = tcx.item_name(intrinsic_id);
138148
let name_str = intrinsic_name.as_str();
@@ -475,9 +485,16 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
475485

476486
/// Type-check `extern "platform-intrinsic" { ... }` functions.
477487
pub fn check_platform_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
488+
let generics = tcx.generics_of(it.owner_id);
478489
let param = |n| {
479-
let name = Symbol::intern(&format!("P{n}"));
480-
Ty::new_param(tcx, n, name)
490+
if let Some(&ty::GenericParamDef {
491+
name, kind: ty::GenericParamDefKind::Type { .. }, ..
492+
}) = generics.opt_param_at(n as usize, tcx)
493+
{
494+
Ty::new_param(tcx, n, name)
495+
} else {
496+
Ty::new_error_with_message(tcx, tcx.def_span(it.owner_id), "expected param")
497+
}
481498
};
482499

483500
let name = it.ident.name;

compiler/rustc_lint/src/lib.rs

+4
Original file line numberDiff line numberDiff line change
@@ -516,6 +516,10 @@ fn register_builtins(store: &mut LintStore) {
516516
"converted into hard error, see PR #118649 \
517517
<https://github.com/rust-lang/rust/pull/118649> for more information",
518518
);
519+
store.register_removed(
520+
"illegal_floating_point_literal_pattern",
521+
"no longer a warning, float patterns behave the same as `==`",
522+
);
519523
}
520524

521525
fn register_internals(store: &mut LintStore) {

compiler/rustc_lint_defs/src/builtin.rs

-50
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@ declare_lint_pass! {
4545
FUZZY_PROVENANCE_CASTS,
4646
HIDDEN_GLOB_REEXPORTS,
4747
ILL_FORMED_ATTRIBUTE_INPUT,
48-
ILLEGAL_FLOATING_POINT_LITERAL_PATTERN,
4948
INCOMPLETE_INCLUDE,
5049
INDIRECT_STRUCTURAL_MATCH,
5150
INEFFECTIVE_UNSTABLE_TRAIT_IMPL,
@@ -1873,55 +1872,6 @@ declare_lint! {
18731872
};
18741873
}
18751874

1876-
declare_lint! {
1877-
/// The `illegal_floating_point_literal_pattern` lint detects
1878-
/// floating-point literals used in patterns.
1879-
///
1880-
/// ### Example
1881-
///
1882-
/// ```rust
1883-
/// let x = 42.0;
1884-
///
1885-
/// match x {
1886-
/// 5.0 => {}
1887-
/// _ => {}
1888-
/// }
1889-
/// ```
1890-
///
1891-
/// {{produces}}
1892-
///
1893-
/// ### Explanation
1894-
///
1895-
/// Previous versions of the compiler accepted floating-point literals in
1896-
/// patterns, but it was later determined this was a mistake. The
1897-
/// semantics of comparing floating-point values may not be clear in a
1898-
/// pattern when contrasted with "structural equality". Typically you can
1899-
/// work around this by using a [match guard], such as:
1900-
///
1901-
/// ```rust
1902-
/// # let x = 42.0;
1903-
///
1904-
/// match x {
1905-
/// y if y == 5.0 => {}
1906-
/// _ => {}
1907-
/// }
1908-
/// ```
1909-
///
1910-
/// This is a [future-incompatible] lint to transition this to a hard
1911-
/// error in the future. See [issue #41620] for more details.
1912-
///
1913-
/// [issue #41620]: https://github.com/rust-lang/rust/issues/41620
1914-
/// [match guard]: https://doc.rust-lang.org/reference/expressions/match-expr.html#match-guards
1915-
/// [future-incompatible]: ../index.md#future-incompatible-lints
1916-
pub ILLEGAL_FLOATING_POINT_LITERAL_PATTERN,
1917-
Warn,
1918-
"floating-point literals cannot be used in patterns",
1919-
@future_incompatible = FutureIncompatibleInfo {
1920-
reason: FutureIncompatibilityReason::FutureReleaseErrorDontReportInDeps,
1921-
reference: "issue #41620 <https://github.com/rust-lang/rust/issues/41620>",
1922-
};
1923-
}
1924-
19251875
declare_lint! {
19261876
/// The `unstable_name_collisions` lint detects that you have used a name
19271877
/// that the standard library plans to add in the future.

compiler/rustc_middle/src/mir/interpret/value.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -418,8 +418,8 @@ impl<'tcx, Prov: Provenance> Scalar<Prov> {
418418

419419
#[inline]
420420
pub fn to_float<F: Float>(self) -> InterpResult<'tcx, F> {
421-
// Going through `to_uint` to check size and truncation.
422-
Ok(F::from_bits(self.to_uint(Size::from_bits(F::BITS))?))
421+
// Going through `to_bits` to check size and truncation.
422+
Ok(F::from_bits(self.to_bits(Size::from_bits(F::BITS))?))
423423
}
424424

425425
#[inline]

compiler/rustc_middle/src/ty/consts/int.rs

+44-27
Original file line numberDiff line numberDiff line change
@@ -249,11 +249,6 @@ impl ScalarInt {
249249
}
250250
}
251251

252-
#[inline]
253-
pub fn try_to_target_usize(&self, tcx: TyCtxt<'_>) -> Result<u64, Size> {
254-
Ok(self.to_bits(tcx.data_layout.pointer_size)? as u64)
255-
}
256-
257252
/// Tries to convert the `ScalarInt` to an unsigned integer of the given size.
258253
/// Fails if the size of the `ScalarInt` is not equal to `size` and returns the
259254
/// `ScalarInt`s size in that case.
@@ -262,56 +257,61 @@ impl ScalarInt {
262257
self.to_bits(size)
263258
}
264259

265-
// Tries to convert the `ScalarInt` to `bool`. Fails if the `size` of the `ScalarInt`
266-
// in not equal to `Size { raw: 1 }` or if the value is not 0 or 1 and returns the `size`
267-
// value of the `ScalarInt` in that case.
268-
#[inline]
269-
pub fn try_to_bool(self) -> Result<bool, Size> {
270-
match self.try_to_u8()? {
271-
0 => Ok(false),
272-
1 => Ok(true),
273-
_ => Err(self.size()),
274-
}
275-
}
276-
277260
// Tries to convert the `ScalarInt` to `u8`. Fails if the `size` of the `ScalarInt`
278261
// in not equal to `Size { raw: 1 }` and returns the `size` value of the `ScalarInt` in
279262
// that case.
280263
#[inline]
281264
pub fn try_to_u8(self) -> Result<u8, Size> {
282-
self.to_bits(Size::from_bits(8)).map(|v| u8::try_from(v).unwrap())
265+
self.try_to_uint(Size::from_bits(8)).map(|v| u8::try_from(v).unwrap())
283266
}
284267

285268
/// Tries to convert the `ScalarInt` to `u16`. Fails if the size of the `ScalarInt`
286269
/// in not equal to `Size { raw: 2 }` and returns the `size` value of the `ScalarInt` in
287270
/// that case.
288271
#[inline]
289272
pub fn try_to_u16(self) -> Result<u16, Size> {
290-
self.to_bits(Size::from_bits(16)).map(|v| u16::try_from(v).unwrap())
273+
self.try_to_uint(Size::from_bits(16)).map(|v| u16::try_from(v).unwrap())
291274
}
292275

293276
/// Tries to convert the `ScalarInt` to `u32`. Fails if the `size` of the `ScalarInt`
294277
/// in not equal to `Size { raw: 4 }` and returns the `size` value of the `ScalarInt` in
295278
/// that case.
296279
#[inline]
297280
pub fn try_to_u32(self) -> Result<u32, Size> {
298-
self.to_bits(Size::from_bits(32)).map(|v| u32::try_from(v).unwrap())
281+
self.try_to_uint(Size::from_bits(32)).map(|v| u32::try_from(v).unwrap())
299282
}
300283

301284
/// Tries to convert the `ScalarInt` to `u64`. Fails if the `size` of the `ScalarInt`
302285
/// in not equal to `Size { raw: 8 }` and returns the `size` value of the `ScalarInt` in
303286
/// that case.
304287
#[inline]
305288
pub fn try_to_u64(self) -> Result<u64, Size> {
306-
self.to_bits(Size::from_bits(64)).map(|v| u64::try_from(v).unwrap())
289+
self.try_to_uint(Size::from_bits(64)).map(|v| u64::try_from(v).unwrap())
307290
}
308291

309292
/// Tries to convert the `ScalarInt` to `u128`. Fails if the `size` of the `ScalarInt`
310293
/// in not equal to `Size { raw: 16 }` and returns the `size` value of the `ScalarInt` in
311294
/// that case.
312295
#[inline]
313296
pub fn try_to_u128(self) -> Result<u128, Size> {
314-
self.to_bits(Size::from_bits(128))
297+
self.try_to_uint(Size::from_bits(128))
298+
}
299+
300+
#[inline]
301+
pub fn try_to_target_usize(&self, tcx: TyCtxt<'_>) -> Result<u64, Size> {
302+
self.try_to_uint(tcx.data_layout.pointer_size).map(|v| u64::try_from(v).unwrap())
303+
}
304+
305+
// Tries to convert the `ScalarInt` to `bool`. Fails if the `size` of the `ScalarInt`
306+
// in not equal to `Size { raw: 1 }` or if the value is not 0 or 1 and returns the `size`
307+
// value of the `ScalarInt` in that case.
308+
#[inline]
309+
pub fn try_to_bool(self) -> Result<bool, Size> {
310+
match self.try_to_u8()? {
311+
0 => Ok(false),
312+
1 => Ok(true),
313+
_ => Err(self.size()),
314+
}
315315
}
316316

317317
/// Tries to convert the `ScalarInt` to a signed integer of the given size.
@@ -357,6 +357,27 @@ impl ScalarInt {
357357
pub fn try_to_i128(self) -> Result<i128, Size> {
358358
self.try_to_int(Size::from_bits(128))
359359
}
360+
361+
#[inline]
362+
pub fn try_to_target_isize(&self, tcx: TyCtxt<'_>) -> Result<i64, Size> {
363+
self.try_to_int(tcx.data_layout.pointer_size).map(|v| i64::try_from(v).unwrap())
364+
}
365+
366+
#[inline]
367+
pub fn try_to_float<F: Float>(self) -> Result<F, Size> {
368+
// Going through `to_uint` to check size and truncation.
369+
Ok(F::from_bits(self.to_bits(Size::from_bits(F::BITS))?))
370+
}
371+
372+
#[inline]
373+
pub fn try_to_f32(self) -> Result<Single, Size> {
374+
self.try_to_float()
375+
}
376+
377+
#[inline]
378+
pub fn try_to_f64(self) -> Result<Double, Size> {
379+
self.try_to_float()
380+
}
360381
}
361382

362383
macro_rules! from {
@@ -399,11 +420,7 @@ impl TryFrom<ScalarInt> for bool {
399420
type Error = Size;
400421
#[inline]
401422
fn try_from(int: ScalarInt) -> Result<Self, Size> {
402-
int.to_bits(Size::from_bytes(1)).and_then(|u| match u {
403-
0 => Ok(false),
404-
1 => Ok(true),
405-
_ => Err(Size::from_bytes(1)),
406-
})
423+
int.try_to_bool()
407424
}
408425
}
409426

compiler/rustc_middle/src/ty/relate.rs

+8-2
Original file line numberDiff line numberDiff line change
@@ -435,7 +435,10 @@ pub fn structurally_relate_tys<'tcx, R: TypeRelation<'tcx>>(
435435
Ok(a)
436436
}
437437

438-
(ty::Param(a_p), ty::Param(b_p)) if a_p.index == b_p.index => Ok(a),
438+
(ty::Param(a_p), ty::Param(b_p)) if a_p.index == b_p.index => {
439+
debug_assert_eq!(a_p.name, b_p.name, "param types with same index differ in name");
440+
Ok(a)
441+
}
439442

440443
(ty::Placeholder(p1), ty::Placeholder(p2)) if p1 == p2 => Ok(a),
441444

@@ -586,7 +589,10 @@ pub fn structurally_relate_consts<'tcx, R: TypeRelation<'tcx>>(
586589
(ty::ConstKind::Error(_), _) => return Ok(a),
587590
(_, ty::ConstKind::Error(_)) => return Ok(b),
588591

589-
(ty::ConstKind::Param(a_p), ty::ConstKind::Param(b_p)) => a_p.index == b_p.index,
592+
(ty::ConstKind::Param(a_p), ty::ConstKind::Param(b_p)) if a_p.index == b_p.index => {
593+
debug_assert_eq!(a_p.name, b_p.name, "param types with same index differ in name");
594+
true
595+
}
590596
(ty::ConstKind::Placeholder(p1), ty::ConstKind::Placeholder(p2)) => p1 == p2,
591597
(ty::ConstKind::Value(a_val), ty::ConstKind::Value(b_val)) => a_val == b_val,
592598

compiler/rustc_mir_build/messages.ftl

+4-2
Original file line numberDiff line numberDiff line change
@@ -107,8 +107,6 @@ mir_build_extern_static_requires_unsafe_unsafe_op_in_unsafe_fn_allowed =
107107
.note = extern statics are not controlled by the Rust type system: invalid data, aliasing violations or data races will cause undefined behavior
108108
.label = use of extern static
109109
110-
mir_build_float_pattern = floating-point types cannot be used in patterns
111-
112110
mir_build_indirect_structural_match =
113111
to use a constant of type `{$non_sm_ty}` in a pattern, `{$non_sm_ty}` must be annotated with `#[derive(PartialEq)]`
114112
@@ -232,6 +230,10 @@ mir_build_mutation_of_layout_constrained_field_requires_unsafe_unsafe_op_in_unsa
232230
.note = mutating layout constrained fields cannot statically be checked for valid values
233231
.label = mutation of layout constrained field
234232
233+
mir_build_nan_pattern = cannot use NaN in patterns
234+
.note = NaNs compare inequal to everything, even themselves, so this pattern would never match
235+
.help = try using the `is_nan` method instead
236+
235237
mir_build_non_const_path = runtime values cannot be referenced in patterns
236238
237239
mir_build_non_empty_never_pattern =

compiler/rustc_mir_build/src/errors.rs

+8-3
Original file line numberDiff line numberDiff line change
@@ -780,9 +780,14 @@ pub struct UnsizedPattern<'tcx> {
780780
pub non_sm_ty: Ty<'tcx>,
781781
}
782782

783-
#[derive(LintDiagnostic)]
784-
#[diag(mir_build_float_pattern)]
785-
pub struct FloatPattern;
783+
#[derive(Diagnostic)]
784+
#[diag(mir_build_nan_pattern)]
785+
#[note]
786+
#[help]
787+
pub struct NaNPattern {
788+
#[primary_span]
789+
pub span: Span,
790+
}
786791

787792
#[derive(LintDiagnostic)]
788793
#[diag(mir_build_pointer_pattern)]

compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs

+18-11
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use rustc_apfloat::Float;
12
use rustc_hir as hir;
23
use rustc_hir::def_id::DefId;
34
use rustc_index::Idx;
@@ -16,7 +17,7 @@ use std::cell::Cell;
1617

1718
use super::PatCtxt;
1819
use crate::errors::{
19-
FloatPattern, IndirectStructuralMatch, InvalidPattern, NonPartialEqMatch,
20+
IndirectStructuralMatch, InvalidPattern, NaNPattern, NonPartialEqMatch,
2021
NontrivialStructuralMatch, PointerPattern, TypeNotStructural, UnionPattern, UnsizedPattern,
2122
};
2223

@@ -317,16 +318,6 @@ impl<'tcx> ConstToPat<'tcx> {
317318
let param_env = self.param_env;
318319

319320
let kind = match ty.kind() {
320-
ty::Float(_) => {
321-
self.saw_const_match_lint.set(true);
322-
tcx.emit_node_span_lint(
323-
lint::builtin::ILLEGAL_FLOATING_POINT_LITERAL_PATTERN,
324-
id,
325-
span,
326-
FloatPattern,
327-
);
328-
return Err(FallbackToOpaqueConst);
329-
}
330321
// If the type is not structurally comparable, just emit the constant directly,
331322
// causing the pattern match code to treat it opaquely.
332323
// FIXME: This code doesn't emit errors itself, the caller emits the errors.
@@ -486,6 +477,22 @@ impl<'tcx> ConstToPat<'tcx> {
486477
}
487478
}
488479
},
480+
ty::Float(flt) => {
481+
let v = cv.unwrap_leaf();
482+
let is_nan = match flt {
483+
ty::FloatTy::F32 => v.try_to_f32().unwrap().is_nan(),
484+
ty::FloatTy::F64 => v.try_to_f64().unwrap().is_nan(),
485+
};
486+
if is_nan {
487+
// NaNs are not ever equal to anything so they make no sense as patterns.
488+
// Also see <https://github.com/rust-lang/rfcs/pull/3535>.
489+
let e = tcx.dcx().emit_err(NaNPattern { span });
490+
self.saw_const_match_error.set(Some(e));
491+
return Err(FallbackToOpaqueConst);
492+
} else {
493+
PatKind::Constant { value: mir::Const::Ty(ty::Const::new_value(tcx, cv, ty)) }
494+
}
495+
}
489496
ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::RawPtr(..) => {
490497
// The raw pointers we see here have been "vetted" by valtree construction to be
491498
// just integers, so we simply allow them.

compiler/rustc_target/src/spec/targets/loongarch64_unknown_linux_gnu.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::spec::{base, Target, TargetOptions};
1+
use crate::spec::{base, CodeModel, Target, TargetOptions};
22

33
pub fn target() -> Target {
44
Target {
@@ -7,6 +7,7 @@ pub fn target() -> Target {
77
data_layout: "e-m:e-p:64:64-i64:64-i128:128-n64-S128".into(),
88
arch: "loongarch64".into(),
99
options: TargetOptions {
10+
code_model: Some(CodeModel::Medium),
1011
cpu: "generic".into(),
1112
features: "+f,+d".into(),
1213
llvm_abiname: "lp64d".into(),

0 commit comments

Comments
 (0)