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

patterns: reject raw pointers that are not just integers #116930

Merged
merged 5 commits into from
Nov 8, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
22 changes: 9 additions & 13 deletions compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -239,19 +239,15 @@ impl<'tcx> ConstToPat<'tcx> {
}
}
} else if !self.saw_const_match_lint.get() {
match cv.ty().kind() {
ty::RawPtr(..) if have_valtree => {
// This is a good raw pointer, it was accepted by valtree construction.
}
ty::FnPtr(..) | ty::RawPtr(..) => {
self.tcx().emit_spanned_lint(
lint::builtin::POINTER_STRUCTURAL_MATCH,
self.id,
self.span,
PointerPattern,
);
}
_ => {}
if !have_valtree {
Copy link
Member

Choose a reason for hiding this comment

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

nit: could be part of the condition on the previous line

// 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_spanned_lint(
lint::builtin::POINTER_STRUCTURAL_MATCH,
self.id,
self.span,
PointerPattern,
);
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
#![deny(pointer_structural_match)]
#![allow(dead_code)]

const C: *const u8 = &0;
// Make sure we also find pointers nested in other types.
const C_INNER: (*const u8, u8) = (C, 0);

fn foo(x: *const u8) {
match x {
Expand All @@ -10,6 +13,14 @@ fn foo(x: *const u8) {
}
}

fn foo2(x: *const u8) {
match (x, 1) {
C_INNER => {} //~ERROR: behave unpredictably
//~| previously accepted
_ => {}
}
}

const D: *const [u8; 4] = b"abcd";

fn main() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
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:7:9
--> $DIR/issue-34784-match-on-non-int-raw-ptr.rs:10:9
|
LL | C => {}
| ^
Expand All @@ -13,13 +13,22 @@ 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:17:9
--> $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 #62411 <https://github.com/rust-lang/rust/issues/70861>

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:28: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 #62411 <https://github.com/rust-lang/rust/issues/70861>

error: aborting due to 2 previous errors
error: aborting due to 3 previous errors

Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,22 @@ fn my_fn(_args: &[A]) {
}

const TEST: Fn = my_fn;
const TEST2: (Fn, u8) = (TEST, 0);

struct B(Fn);

fn main() {
let s = B(my_fn);
match s {
B(TEST) => println!("matched"),
//~^ WARN behave unpredictably
//~^ WARN behave unpredictably
//~| WARN this was previously accepted by the compiler but is being phased out
_ => panic!("didn't match")
};
match (s.0, 0) {
TEST2 => println!("matched"),
//~^ WARN behave unpredictably
//~| WARN this was previously accepted by the compiler but is being phased out
_ => panic!("didn't match")
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
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-63479-match-fnptr.rs:35:7
--> $DIR/issue-63479-match-fnptr.rs:36:7
|
LL | B(TEST) => println!("matched"),
| ^^^^
Expand All @@ -12,5 +12,14 @@ note: the lint level is defined here
LL | #![warn(pointer_structural_match)]
| ^^^^^^^^^^^^^^^^^^^^^^^^

warning: 1 warning emitted
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-63479-match-fnptr.rs:42:5
|
LL | TEST2 => println!("matched"),
| ^^^^^
|
= 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 #62411 <https://github.com/rust-lang/rust/issues/70861>

warning: 2 warnings emitted