Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

remove 'illegal_floating_point_literal_pattern' future-compat lint #116098

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: 4 additions & 0 deletions compiler/rustc_lint/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -505,6 +505,10 @@ fn register_builtins(store: &mut LintStore) {
"replaced with another group of lints, see RFC \
<https://rust-lang.github.io/rfcs/2145-type-privacy.html> for more information",
);
store.register_removed(
"illegal_floating_point_literal_pattern",
"no longer a warning, float patterns behave the same as `==`",
);
}

fn register_internals(store: &mut LintStore) {
Expand Down
27 changes: 3 additions & 24 deletions compiler/rustc_lint/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ use rustc_middle::ty::GenericArgsRef;
use rustc_middle::ty::{
self, AdtKind, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt,
};
use rustc_session::lint::builtin;
use rustc_span::def_id::LocalDefId;
use rustc_span::source_map;
use rustc_span::symbol::sym;
Expand Down Expand Up @@ -114,35 +115,13 @@ declare_lint! {
"detects enums with widely varying variant sizes"
}

declare_lint! {
/// The `invalid_nan_comparisons` lint checks comparison with `f32::NAN` or `f64::NAN`
/// as one of the operand.
///
/// ### Example
///
/// ```rust
/// let a = 2.3f32;
/// if a == f32::NAN {}
/// ```
///
/// {{produces}}
///
/// ### Explanation
///
/// NaN does not compare meaningfully to anything – not
/// even itself – so those comparisons are always false.
INVALID_NAN_COMPARISONS,
Warn,
"detects invalid floating point NaN comparisons"
}

#[derive(Copy, Clone)]
pub struct TypeLimits {
/// Id of the last visited negated expression
negated_expr_id: Option<hir::HirId>,
}

impl_lint_pass!(TypeLimits => [UNUSED_COMPARISONS, OVERFLOWING_LITERALS, INVALID_NAN_COMPARISONS]);
impl_lint_pass!(TypeLimits => [UNUSED_COMPARISONS, OVERFLOWING_LITERALS, builtin::INVALID_NAN_COMPARISONS]);

impl TypeLimits {
pub fn new() -> TypeLimits {
Expand Down Expand Up @@ -615,7 +594,7 @@ fn lint_nan<'tcx>(
_ => return,
};

cx.emit_spanned_lint(INVALID_NAN_COMPARISONS, e.span, lint);
cx.emit_spanned_lint(builtin::INVALID_NAN_COMPARISONS, e.span, lint);
}

impl<'tcx> LateLintPass<'tcx> for TypeLimits {
Expand Down
75 changes: 25 additions & 50 deletions compiler/rustc_lint_defs/src/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1754,55 +1754,6 @@ declare_lint! {
};
}

declare_lint! {
/// The `illegal_floating_point_literal_pattern` lint detects
/// floating-point literals used in patterns.
///
/// ### Example
///
/// ```rust
/// let x = 42.0;
///
/// match x {
/// 5.0 => {}
/// _ => {}
/// }
/// ```
///
/// {{produces}}
///
/// ### Explanation
///
/// Previous versions of the compiler accepted floating-point literals in
/// patterns, but it was later determined this was a mistake. The
/// semantics of comparing floating-point values may not be clear in a
/// pattern when contrasted with "structural equality". Typically you can
/// work around this by using a [match guard], such as:
///
/// ```rust
/// # let x = 42.0;
///
/// match x {
/// y if y == 5.0 => {}
/// _ => {}
/// }
/// ```
///
/// This is a [future-incompatible] lint to transition this to a hard
/// error in the future. See [issue #41620] for more details.
///
/// [issue #41620]: https://github.com/rust-lang/rust/issues/41620
/// [match guard]: https://doc.rust-lang.org/reference/expressions/match-expr.html#match-guards
/// [future-incompatible]: ../index.md#future-incompatible-lints
pub ILLEGAL_FLOATING_POINT_LITERAL_PATTERN,
Warn,
"floating-point literals cannot be used in patterns",
@future_incompatible = FutureIncompatibleInfo {
reason: FutureIncompatibilityReason::FutureReleaseErrorDontReportInDeps,
reference: "issue #41620 <https://github.com/rust-lang/rust/issues/41620>",
};
}

declare_lint! {
/// The `unstable_name_collisions` lint detects that you have used a name
/// that the standard library plans to add in the future.
Expand Down Expand Up @@ -3334,6 +3285,31 @@ declare_lint! {
"name introduced by a private item shadows a name introduced by a public glob re-export",
}

declare_lint! {
/// The `invalid_nan_comparisons` lint checks comparison with `f32::NAN` or `f64::NAN`
/// as one of the operand.
///
/// ### Example
///
/// ```rust
/// let a = 2.3f32;
/// if a == f32::NAN {}
/// if matches!(a, f32::NAN) {}
/// ```
///
/// {{produces}}
///
/// ### Explanation
///
/// NaN does not compare meaningfully to anything – not
/// even itself – so those comparisons are always false.
pub INVALID_NAN_COMPARISONS,
Warn,
"detects invalid floating point NaN comparisons"
}

// When removing any lint here, remember to add a call to `register_removed` in `fn
// register_builtins` in the `rustc_lints` crate.
declare_lint_pass! {
/// Does nothing as a lint pass, but registers some `Lint`s
/// that are used by other parts of the compiler.
Expand Down Expand Up @@ -3371,7 +3347,6 @@ declare_lint_pass! {
FUZZY_PROVENANCE_CASTS,
HIDDEN_GLOB_REEXPORTS,
ILL_FORMED_ATTRIBUTE_INPUT,
ILLEGAL_FLOATING_POINT_LITERAL_PATTERN,
IMPLIED_BOUNDS_ENTAILMENT,
INCOMPLETE_INCLUDE,
INDIRECT_STRUCTURAL_MATCH,
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_mir_build/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,6 @@ mir_build_extern_static_requires_unsafe_unsafe_op_in_unsafe_fn_allowed =
.note = extern statics are not controlled by the Rust type system: invalid data, aliasing violations or data races will cause undefined behavior
.label = use of extern static

mir_build_float_pattern = floating-point types cannot be used in patterns

mir_build_indirect_structural_match =
to use a constant of type `{$non_sm_ty}` in a pattern, `{$non_sm_ty}` must be annotated with `#[derive(PartialEq, Eq)]`

Expand Down Expand Up @@ -212,6 +210,8 @@ mir_build_mutation_of_layout_constrained_field_requires_unsafe_unsafe_op_in_unsa
.note = mutating layout constrained fields cannot statically be checked for valid values
.label = mutation of layout constrained field

mir_build_nan_pattern = incorrect NaN comparison, NaN cannot be directly compared to itself

mir_build_non_const_path = runtime values cannot be referenced in patterns

mir_build_non_exhaustive_match_all_arms_guarded =
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_mir_build/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -725,8 +725,8 @@ pub struct UnsizedPattern<'tcx> {
}

#[derive(LintDiagnostic)]
#[diag(mir_build_float_pattern)]
pub struct FloatPattern;
#[diag(mir_build_nan_pattern)]
pub struct NaNPattern;

#[derive(LintDiagnostic)]
#[diag(mir_build_pointer_pattern)]
Expand Down
33 changes: 21 additions & 12 deletions compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ use std::cell::Cell;

use super::PatCtxt;
use crate::errors::{
FloatPattern, IndirectStructuralMatch, InvalidPattern, NontrivialStructuralMatch,
PointerPattern, TypeNotStructural, UnionPattern, UnsizedPattern,
IndirectStructuralMatch, InvalidPattern, NaNPattern, NontrivialStructuralMatch, PointerPattern,
TypeNotStructural, UnionPattern, UnsizedPattern,
};

impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
Expand Down Expand Up @@ -291,16 +291,6 @@ impl<'tcx> ConstToPat<'tcx> {
let param_env = self.param_env;

let kind = match ty.kind() {
ty::Float(_) => {
self.saw_const_match_lint.set(true);
tcx.emit_spanned_lint(
lint::builtin::ILLEGAL_FLOATING_POINT_LITERAL_PATTERN,
id,
span,
FloatPattern,
);
return Err(FallbackToConstRef);
}
// If the type is not structurally comparable, just emit the constant directly,
// causing the pattern match code to treat it opaquely.
// FIXME: This code doesn't emit errors itself, the caller emits the errors.
Expand Down Expand Up @@ -445,6 +435,25 @@ impl<'tcx> ConstToPat<'tcx> {
}
}
},
ty::Float(fty) => {
// FIXME: Can this be done in a separate lint pass, rather than in the middle of
// const-to-pat conversion?
let val = cv.unwrap_leaf();
let is_nan = match fty {
// FIXME: Do this without host floats.
ty::FloatTy::F32 => f32::from_bits(val.try_to_u32().unwrap()).is_nan(),
ty::FloatTy::F64 => f64::from_bits(val.try_to_u64().unwrap()).is_nan(),
};
if is_nan {
tcx.emit_spanned_lint(
lint::builtin::INVALID_NAN_COMPARISONS,
id,
span,
NaNPattern,
);
}
PatKind::Constant { value: mir::Const::Ty(ty::Const::new_value(tcx, cv, ty)) }
}
ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) => {
PatKind::Constant { value: mir::Const::Ty(ty::Const::new_value(tcx, cv, ty)) }
}
Expand Down
16 changes: 4 additions & 12 deletions src/tools/clippy/tests/ui/expect_tool_lint_rfc_2383.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,8 @@ mod rustc_ok {
pub fn rustc_lints() {
let x = 42.0;

#[expect(illegal_floating_point_literal_pattern)]
match x {
5.0 => {}
6.0 => {}
_ => {}
}
#[expect(invalid_nan_comparisons)]
let _b = x == f32::NAN;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried to keep this the same as the other copies of the file, but the clippy test is somehow different, ad that doesn't work. It says rustfix failed. I didn't see any other useful information, I just did random mutation of the test file until the clippy test suite passed...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks fine to me. The purpose of this test is to check the expect attribute, which lint the test expects shouldn't really matter.

}
}

Expand All @@ -38,13 +34,9 @@ mod rustc_warn {
pub fn rustc_lints() {
let x = 42;

#[expect(illegal_floating_point_literal_pattern)]
#[expect(invalid_nan_comparisons)]
//~^ ERROR: this lint expectation is unfulfilled
match x {
5 => {}
6 => {}
_ => {}
}
let _b = x == 5;
}
}

Expand Down
16 changes: 8 additions & 8 deletions src/tools/clippy/tests/ui/expect_tool_lint_rfc_2383.stderr
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
error: this lint expectation is unfulfilled
--> $DIR/expect_tool_lint_rfc_2383.rs:35:14
--> $DIR/expect_tool_lint_rfc_2383.rs:31:14
|
LL | #[expect(dead_code)]
| ^^^^^^^^^
Expand All @@ -8,31 +8,31 @@ LL | #[expect(dead_code)]
= help: to override `-D warnings` add `#[allow(unfulfilled_lint_expectations)]`

error: this lint expectation is unfulfilled
--> $DIR/expect_tool_lint_rfc_2383.rs:41:18
--> $DIR/expect_tool_lint_rfc_2383.rs:37:18
|
LL | #[expect(illegal_floating_point_literal_pattern)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL | #[expect(invalid_nan_comparisons)]
| ^^^^^^^^^^^^^^^^^^^^^^^

error: this lint expectation is unfulfilled
--> $DIR/expect_tool_lint_rfc_2383.rs:116:14
--> $DIR/expect_tool_lint_rfc_2383.rs:108:14
|
LL | #[expect(clippy::almost_swapped)]
| ^^^^^^^^^^^^^^^^^^^^^^

error: this lint expectation is unfulfilled
--> $DIR/expect_tool_lint_rfc_2383.rs:124:14
--> $DIR/expect_tool_lint_rfc_2383.rs:116:14
|
LL | #[expect(clippy::bytes_nth)]
| ^^^^^^^^^^^^^^^^^

error: this lint expectation is unfulfilled
--> $DIR/expect_tool_lint_rfc_2383.rs:130:14
--> $DIR/expect_tool_lint_rfc_2383.rs:122:14
|
LL | #[expect(clippy::if_same_then_else)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^

error: this lint expectation is unfulfilled
--> $DIR/expect_tool_lint_rfc_2383.rs:136:14
--> $DIR/expect_tool_lint_rfc_2383.rs:128:14
|
LL | #[expect(clippy::overly_complex_bool_expr)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Expand Down
7 changes: 3 additions & 4 deletions tests/rustdoc-ui/lints/expect-tool-lint-rfc-2383.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,9 @@ mod rustc_ok {
pub fn rustc_lints() {
let x = 42.0;

#[expect(illegal_floating_point_literal_pattern)]
#[expect(invalid_nan_comparisons)]
match x {
5.0 => {}
6.0 => {}
f32::NAN => {}
_ => {}
}
}
Expand All @@ -40,7 +39,7 @@ mod rustc_warn {
pub fn rustc_lints() {
let x = 42;

#[expect(illegal_floating_point_literal_pattern)]
#[expect(invalid_nan_comparisons)]
match x {
5 => {}
6 => {}
Expand Down
6 changes: 3 additions & 3 deletions tests/rustdoc-ui/lints/expect-tool-lint-rfc-2383.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,19 @@ LL | #![expect(rustdoc::missing_crate_level_docs)]
= note: `#[warn(unfulfilled_lint_expectations)]` on by default

warning: this lint expectation is unfulfilled
--> $DIR/expect-tool-lint-rfc-2383.rs:71:14
--> $DIR/expect-tool-lint-rfc-2383.rs:70:14
|
LL | #[expect(rustdoc::broken_intra_doc_links)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

warning: this lint expectation is unfulfilled
--> $DIR/expect-tool-lint-rfc-2383.rs:76:14
--> $DIR/expect-tool-lint-rfc-2383.rs:75:14
|
LL | #[expect(rustdoc::invalid_html_tags)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^

warning: this lint expectation is unfulfilled
--> $DIR/expect-tool-lint-rfc-2383.rs:81:14
--> $DIR/expect-tool-lint-rfc-2383.rs:80:14
|
LL | #[expect(rustdoc::bare_urls)]
| ^^^^^^^^^^^^^^^^^^
Expand Down
1 change: 0 additions & 1 deletion tests/ui/array-slice-vec/vec-matching-autoslice.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
// run-pass
#![allow(illegal_floating_point_literal_pattern)] // FIXME #41620

pub fn main() {
let x = [1, 2, 3];
Expand Down
1 change: 0 additions & 1 deletion tests/ui/binding/match-range.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
// run-pass
#![allow(illegal_floating_point_literal_pattern)] // FIXME #41620
#![feature(exclusive_range_pattern)]

pub fn main() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// Test various non-exhaustive matches for `X..`, `..=X` and `..X` ranges.

#![feature(exclusive_range_pattern)]
#![allow(illegal_floating_point_literal_pattern)]

fn main() {}

Expand Down
Loading
Loading