Skip to content

Commit

Permalink
turn pointer_structural_match into a hard error
Browse files Browse the repository at this point in the history
  • Loading branch information
RalfJung committed May 3, 2024
1 parent 95133ec commit 6ef7b3c
Show file tree
Hide file tree
Showing 23 changed files with 131 additions and 811 deletions.
5 changes: 5 additions & 0 deletions compiler/rustc_lint/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -544,6 +544,11 @@ fn register_builtins(store: &mut LintStore) {
"converted into hard error, see RFC #3535 \
<https://rust-lang.github.io/rfcs/3535-constants-in-patterns.html> for more information",
);
store.register_removed(
"pointer_structural_match",
"converted into hard error, see RFC #3535 \
<https://rust-lang.github.io/rfcs/3535-constants-in-patterns.html> for more information",
);
}

fn register_internals(store: &mut LintStore) {
Expand Down
40 changes: 0 additions & 40 deletions compiler/rustc_lint_defs/src/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,6 @@ declare_lint_pass! {
ORDER_DEPENDENT_TRAIT_OBJECTS,
OVERLAPPING_RANGE_ENDPOINTS,
PATTERNS_IN_FNS_WITHOUT_BODY,
POINTER_STRUCTURAL_MATCH,
PRIVATE_BOUNDS,
PRIVATE_INTERFACES,
PROC_MACRO_BACK_COMPAT,
Expand Down Expand Up @@ -2371,45 +2370,6 @@ declare_lint! {
report_in_external_macro
}

declare_lint! {
/// The `pointer_structural_match` lint detects pointers used in patterns whose behaviour
/// cannot be relied upon across compiler versions and optimization levels.
///
/// ### Example
///
/// ```rust,compile_fail
/// #![deny(pointer_structural_match)]
/// fn foo(a: usize, b: usize) -> usize { a + b }
/// const FOO: fn(usize, usize) -> usize = foo;
/// fn main() {
/// match FOO {
/// FOO => {},
/// _ => {},
/// }
/// }
/// ```
///
/// {{produces}}
///
/// ### Explanation
///
/// Previous versions of Rust allowed function pointers and all raw pointers in patterns.
/// While these work in many cases as expected by users, it is possible that due to
/// optimizations pointers are "not equal to themselves" or pointers to different functions
/// compare as equal during runtime. This is because LLVM optimizations can deduplicate
/// functions if their bodies are the same, thus also making pointers to these functions point
/// to the same location. Additionally functions may get duplicated if they are instantiated
/// in different crates and not deduplicated again via LTO. Pointer identity for memory
/// created by `const` is similarly unreliable.
pub POINTER_STRUCTURAL_MATCH,
Warn,
"pointers are not structural-match",
@future_incompatible = FutureIncompatibleInfo {
reason: FutureIncompatibilityReason::FutureReleaseErrorReportInDeps,
reference: "issue #120362 <https://github.com/rust-lang/rust/issues/120362>",
};
}

declare_lint! {
/// The `ambiguous_associated_items` lint detects ambiguity between
/// [associated items] and [enum variants].
Expand Down
7 changes: 5 additions & 2 deletions compiler/rustc_mir_build/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -788,9 +788,12 @@ pub struct NaNPattern {
pub span: Span,
}

#[derive(LintDiagnostic)]
#[derive(Diagnostic)]
#[diag(mir_build_pointer_pattern)]
pub struct PointerPattern;
pub struct PointerPattern {
#[primary_span]
pub span: Span,
}

#[derive(Diagnostic)]
#[diag(mir_build_non_empty_never_pattern)]
Expand Down
10 changes: 3 additions & 7 deletions compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ use rustc_infer::traits::Obligation;
use rustc_middle::mir;
use rustc_middle::thir::{FieldPat, Pat, PatKind};
use rustc_middle::ty::{self, Ty, TyCtxt, ValTree};
use rustc_session::lint;
use rustc_span::{ErrorGuaranteed, Span};
use rustc_target::abi::{FieldIdx, VariantIdx};
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
Expand Down Expand Up @@ -189,12 +188,9 @@ impl<'tcx> ConstToPat<'tcx> {
} else if !have_valtree {
// The only way valtree construction can fail without the structural match
// checker finding a violation is if there is a pointer somewhere.
self.tcx().emit_node_span_lint(
lint::builtin::POINTER_STRUCTURAL_MATCH,
self.id,
self.span,
PointerPattern,
);
let e = self.tcx().dcx().emit_err(PointerPattern { span: self.span });
let kind = PatKind::Error(e);
return Box::new(Pat { span: self.span, ty: cv.ty(), kind });
}

// Always check for `PartialEq` if we had no other errors yet.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@
//@ edition:2021

const PATTERN_REF: &str = "Hello World";
const NUMBER: i32 = 30;
const NUMBER_POINTER: *const i32 = &NUMBER;
const NUMBER_POINTER: *const i32 = 30 as *const i32;

pub fn edge_case_ref(event: &str) {
let _ = || {
Expand All @@ -26,8 +25,7 @@ pub fn edge_case_str(event: String) {
pub fn edge_case_raw_ptr(event: *const i32) {
let _ = || {
match event {
NUMBER_POINTER => (), //~WARN behave unpredictably
//~| previously accepted
NUMBER_POINTER => (),
_ => (),
};
};
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
#![deny(pointer_structural_match)]
#![allow(dead_code)]

const C: *const u8 = &0;
Expand All @@ -8,15 +7,13 @@ const C_INNER: (*const u8, u8) = (C, 0);
fn foo(x: *const u8) {
match x {
C => {} //~ERROR: behave unpredictably
//~| previously accepted
_ => {}
}
}

fn foo2(x: *const u8) {
match (x, 1) {
C_INNER => {} //~ERROR: behave unpredictably
//~| previously accepted
_ => {}
}
}
Expand All @@ -28,13 +25,11 @@ const STR: *const str = "abcd";
fn main() {
match D {
D => {} //~ERROR: behave unpredictably
//~| previously accepted
_ => {}
}

match STR {
STR => {} //~ERROR: behave unpredictably
//~| previously accepted
_ => {}
}
}
Original file line number Diff line number Diff line change
@@ -1,103 +1,26 @@
error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
--> $DIR/issue-34784-match-on-non-int-raw-ptr.rs:10:9
--> $DIR/issue-34784-match-on-non-int-raw-ptr.rs:9:9
|
LL | C => {}
| ^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #120362 <https://github.com/rust-lang/rust/issues/120362>
note: the lint level is defined here
--> $DIR/issue-34784-match-on-non-int-raw-ptr.rs:1:9
|
LL | #![deny(pointer_structural_match)]
| ^^^^^^^^^^^^^^^^^^^^^^^^

error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
--> $DIR/issue-34784-match-on-non-int-raw-ptr.rs:18:9
--> $DIR/issue-34784-match-on-non-int-raw-ptr.rs:16:9
|
LL | C_INNER => {}
| ^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #120362 <https://github.com/rust-lang/rust/issues/120362>

error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
--> $DIR/issue-34784-match-on-non-int-raw-ptr.rs:30:9
--> $DIR/issue-34784-match-on-non-int-raw-ptr.rs:27:9
|
LL | D => {}
| ^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #120362 <https://github.com/rust-lang/rust/issues/120362>

error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
--> $DIR/issue-34784-match-on-non-int-raw-ptr.rs:36:9
--> $DIR/issue-34784-match-on-non-int-raw-ptr.rs:32:9
|
LL | STR => {}
| ^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #120362 <https://github.com/rust-lang/rust/issues/120362>

error: aborting due to 4 previous errors

Future incompatibility report: Future breakage diagnostic:
error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
--> $DIR/issue-34784-match-on-non-int-raw-ptr.rs:10:9
|
LL | C => {}
| ^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #120362 <https://github.com/rust-lang/rust/issues/120362>
note: the lint level is defined here
--> $DIR/issue-34784-match-on-non-int-raw-ptr.rs:1:9
|
LL | #![deny(pointer_structural_match)]
| ^^^^^^^^^^^^^^^^^^^^^^^^

Future breakage diagnostic:
error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
--> $DIR/issue-34784-match-on-non-int-raw-ptr.rs:18:9
|
LL | C_INNER => {}
| ^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #120362 <https://github.com/rust-lang/rust/issues/120362>
note: the lint level is defined here
--> $DIR/issue-34784-match-on-non-int-raw-ptr.rs:1:9
|
LL | #![deny(pointer_structural_match)]
| ^^^^^^^^^^^^^^^^^^^^^^^^

Future breakage diagnostic:
error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
--> $DIR/issue-34784-match-on-non-int-raw-ptr.rs:30:9
|
LL | D => {}
| ^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #120362 <https://github.com/rust-lang/rust/issues/120362>
note: the lint level is defined here
--> $DIR/issue-34784-match-on-non-int-raw-ptr.rs:1:9
|
LL | #![deny(pointer_structural_match)]
| ^^^^^^^^^^^^^^^^^^^^^^^^

Future breakage diagnostic:
error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
--> $DIR/issue-34784-match-on-non-int-raw-ptr.rs:36:9
|
LL | STR => {}
| ^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #120362 <https://github.com/rust-lang/rust/issues/120362>
note: the lint level is defined here
--> $DIR/issue-34784-match-on-non-int-raw-ptr.rs:1:9
|
LL | #![deny(pointer_structural_match)]
| ^^^^^^^^^^^^^^^^^^^^^^^^

10 changes: 2 additions & 8 deletions tests/ui/consts/const_in_pattern/issue-44333.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
//@ run-pass

#![warn(pointer_structural_match)]

type Func = fn(usize, usize) -> usize;

fn foo(a: usize, b: usize) -> usize { a + b }
Expand All @@ -16,10 +12,8 @@ const BAR: Func = bar;

fn main() {
match test(std::env::consts::ARCH.len()) {
FOO => println!("foo"), //~ WARN behave unpredictably
//~^ WARN will become a hard error
BAR => println!("bar"), //~ WARN behave unpredictably
//~^ WARN will become a hard error
FOO => println!("foo"), //~ ERROR behave unpredictably
BAR => println!("bar"), //~ ERROR behave unpredictably
_ => unreachable!(),
}
}
51 changes: 5 additions & 46 deletions tests/ui/consts/const_in_pattern/issue-44333.stderr
Original file line number Diff line number Diff line change
@@ -1,55 +1,14 @@
warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
--> $DIR/issue-44333.rs:19:9
error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
--> $DIR/issue-44333.rs:15:9
|
LL | FOO => println!("foo"),
| ^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #120362 <https://github.com/rust-lang/rust/issues/120362>
note: the lint level is defined here
--> $DIR/issue-44333.rs:3:9
|
LL | #![warn(pointer_structural_match)]
| ^^^^^^^^^^^^^^^^^^^^^^^^

warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
--> $DIR/issue-44333.rs:21:9
error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
--> $DIR/issue-44333.rs:16:9
|
LL | BAR => println!("bar"),
| ^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #120362 <https://github.com/rust-lang/rust/issues/120362>

warning: 2 warnings emitted

Future incompatibility report: Future breakage diagnostic:
warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
--> $DIR/issue-44333.rs:19:9
|
LL | FOO => println!("foo"),
| ^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #120362 <https://github.com/rust-lang/rust/issues/120362>
note: the lint level is defined here
--> $DIR/issue-44333.rs:3:9
|
LL | #![warn(pointer_structural_match)]
| ^^^^^^^^^^^^^^^^^^^^^^^^

Future breakage diagnostic:
warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
--> $DIR/issue-44333.rs:21:9
|
LL | BAR => println!("bar"),
| ^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #120362 <https://github.com/rust-lang/rust/issues/120362>
note: the lint level is defined here
--> $DIR/issue-44333.rs:3:9
|
LL | #![warn(pointer_structural_match)]
| ^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 2 previous errors

Loading

0 comments on commit 6ef7b3c

Please sign in to comment.