Skip to content

Commit

Permalink
remove 'illegal_floating_point_literal_pattern' future-compat lint
Browse files Browse the repository at this point in the history
  • Loading branch information
RalfJung committed Sep 24, 2023
1 parent bf98263 commit 405a1c3
Show file tree
Hide file tree
Showing 35 changed files with 213 additions and 469 deletions.
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;
}
}

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

0 comments on commit 405a1c3

Please sign in to comment.