mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 14:55:26 +00:00
Auto merge of #116930 - RalfJung:raw-ptr-match, r=davidtwco
patterns: reject raw pointers that are not just integers Matching against `0 as *const i32` is fine, matching against `&42 as *const i32` is not. This extends the existing check against function pointers and wide pointers: we now uniformly reject all these pointer types during valtree construction, and then later lint because of that. See [here](https://github.com/rust-lang/rust/pull/116930#issuecomment-1784654073) for some more explanation and context. Also fixes https://github.com/rust-lang/rust/issues/116929. Cc `@oli-obk` `@lcnr`
This commit is contained in:
commit
fdaaaf9f92
@ -97,11 +97,27 @@ pub(crate) fn const_to_valtree_inner<'tcx>(
|
|||||||
Ok(ty::ValTree::Leaf(val.assert_int()))
|
Ok(ty::ValTree::Leaf(val.assert_int()))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Raw pointers are not allowed in type level constants, as we cannot properly test them for
|
ty::RawPtr(_) => {
|
||||||
// equality at compile-time (see `ptr_guaranteed_cmp`).
|
// Not all raw pointers are allowed, as we cannot properly test them for
|
||||||
|
// equality at compile-time (see `ptr_guaranteed_cmp`).
|
||||||
|
// However we allow those that are just integers in disguise.
|
||||||
|
// (We could allow wide raw pointers where both sides are integers in the future,
|
||||||
|
// but for now we reject them.)
|
||||||
|
let Ok(val) = ecx.read_scalar(place) else {
|
||||||
|
return Err(ValTreeCreationError::Other);
|
||||||
|
};
|
||||||
|
// We are in the CTFE machine, so ptr-to-int casts will fail.
|
||||||
|
// This can only be `Ok` if `val` already is an integer.
|
||||||
|
let Ok(val) = val.try_to_int() else {
|
||||||
|
return Err(ValTreeCreationError::Other);
|
||||||
|
};
|
||||||
|
// It's just a ScalarInt!
|
||||||
|
Ok(ty::ValTree::Leaf(val))
|
||||||
|
}
|
||||||
|
|
||||||
// Technically we could allow function pointers (represented as `ty::Instance`), but this is not guaranteed to
|
// Technically we could allow function pointers (represented as `ty::Instance`), but this is not guaranteed to
|
||||||
// agree with runtime equality tests.
|
// agree with runtime equality tests.
|
||||||
ty::FnPtr(_) | ty::RawPtr(_) => Err(ValTreeCreationError::NonSupportedType),
|
ty::FnPtr(_) => Err(ValTreeCreationError::NonSupportedType),
|
||||||
|
|
||||||
ty::Ref(_, _, _) => {
|
ty::Ref(_, _, _) => {
|
||||||
let Ok(derefd_place)= ecx.deref_pointer(place) else {
|
let Ok(derefd_place)= ecx.deref_pointer(place) else {
|
||||||
@ -222,12 +238,14 @@ pub fn valtree_to_const_value<'tcx>(
|
|||||||
assert!(valtree.unwrap_branch().is_empty());
|
assert!(valtree.unwrap_branch().is_empty());
|
||||||
mir::ConstValue::ZeroSized
|
mir::ConstValue::ZeroSized
|
||||||
}
|
}
|
||||||
ty::Bool | ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::Char => match valtree {
|
ty::Bool | ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::Char | ty::RawPtr(_) => {
|
||||||
ty::ValTree::Leaf(scalar_int) => mir::ConstValue::Scalar(Scalar::Int(scalar_int)),
|
match valtree {
|
||||||
ty::ValTree::Branch(_) => bug!(
|
ty::ValTree::Leaf(scalar_int) => mir::ConstValue::Scalar(Scalar::Int(scalar_int)),
|
||||||
"ValTrees for Bool, Int, Uint, Float or Char should have the form ValTree::Leaf"
|
ty::ValTree::Branch(_) => bug!(
|
||||||
),
|
"ValTrees for Bool, Int, Uint, Float, Char or RawPtr should have the form ValTree::Leaf"
|
||||||
},
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
ty::Ref(_, inner_ty, _) => {
|
ty::Ref(_, inner_ty, _) => {
|
||||||
let mut ecx = mk_eval_cx(tcx, DUMMY_SP, param_env, CanAccessStatics::No);
|
let mut ecx = mk_eval_cx(tcx, DUMMY_SP, param_env, CanAccessStatics::No);
|
||||||
let imm = valtree_to_ref(&mut ecx, valtree, *inner_ty);
|
let imm = valtree_to_ref(&mut ecx, valtree, *inner_ty);
|
||||||
@ -281,7 +299,6 @@ pub fn valtree_to_const_value<'tcx>(
|
|||||||
| ty::Coroutine(..)
|
| ty::Coroutine(..)
|
||||||
| ty::CoroutineWitness(..)
|
| ty::CoroutineWitness(..)
|
||||||
| ty::FnPtr(_)
|
| ty::FnPtr(_)
|
||||||
| ty::RawPtr(_)
|
|
||||||
| ty::Str
|
| ty::Str
|
||||||
| ty::Slice(_)
|
| ty::Slice(_)
|
||||||
| ty::Dynamic(..) => bug!("no ValTree should have been created for type {:?}", ty.kind()),
|
| ty::Dynamic(..) => bug!("no ValTree should have been created for type {:?}", ty.kind()),
|
||||||
|
@ -2217,15 +2217,16 @@ declare_lint! {
|
|||||||
///
|
///
|
||||||
/// ### Explanation
|
/// ### Explanation
|
||||||
///
|
///
|
||||||
/// Previous versions of Rust allowed function pointers and wide raw pointers in patterns.
|
/// 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
|
/// 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
|
/// optimizations pointers are "not equal to themselves" or pointers to different functions
|
||||||
/// compare as equal during runtime. This is because LLVM optimizations can deduplicate
|
/// 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
|
/// 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
|
/// to the same location. Additionally functions may get duplicated if they are instantiated
|
||||||
/// in different crates and not deduplicated again via LTO.
|
/// in different crates and not deduplicated again via LTO. Pointer identity for memory
|
||||||
|
/// created by `const` is similarly unreliable.
|
||||||
pub POINTER_STRUCTURAL_MATCH,
|
pub POINTER_STRUCTURAL_MATCH,
|
||||||
Allow,
|
Warn,
|
||||||
"pointers are not structural-match",
|
"pointers are not structural-match",
|
||||||
@future_incompatible = FutureIncompatibleInfo {
|
@future_incompatible = FutureIncompatibleInfo {
|
||||||
reason: FutureIncompatibilityReason::FutureReleaseErrorDontReportInDeps,
|
reason: FutureIncompatibilityReason::FutureReleaseErrorDontReportInDeps,
|
||||||
|
@ -247,7 +247,7 @@ mir_build_overlapping_range_endpoints = multiple patterns overlap on their endpo
|
|||||||
mir_build_pattern_not_covered = refutable pattern in {$origin}
|
mir_build_pattern_not_covered = refutable pattern in {$origin}
|
||||||
.pattern_ty = the matched value is of type `{$pattern_ty}`
|
.pattern_ty = the matched value is of type `{$pattern_ty}`
|
||||||
|
|
||||||
mir_build_pointer_pattern = function pointers and unsized pointers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
|
mir_build_pointer_pattern = 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.
|
||||||
|
|
||||||
mir_build_privately_uninhabited = pattern `{$witness_1}` is currently uninhabited, but this variant contains private fields which may become inhabited in the future
|
mir_build_privately_uninhabited = pattern `{$witness_1}` is currently uninhabited, but this variant contains private fields which may become inhabited in the future
|
||||||
|
|
||||||
|
@ -123,6 +123,8 @@ impl<'tcx> ConstToPat<'tcx> {
|
|||||||
});
|
});
|
||||||
debug!(?check_body_for_struct_match_violation, ?mir_structural_match_violation);
|
debug!(?check_body_for_struct_match_violation, ?mir_structural_match_violation);
|
||||||
|
|
||||||
|
let have_valtree =
|
||||||
|
matches!(cv, mir::Const::Ty(c) if matches!(c.kind(), ty::ConstKind::Value(_)));
|
||||||
let inlined_const_as_pat = match cv {
|
let inlined_const_as_pat = match cv {
|
||||||
mir::Const::Ty(c) => match c.kind() {
|
mir::Const::Ty(c) => match c.kind() {
|
||||||
ty::ConstKind::Param(_)
|
ty::ConstKind::Param(_)
|
||||||
@ -209,16 +211,6 @@ impl<'tcx> ConstToPat<'tcx> {
|
|||||||
} else if !self.saw_const_match_lint.get() {
|
} else if !self.saw_const_match_lint.get() {
|
||||||
if let Some(mir_structural_match_violation) = mir_structural_match_violation {
|
if let Some(mir_structural_match_violation) = mir_structural_match_violation {
|
||||||
match non_sm_ty.kind() {
|
match non_sm_ty.kind() {
|
||||||
ty::RawPtr(pointee)
|
|
||||||
if pointee.ty.is_sized(self.tcx(), self.param_env) => {}
|
|
||||||
ty::FnPtr(..) | ty::RawPtr(..) => {
|
|
||||||
self.tcx().emit_spanned_lint(
|
|
||||||
lint::builtin::POINTER_STRUCTURAL_MATCH,
|
|
||||||
self.id,
|
|
||||||
self.span,
|
|
||||||
PointerPattern,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
ty::Adt(..) if mir_structural_match_violation => {
|
ty::Adt(..) if mir_structural_match_violation => {
|
||||||
self.tcx().emit_spanned_lint(
|
self.tcx().emit_spanned_lint(
|
||||||
lint::builtin::INDIRECT_STRUCTURAL_MATCH,
|
lint::builtin::INDIRECT_STRUCTURAL_MATCH,
|
||||||
@ -236,19 +228,15 @@ impl<'tcx> ConstToPat<'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if !self.saw_const_match_lint.get() {
|
} else if !have_valtree && !self.saw_const_match_lint.get() {
|
||||||
match cv.ty().kind() {
|
// The only way valtree construction can fail without the structural match
|
||||||
ty::RawPtr(pointee) if pointee.ty.is_sized(self.tcx(), self.param_env) => {}
|
// checker finding a violation is if there is a pointer somewhere.
|
||||||
ty::FnPtr(..) | ty::RawPtr(..) => {
|
self.tcx().emit_spanned_lint(
|
||||||
self.tcx().emit_spanned_lint(
|
lint::builtin::POINTER_STRUCTURAL_MATCH,
|
||||||
lint::builtin::POINTER_STRUCTURAL_MATCH,
|
self.id,
|
||||||
self.id,
|
self.span,
|
||||||
self.span,
|
PointerPattern,
|
||||||
PointerPattern,
|
);
|
||||||
);
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Always check for `PartialEq`, even if we emitted other lints. (But not if there were
|
// Always check for `PartialEq`, even if we emitted other lints. (But not if there were
|
||||||
@ -389,11 +377,19 @@ impl<'tcx> ConstToPat<'tcx> {
|
|||||||
subpatterns: self
|
subpatterns: self
|
||||||
.field_pats(cv.unwrap_branch().iter().copied().zip(fields.iter()))?,
|
.field_pats(cv.unwrap_branch().iter().copied().zip(fields.iter()))?,
|
||||||
},
|
},
|
||||||
ty::Adt(def, args) => PatKind::Leaf {
|
ty::Adt(def, args) => {
|
||||||
subpatterns: self.field_pats(cv.unwrap_branch().iter().copied().zip(
|
assert!(!def.is_union()); // Valtree construction would never succeed for unions.
|
||||||
def.non_enum_variant().fields.iter().map(|field| field.ty(self.tcx(), args)),
|
PatKind::Leaf {
|
||||||
))?,
|
subpatterns: self.field_pats(
|
||||||
},
|
cv.unwrap_branch().iter().copied().zip(
|
||||||
|
def.non_enum_variant()
|
||||||
|
.fields
|
||||||
|
.iter()
|
||||||
|
.map(|field| field.ty(self.tcx(), args)),
|
||||||
|
),
|
||||||
|
)?,
|
||||||
|
}
|
||||||
|
}
|
||||||
ty::Slice(elem_ty) => PatKind::Slice {
|
ty::Slice(elem_ty) => PatKind::Slice {
|
||||||
prefix: cv
|
prefix: cv
|
||||||
.unwrap_branch()
|
.unwrap_branch()
|
||||||
@ -480,10 +476,15 @@ impl<'tcx> ConstToPat<'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) => {
|
ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::RawPtr(..) => {
|
||||||
|
// The raw pointers we see here have been "vetted" by valtree construction to be
|
||||||
|
// just integers, so we simply allow them.
|
||||||
PatKind::Constant { value: mir::Const::Ty(ty::Const::new_value(tcx, cv, ty)) }
|
PatKind::Constant { value: mir::Const::Ty(ty::Const::new_value(tcx, cv, ty)) }
|
||||||
}
|
}
|
||||||
ty::FnPtr(..) | ty::RawPtr(..) => unreachable!(),
|
ty::FnPtr(..) => {
|
||||||
|
// Valtree construction would never succeed for these, so this is unreachable.
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
_ => {
|
_ => {
|
||||||
let err = InvalidPattern { span, non_sm_ty: ty };
|
let err = InvalidPattern { span, non_sm_ty: ty };
|
||||||
let e = tcx.sess.emit_err(err);
|
let e = tcx.sess.emit_err(err);
|
||||||
|
@ -253,6 +253,7 @@ marker_impls! {
|
|||||||
///
|
///
|
||||||
/// const CFN: Wrap<fn(&())> = Wrap(higher_order);
|
/// const CFN: Wrap<fn(&())> = Wrap(higher_order);
|
||||||
///
|
///
|
||||||
|
/// #[allow(pointer_structural_match)]
|
||||||
/// fn main() {
|
/// fn main() {
|
||||||
/// match CFN {
|
/// match CFN {
|
||||||
/// CFN => {}
|
/// CFN => {}
|
||||||
|
@ -26,7 +26,8 @@ pub fn edge_case_str(event: String) {
|
|||||||
pub fn edge_case_raw_ptr(event: *const i32) {
|
pub fn edge_case_raw_ptr(event: *const i32) {
|
||||||
let _ = || {
|
let _ = || {
|
||||||
match event {
|
match event {
|
||||||
NUMBER_POINTER => (),
|
NUMBER_POINTER => (), //~WARN behave unpredictably
|
||||||
|
//~| previously accepted
|
||||||
_ => (),
|
_ => (),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -0,0 +1,12 @@
|
|||||||
|
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/match-edge-cases_1.rs:29:13
|
||||||
|
|
|
||||||
|
LL | NUMBER_POINTER => (),
|
||||||
|
| ^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= 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>
|
||||||
|
= note: `#[warn(pointer_structural_match)]` on by default
|
||||||
|
|
||||||
|
warning: 1 warning emitted
|
||||||
|
|
@ -0,0 +1,32 @@
|
|||||||
|
#![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 {
|
||||||
|
C => {} //~ERROR: behave unpredictably
|
||||||
|
//~| previously accepted
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn foo2(x: *const u8) {
|
||||||
|
match (x, 1) {
|
||||||
|
C_INNER => {} //~ERROR: behave unpredictably
|
||||||
|
//~| previously accepted
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const D: *const [u8; 4] = b"abcd";
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
match D {
|
||||||
|
D => {} //~ERROR: behave unpredictably
|
||||||
|
//~| previously accepted
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,34 @@
|
|||||||
|
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 #62411 <https://github.com/rust-lang/rust/issues/70861>
|
||||||
|
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
|
||||||
|
|
|
||||||
|
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 3 previous errors
|
||||||
|
|
@ -16,9 +16,9 @@ const BAR: Func = bar;
|
|||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
match test(std::env::consts::ARCH.len()) {
|
match test(std::env::consts::ARCH.len()) {
|
||||||
FOO => println!("foo"), //~ WARN pointers in patterns behave unpredictably
|
FOO => println!("foo"), //~ WARN behave unpredictably
|
||||||
//~^ WARN will become a hard error
|
//~^ WARN will become a hard error
|
||||||
BAR => println!("bar"), //~ WARN pointers in patterns behave unpredictably
|
BAR => println!("bar"), //~ WARN behave unpredictably
|
||||||
//~^ WARN will become a hard error
|
//~^ WARN will become a hard error
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
warning: function pointers and unsized pointers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
|
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
|
--> $DIR/issue-44333.rs:19:9
|
||||||
|
|
|
|
||||||
LL | FOO => println!("foo"),
|
LL | FOO => println!("foo"),
|
||||||
@ -12,7 +12,7 @@ note: the lint level is defined here
|
|||||||
LL | #![warn(pointer_structural_match)]
|
LL | #![warn(pointer_structural_match)]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
warning: function pointers and unsized pointers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
|
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
|
--> $DIR/issue-44333.rs:21:9
|
||||||
|
|
|
|
||||||
LL | BAR => println!("bar"),
|
LL | BAR => println!("bar"),
|
||||||
|
@ -1,21 +0,0 @@
|
|||||||
// run-pass
|
|
||||||
|
|
||||||
#![warn(pointer_structural_match)]
|
|
||||||
#![allow(dead_code)]
|
|
||||||
const C: *const u8 = &0;
|
|
||||||
|
|
||||||
fn foo(x: *const u8) {
|
|
||||||
match x {
|
|
||||||
C => {}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const D: *const [u8; 4] = b"abcd";
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
match D {
|
|
||||||
D => {}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
|
@ -95,8 +95,10 @@ fn main() {
|
|||||||
const QUUX: Quux = quux;
|
const QUUX: Quux = quux;
|
||||||
|
|
||||||
match QUUX {
|
match QUUX {
|
||||||
QUUX => {}
|
QUUX => {} //~WARN behave unpredictably
|
||||||
QUUX => {}
|
//~| previously accepted
|
||||||
|
QUUX => {} //~WARN behave unpredictably
|
||||||
|
//~| previously accepted
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -105,14 +107,17 @@ fn main() {
|
|||||||
const WRAPQUUX: Wrap<Quux> = Wrap(quux);
|
const WRAPQUUX: Wrap<Quux> = Wrap(quux);
|
||||||
|
|
||||||
match WRAPQUUX {
|
match WRAPQUUX {
|
||||||
WRAPQUUX => {}
|
WRAPQUUX => {} //~WARN behave unpredictably
|
||||||
WRAPQUUX => {}
|
//~| previously accepted
|
||||||
|
WRAPQUUX => {} //~WARN behave unpredictably
|
||||||
|
//~| previously accepted
|
||||||
Wrap(_) => {}
|
Wrap(_) => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
match WRAPQUUX {
|
match WRAPQUUX {
|
||||||
Wrap(_) => {}
|
Wrap(_) => {}
|
||||||
WRAPQUUX => {}
|
WRAPQUUX => {} //~WARN behave unpredictably
|
||||||
|
//~| previously accepted
|
||||||
}
|
}
|
||||||
|
|
||||||
match WRAPQUUX {
|
match WRAPQUUX {
|
||||||
@ -121,7 +126,8 @@ fn main() {
|
|||||||
|
|
||||||
match WRAPQUUX {
|
match WRAPQUUX {
|
||||||
//~^ ERROR: non-exhaustive patterns: `Wrap(_)` not covered
|
//~^ ERROR: non-exhaustive patterns: `Wrap(_)` not covered
|
||||||
WRAPQUUX => {}
|
WRAPQUUX => {} //~WARN behave unpredictably
|
||||||
|
//~| previously accepted
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Eq)]
|
#[derive(PartialEq, Eq)]
|
||||||
@ -132,9 +138,11 @@ fn main() {
|
|||||||
const WHOKNOWSQUUX: WhoKnows<Quux> = WhoKnows::Yay(quux);
|
const WHOKNOWSQUUX: WhoKnows<Quux> = WhoKnows::Yay(quux);
|
||||||
|
|
||||||
match WHOKNOWSQUUX {
|
match WHOKNOWSQUUX {
|
||||||
WHOKNOWSQUUX => {}
|
WHOKNOWSQUUX => {} //~WARN behave unpredictably
|
||||||
|
//~| previously accepted
|
||||||
WhoKnows::Yay(_) => {}
|
WhoKnows::Yay(_) => {}
|
||||||
WHOKNOWSQUUX => {}
|
WHOKNOWSQUUX => {} //~WARN behave unpredictably
|
||||||
|
//~| previously accepted
|
||||||
WhoKnows::Nope => {}
|
WhoKnows::Nope => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -91,24 +91,96 @@ LL | BAZ => {}
|
|||||||
= note: the traits must be derived, manual `impl`s are not sufficient
|
= note: the traits must be derived, manual `impl`s are not sufficient
|
||||||
= note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details
|
= note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details
|
||||||
|
|
||||||
|
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/consts-opaque.rs:98:9
|
||||||
|
|
|
||||||
|
LL | QUUX => {}
|
||||||
|
| ^^^^
|
||||||
|
|
|
||||||
|
= 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>
|
||||||
|
= note: `#[warn(pointer_structural_match)]` on by default
|
||||||
|
|
||||||
|
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/consts-opaque.rs:100:9
|
||||||
|
|
|
||||||
|
LL | QUUX => {}
|
||||||
|
| ^^^^
|
||||||
|
|
|
||||||
|
= 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: 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/consts-opaque.rs:110:9
|
||||||
|
|
|
||||||
|
LL | WRAPQUUX => {}
|
||||||
|
| ^^^^^^^^
|
||||||
|
|
|
||||||
|
= 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: 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/consts-opaque.rs:112:9
|
||||||
|
|
|
||||||
|
LL | WRAPQUUX => {}
|
||||||
|
| ^^^^^^^^
|
||||||
|
|
|
||||||
|
= 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: 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/consts-opaque.rs:119:9
|
||||||
|
|
|
||||||
|
LL | WRAPQUUX => {}
|
||||||
|
| ^^^^^^^^
|
||||||
|
|
|
||||||
|
= 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: 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/consts-opaque.rs:129:9
|
||||||
|
|
|
||||||
|
LL | WRAPQUUX => {}
|
||||||
|
| ^^^^^^^^
|
||||||
|
|
|
||||||
|
= 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: 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/consts-opaque.rs:141:9
|
||||||
|
|
|
||||||
|
LL | WHOKNOWSQUUX => {}
|
||||||
|
| ^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= 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: 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/consts-opaque.rs:144:9
|
||||||
|
|
|
||||||
|
LL | WHOKNOWSQUUX => {}
|
||||||
|
| ^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= 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[E0004]: non-exhaustive patterns: `Wrap(_)` not covered
|
error[E0004]: non-exhaustive patterns: `Wrap(_)` not covered
|
||||||
--> $DIR/consts-opaque.rs:122:11
|
--> $DIR/consts-opaque.rs:127:11
|
||||||
|
|
|
|
||||||
LL | match WRAPQUUX {
|
LL | match WRAPQUUX {
|
||||||
| ^^^^^^^^ pattern `Wrap(_)` not covered
|
| ^^^^^^^^ pattern `Wrap(_)` not covered
|
||||||
|
|
|
|
||||||
note: `Wrap<fn(usize, usize) -> usize>` defined here
|
note: `Wrap<fn(usize, usize) -> usize>` defined here
|
||||||
--> $DIR/consts-opaque.rs:104:12
|
--> $DIR/consts-opaque.rs:106:12
|
||||||
|
|
|
|
||||||
LL | struct Wrap<T>(T);
|
LL | struct Wrap<T>(T);
|
||||||
| ^^^^
|
| ^^^^
|
||||||
= note: the matched value is of type `Wrap<fn(usize, usize) -> usize>`
|
= note: the matched value is of type `Wrap<fn(usize, usize) -> usize>`
|
||||||
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
||||||
|
|
|
|
||||||
LL ~ WRAPQUUX => {},
|
LL | WRAPQUUX => {}, Wrap(_) => todo!()
|
||||||
LL + Wrap(_) => todo!()
|
| ++++++++++++++++++++
|
||||||
|
|
|
||||||
|
|
||||||
error: aborting due to 10 previous errors; 1 warning emitted
|
error: aborting due to 10 previous errors; 9 warnings emitted
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0004`.
|
For more information about this error, try `rustc --explain E0004`.
|
||||||
|
@ -40,7 +40,8 @@ fn main() {
|
|||||||
const CFN1: Wrap<fn()> = Wrap(trivial);
|
const CFN1: Wrap<fn()> = Wrap(trivial);
|
||||||
let input: Wrap<fn()> = Wrap(trivial);
|
let input: Wrap<fn()> = Wrap(trivial);
|
||||||
match Wrap(input) {
|
match Wrap(input) {
|
||||||
Wrap(CFN1) => count += 1,
|
Wrap(CFN1) => count += 1, //~WARN behave unpredictably
|
||||||
|
//~| previously accepted
|
||||||
Wrap(_) => {}
|
Wrap(_) => {}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -48,7 +49,8 @@ fn main() {
|
|||||||
const CFN2: Wrap<fn(SM)> = Wrap(sm_to);
|
const CFN2: Wrap<fn(SM)> = Wrap(sm_to);
|
||||||
let input: Wrap<fn(SM)> = Wrap(sm_to);
|
let input: Wrap<fn(SM)> = Wrap(sm_to);
|
||||||
match Wrap(input) {
|
match Wrap(input) {
|
||||||
Wrap(CFN2) => count += 1,
|
Wrap(CFN2) => count += 1, //~WARN behave unpredictably
|
||||||
|
//~| previously accepted
|
||||||
Wrap(_) => {}
|
Wrap(_) => {}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -56,7 +58,8 @@ fn main() {
|
|||||||
const CFN3: Wrap<fn() -> SM> = Wrap(to_sm);
|
const CFN3: Wrap<fn() -> SM> = Wrap(to_sm);
|
||||||
let input: Wrap<fn() -> SM> = Wrap(to_sm);
|
let input: Wrap<fn() -> SM> = Wrap(to_sm);
|
||||||
match Wrap(input) {
|
match Wrap(input) {
|
||||||
Wrap(CFN3) => count += 1,
|
Wrap(CFN3) => count += 1, //~WARN behave unpredictably
|
||||||
|
//~| previously accepted
|
||||||
Wrap(_) => {}
|
Wrap(_) => {}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -64,7 +67,8 @@ fn main() {
|
|||||||
const CFN4: Wrap<fn(NotSM)> = Wrap(not_sm_to);
|
const CFN4: Wrap<fn(NotSM)> = Wrap(not_sm_to);
|
||||||
let input: Wrap<fn(NotSM)> = Wrap(not_sm_to);
|
let input: Wrap<fn(NotSM)> = Wrap(not_sm_to);
|
||||||
match Wrap(input) {
|
match Wrap(input) {
|
||||||
Wrap(CFN4) => count += 1,
|
Wrap(CFN4) => count += 1, //~WARN behave unpredictably
|
||||||
|
//~| previously accepted
|
||||||
Wrap(_) => {}
|
Wrap(_) => {}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -72,7 +76,8 @@ fn main() {
|
|||||||
const CFN5: Wrap<fn() -> NotSM> = Wrap(to_not_sm);
|
const CFN5: Wrap<fn() -> NotSM> = Wrap(to_not_sm);
|
||||||
let input: Wrap<fn() -> NotSM> = Wrap(to_not_sm);
|
let input: Wrap<fn() -> NotSM> = Wrap(to_not_sm);
|
||||||
match Wrap(input) {
|
match Wrap(input) {
|
||||||
Wrap(CFN5) => count += 1,
|
Wrap(CFN5) => count += 1, //~WARN behave unpredictably
|
||||||
|
//~| previously accepted
|
||||||
Wrap(_) => {}
|
Wrap(_) => {}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -80,7 +85,8 @@ fn main() {
|
|||||||
const CFN6: Wrap<fn(&SM)> = Wrap(r_sm_to);
|
const CFN6: Wrap<fn(&SM)> = Wrap(r_sm_to);
|
||||||
let input: Wrap<fn(&SM)> = Wrap(r_sm_to);
|
let input: Wrap<fn(&SM)> = Wrap(r_sm_to);
|
||||||
match Wrap(input) {
|
match Wrap(input) {
|
||||||
Wrap(CFN6) => count += 1,
|
Wrap(CFN6) => count += 1, //~WARN behave unpredictably
|
||||||
|
//~| previously accepted
|
||||||
Wrap(_) => {}
|
Wrap(_) => {}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -88,7 +94,8 @@ fn main() {
|
|||||||
const CFN7: Wrap<fn(&()) -> &SM> = Wrap(r_to_r_sm);
|
const CFN7: Wrap<fn(&()) -> &SM> = Wrap(r_to_r_sm);
|
||||||
let input: Wrap<fn(&()) -> &SM> = Wrap(r_to_r_sm);
|
let input: Wrap<fn(&()) -> &SM> = Wrap(r_to_r_sm);
|
||||||
match Wrap(input) {
|
match Wrap(input) {
|
||||||
Wrap(CFN7) => count += 1,
|
Wrap(CFN7) => count += 1, //~WARN behave unpredictably
|
||||||
|
//~| previously accepted
|
||||||
Wrap(_) => {}
|
Wrap(_) => {}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -96,7 +103,8 @@ fn main() {
|
|||||||
const CFN8: Wrap<fn(&NotSM)> = Wrap(r_not_sm_to);
|
const CFN8: Wrap<fn(&NotSM)> = Wrap(r_not_sm_to);
|
||||||
let input: Wrap<fn(&NotSM)> = Wrap(r_not_sm_to);
|
let input: Wrap<fn(&NotSM)> = Wrap(r_not_sm_to);
|
||||||
match Wrap(input) {
|
match Wrap(input) {
|
||||||
Wrap(CFN8) => count += 1,
|
Wrap(CFN8) => count += 1, //~WARN behave unpredictably
|
||||||
|
//~| previously accepted
|
||||||
Wrap(_) => {}
|
Wrap(_) => {}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -104,7 +112,8 @@ fn main() {
|
|||||||
const CFN9: Wrap<fn(&()) -> &NotSM> = Wrap(r_to_r_not_sm);
|
const CFN9: Wrap<fn(&()) -> &NotSM> = Wrap(r_to_r_not_sm);
|
||||||
let input: Wrap<fn(&()) -> &NotSM> = Wrap(r_to_r_not_sm);
|
let input: Wrap<fn(&()) -> &NotSM> = Wrap(r_to_r_not_sm);
|
||||||
match Wrap(input) {
|
match Wrap(input) {
|
||||||
Wrap(CFN9) => count += 1,
|
Wrap(CFN9) => count += 1, //~WARN behave unpredictably
|
||||||
|
//~| previously accepted
|
||||||
Wrap(_) => {}
|
Wrap(_) => {}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -126,7 +135,8 @@ fn main() {
|
|||||||
|
|
||||||
let input = Foo { alpha: not_sm_to, beta: to_not_sm, gamma: sm_to, delta: to_sm };
|
let input = Foo { alpha: not_sm_to, beta: to_not_sm, gamma: sm_to, delta: to_sm };
|
||||||
match input {
|
match input {
|
||||||
CFOO => count += 1,
|
CFOO => count += 1, //~WARN behave unpredictably
|
||||||
|
//~| previously accepted
|
||||||
Foo { .. } => {}
|
Foo { .. } => {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -0,0 +1,93 @@
|
|||||||
|
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/fn-ptr-is-structurally-matchable.rs:43:14
|
||||||
|
|
|
||||||
|
LL | Wrap(CFN1) => count += 1,
|
||||||
|
| ^^^^
|
||||||
|
|
|
||||||
|
= 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>
|
||||||
|
= note: `#[warn(pointer_structural_match)]` on by default
|
||||||
|
|
||||||
|
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/fn-ptr-is-structurally-matchable.rs:52:14
|
||||||
|
|
|
||||||
|
LL | Wrap(CFN2) => count += 1,
|
||||||
|
| ^^^^
|
||||||
|
|
|
||||||
|
= 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: 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/fn-ptr-is-structurally-matchable.rs:61:14
|
||||||
|
|
|
||||||
|
LL | Wrap(CFN3) => count += 1,
|
||||||
|
| ^^^^
|
||||||
|
|
|
||||||
|
= 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: 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/fn-ptr-is-structurally-matchable.rs:70:14
|
||||||
|
|
|
||||||
|
LL | Wrap(CFN4) => count += 1,
|
||||||
|
| ^^^^
|
||||||
|
|
|
||||||
|
= 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: 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/fn-ptr-is-structurally-matchable.rs:79:14
|
||||||
|
|
|
||||||
|
LL | Wrap(CFN5) => count += 1,
|
||||||
|
| ^^^^
|
||||||
|
|
|
||||||
|
= 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: 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/fn-ptr-is-structurally-matchable.rs:88:14
|
||||||
|
|
|
||||||
|
LL | Wrap(CFN6) => count += 1,
|
||||||
|
| ^^^^
|
||||||
|
|
|
||||||
|
= 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: 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/fn-ptr-is-structurally-matchable.rs:97:14
|
||||||
|
|
|
||||||
|
LL | Wrap(CFN7) => count += 1,
|
||||||
|
| ^^^^
|
||||||
|
|
|
||||||
|
= 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: 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/fn-ptr-is-structurally-matchable.rs:106:14
|
||||||
|
|
|
||||||
|
LL | Wrap(CFN8) => count += 1,
|
||||||
|
| ^^^^
|
||||||
|
|
|
||||||
|
= 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: 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/fn-ptr-is-structurally-matchable.rs:115:14
|
||||||
|
|
|
||||||
|
LL | Wrap(CFN9) => count += 1,
|
||||||
|
| ^^^^
|
||||||
|
|
|
||||||
|
= 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: 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/fn-ptr-is-structurally-matchable.rs:138:9
|
||||||
|
|
|
||||||
|
LL | CFOO => count += 1,
|
||||||
|
| ^^^^
|
||||||
|
|
|
||||||
|
= 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: 10 warnings emitted
|
||||||
|
|
@ -26,6 +26,7 @@ fn my_fn(_args: &[A]) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const TEST: Fn = my_fn;
|
const TEST: Fn = my_fn;
|
||||||
|
const TEST2: (Fn, u8) = (TEST, 0);
|
||||||
|
|
||||||
struct B(Fn);
|
struct B(Fn);
|
||||||
|
|
||||||
@ -33,8 +34,14 @@ fn main() {
|
|||||||
let s = B(my_fn);
|
let s = B(my_fn);
|
||||||
match s {
|
match s {
|
||||||
B(TEST) => println!("matched"),
|
B(TEST) => println!("matched"),
|
||||||
//~^ WARN pointers in patterns behave unpredictably
|
//~^ WARN behave unpredictably
|
||||||
//~| WARN this was previously accepted by the compiler but is being phased out
|
//~| WARN this was previously accepted by the compiler but is being phased out
|
||||||
_ => panic!("didn't match")
|
_ => 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")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
warning: function pointers and unsized pointers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
|
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"),
|
LL | B(TEST) => println!("matched"),
|
||||||
| ^^^^
|
| ^^^^
|
||||||
@ -12,5 +12,14 @@ note: the lint level is defined here
|
|||||||
LL | #![warn(pointer_structural_match)]
|
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
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user