Use precise errors during const to pat conversion instead of a catch-all on the main constant
This commit is contained in:
parent
aba5ea1430
commit
adf98ab2dc
28 changed files with 240 additions and 115 deletions
|
@ -43,7 +43,7 @@ struct ConstToPat<'a, 'tcx> {
|
||||||
span: Span,
|
span: Span,
|
||||||
param_env: ty::ParamEnv<'tcx>,
|
param_env: ty::ParamEnv<'tcx>,
|
||||||
|
|
||||||
// This tracks if we signal some hard error for a given const value, so that
|
// This tracks if we saw some error or lint for a given const value, so that
|
||||||
// we will not subsequently issue an irrelevant lint for the same const
|
// we will not subsequently issue an irrelevant lint for the same const
|
||||||
// value.
|
// value.
|
||||||
saw_const_match_error: Cell<bool>,
|
saw_const_match_error: Cell<bool>,
|
||||||
|
@ -103,7 +103,7 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
|
||||||
// once indirect_structural_match is a full fledged error, this
|
// once indirect_structural_match is a full fledged error, this
|
||||||
// level of indirection can be eliminated
|
// level of indirection can be eliminated
|
||||||
|
|
||||||
let inlined_const_as_pat = self.recur(cv);
|
let inlined_const_as_pat = self.recur(cv, mir_structural_match_violation);
|
||||||
|
|
||||||
if self.include_lint_checks && !self.saw_const_match_error.get() {
|
if self.include_lint_checks && !self.saw_const_match_error.get() {
|
||||||
// If we were able to successfully convert the const to some pat,
|
// If we were able to successfully convert the const to some pat,
|
||||||
|
@ -216,7 +216,7 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Recursive helper for `to_pat`; invoke that (instead of calling this directly).
|
// Recursive helper for `to_pat`; invoke that (instead of calling this directly).
|
||||||
fn recur(&self, cv: &'tcx ty::Const<'tcx>) -> Pat<'tcx> {
|
fn recur(&self, cv: &'tcx ty::Const<'tcx>, mir_structural_match_violation: bool) -> Pat<'tcx> {
|
||||||
let id = self.id;
|
let id = self.id;
|
||||||
let span = self.span;
|
let span = self.span;
|
||||||
let tcx = self.tcx();
|
let tcx = self.tcx();
|
||||||
|
@ -227,7 +227,7 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.map(|(idx, val)| {
|
.map(|(idx, val)| {
|
||||||
let field = Field::new(idx);
|
let field = Field::new(idx);
|
||||||
FieldPat { field, pattern: self.recur(val) }
|
FieldPat { field, pattern: self.recur(val, false) }
|
||||||
})
|
})
|
||||||
.collect()
|
.collect()
|
||||||
};
|
};
|
||||||
|
@ -248,6 +248,21 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
|
||||||
tcx.sess.span_err(span, "cannot use unions in constant patterns");
|
tcx.sess.span_err(span, "cannot use unions in constant patterns");
|
||||||
PatKind::Wild
|
PatKind::Wild
|
||||||
}
|
}
|
||||||
|
ty::Adt(..)
|
||||||
|
if !self.type_has_partial_eq_impl(cv.ty)
|
||||||
|
// FIXME(#73448): Find a way to bring const qualification into parity with
|
||||||
|
// `search_for_structural_match_violation` and then remove this condition.
|
||||||
|
&& self.search_for_structural_match_violation(cv.ty).is_some() =>
|
||||||
|
{
|
||||||
|
let msg = format!(
|
||||||
|
"to use a constant of type `{}` in a pattern, \
|
||||||
|
`{}` must be annotated with `#[derive(PartialEq, Eq)]`",
|
||||||
|
cv.ty, cv.ty,
|
||||||
|
);
|
||||||
|
self.saw_const_match_error.set(true);
|
||||||
|
self.tcx().sess.span_err(self.span, &msg);
|
||||||
|
PatKind::Wild
|
||||||
|
}
|
||||||
// If the type is not structurally comparable, just emit the constant directly,
|
// If the type is not structurally comparable, just emit the constant directly,
|
||||||
// causing the pattern match code to treat it opaquely.
|
// causing the pattern match code to treat it opaquely.
|
||||||
// FIXME: This code doesn't emit errors itself, the caller emits the errors.
|
// FIXME: This code doesn't emit errors itself, the caller emits the errors.
|
||||||
|
@ -258,6 +273,20 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
|
||||||
// Backwards compatibility hack because we can't cause hard errors on these
|
// Backwards compatibility hack because we can't cause hard errors on these
|
||||||
// types, so we compare them via `PartialEq::eq` at runtime.
|
// types, so we compare them via `PartialEq::eq` at runtime.
|
||||||
ty::Adt(..) if !self.type_marked_structural(cv.ty) && self.behind_reference.get() => {
|
ty::Adt(..) if !self.type_marked_structural(cv.ty) && self.behind_reference.get() => {
|
||||||
|
if self.include_lint_checks && !self.saw_const_match_error.get() {
|
||||||
|
self.saw_const_match_error.set(true);
|
||||||
|
let msg = format!(
|
||||||
|
"to use a constant of type `{}` in a pattern, \
|
||||||
|
`{}` must be annotated with `#[derive(PartialEq, Eq)]`",
|
||||||
|
cv.ty, cv.ty,
|
||||||
|
);
|
||||||
|
tcx.struct_span_lint_hir(
|
||||||
|
lint::builtin::INDIRECT_STRUCTURAL_MATCH,
|
||||||
|
id,
|
||||||
|
span,
|
||||||
|
|lint| lint.build(&msg).emit(),
|
||||||
|
);
|
||||||
|
}
|
||||||
PatKind::Constant { value: cv }
|
PatKind::Constant { value: cv }
|
||||||
}
|
}
|
||||||
ty::Adt(adt_def, _) if !self.type_marked_structural(cv.ty) => {
|
ty::Adt(adt_def, _) if !self.type_marked_structural(cv.ty) => {
|
||||||
|
@ -292,14 +321,18 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
|
||||||
.destructure_const(param_env.and(cv))
|
.destructure_const(param_env.and(cv))
|
||||||
.fields
|
.fields
|
||||||
.iter()
|
.iter()
|
||||||
.map(|val| self.recur(val))
|
.map(|val| self.recur(val, false))
|
||||||
.collect(),
|
.collect(),
|
||||||
slice: None,
|
slice: None,
|
||||||
suffix: Vec::new(),
|
suffix: Vec::new(),
|
||||||
},
|
},
|
||||||
ty::Ref(_, pointee_ty, ..) => match *pointee_ty.kind() {
|
ty::Ref(_, pointee_ty, ..) => match *pointee_ty.kind() {
|
||||||
// These are not allowed and will error elsewhere anyway.
|
// These are not allowed and will error elsewhere anyway.
|
||||||
ty::Dynamic(..) => PatKind::Constant { value: cv },
|
ty::Dynamic(..) => {
|
||||||
|
self.saw_const_match_error.set(true);
|
||||||
|
tcx.sess.span_err(span, &format!("`{}` cannot be used in patterns", cv.ty));
|
||||||
|
PatKind::Wild
|
||||||
|
}
|
||||||
// `&str` and `&[u8]` are represented as `ConstValue::Slice`, let's keep using this
|
// `&str` and `&[u8]` are represented as `ConstValue::Slice`, let's keep using this
|
||||||
// optimization for now.
|
// optimization for now.
|
||||||
ty::Str => PatKind::Constant { value: cv },
|
ty::Str => PatKind::Constant { value: cv },
|
||||||
|
@ -321,7 +354,7 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
|
||||||
.destructure_const(param_env.and(array))
|
.destructure_const(param_env.and(array))
|
||||||
.fields
|
.fields
|
||||||
.iter()
|
.iter()
|
||||||
.map(|val| self.recur(val))
|
.map(|val| self.recur(val, false))
|
||||||
.collect(),
|
.collect(),
|
||||||
slice: None,
|
slice: None,
|
||||||
suffix: vec![],
|
suffix: vec![],
|
||||||
|
@ -333,16 +366,21 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
|
||||||
self.behind_reference.set(old);
|
self.behind_reference.set(old);
|
||||||
val
|
val
|
||||||
}
|
}
|
||||||
// Backwards compatibility hack. Don't take away the reference, since
|
// Backwards compatibility hack: support references to non-structural types.
|
||||||
// `PartialEq::eq` takes a reference, this makes the rest of the matching logic
|
// We'll lower
|
||||||
// simpler.
|
// this pattern to a `PartialEq::eq` comparison and `PartialEq::eq` takes a
|
||||||
|
// reference. This makes the rest of the matching logic simpler as it doesn't have
|
||||||
|
// to figure out how to get a reference again.
|
||||||
ty::Adt(..) if !self.type_marked_structural(pointee_ty) => {
|
ty::Adt(..) if !self.type_marked_structural(pointee_ty) => {
|
||||||
PatKind::Constant { value: cv }
|
PatKind::Constant { value: cv }
|
||||||
}
|
}
|
||||||
|
// All other references are converted into deref patterns and then recursively
|
||||||
|
// convert the dereferenced constant to a pattern that is the sub-pattern of the
|
||||||
|
// deref pattern.
|
||||||
_ => {
|
_ => {
|
||||||
let old = self.behind_reference.replace(true);
|
let old = self.behind_reference.replace(true);
|
||||||
let val = PatKind::Deref {
|
let val = PatKind::Deref {
|
||||||
subpattern: self.recur(tcx.deref_const(self.param_env.and(cv))),
|
subpattern: self.recur(tcx.deref_const(self.param_env.and(cv)), false),
|
||||||
};
|
};
|
||||||
self.behind_reference.set(old);
|
self.behind_reference.set(old);
|
||||||
val
|
val
|
||||||
|
@ -373,11 +411,34 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
|
||||||
PatKind::Constant { value: cv }
|
PatKind::Constant { value: cv }
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
tcx.sess.delay_span_bug(span, &format!("cannot make a pattern out of {}", cv.ty));
|
self.saw_const_match_error.set(true);
|
||||||
|
tcx.sess.span_err(span, &format!("`{}` cannot be used in patterns", cv.ty));
|
||||||
PatKind::Wild
|
PatKind::Wild
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if self.include_lint_checks
|
||||||
|
&& !self.saw_const_match_error.get()
|
||||||
|
&& mir_structural_match_violation
|
||||||
|
// FIXME(#73448): Find a way to bring const qualification into parity with
|
||||||
|
// `search_for_structural_match_violation` and then remove this condition.
|
||||||
|
&& self.search_for_structural_match_violation(cv.ty).is_some()
|
||||||
|
{
|
||||||
|
self.saw_const_match_error.set(true);
|
||||||
|
let msg = format!(
|
||||||
|
"to use a constant of type `{}` in a pattern, \
|
||||||
|
the constant's initializer must be trivial or all types \
|
||||||
|
in the constant must be annotated with `#[derive(PartialEq, Eq)]`",
|
||||||
|
cv.ty,
|
||||||
|
);
|
||||||
|
tcx.struct_span_lint_hir(
|
||||||
|
lint::builtin::NONTRIVIAL_STRUCTURAL_MATCH,
|
||||||
|
id,
|
||||||
|
span,
|
||||||
|
|lint| lint.build(&msg).emit(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
Pat { span, ty: cv.ty, kind: Box::new(kind) }
|
Pat { span, ty: cv.ty, kind: Box::new(kind) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2138,22 +2138,16 @@ declare_lint! {
|
||||||
/// ```rust,compile_fail
|
/// ```rust,compile_fail
|
||||||
/// #![deny(indirect_structural_match)]
|
/// #![deny(indirect_structural_match)]
|
||||||
///
|
///
|
||||||
/// struct Plus(i32, i32);
|
/// struct NoDerive(i32);
|
||||||
/// const ONE_PLUS_TWO: &&Plus = &&Plus(1, 2);
|
/// impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } }
|
||||||
///
|
/// impl Eq for NoDerive { }
|
||||||
/// impl PartialEq for Plus {
|
/// #[derive(PartialEq, Eq)]
|
||||||
/// fn eq(&self, other: &Self) -> bool {
|
/// struct WrapParam<T>(T);
|
||||||
/// self.0 + self.1 == other.0 + other.1
|
/// const WRAP_INDIRECT_PARAM: & &WrapParam<NoDerive> = & &WrapParam(NoDerive(0));
|
||||||
/// }
|
|
||||||
/// }
|
|
||||||
///
|
|
||||||
/// impl Eq for Plus {}
|
|
||||||
///
|
|
||||||
/// fn main() {
|
/// fn main() {
|
||||||
/// if let ONE_PLUS_TWO = &&Plus(3, 0) {
|
/// match WRAP_INDIRECT_PARAM {
|
||||||
/// println!("semantic!");
|
/// WRAP_INDIRECT_PARAM => { }
|
||||||
/// } else {
|
/// _ => { }
|
||||||
/// println!("structural!");
|
|
||||||
/// }
|
/// }
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
|
@ -2170,9 +2164,8 @@ declare_lint! {
|
||||||
/// [issue #62411]: https://github.com/rust-lang/rust/issues/62411
|
/// [issue #62411]: https://github.com/rust-lang/rust/issues/62411
|
||||||
/// [future-incompatible]: ../index.md#future-incompatible-lints
|
/// [future-incompatible]: ../index.md#future-incompatible-lints
|
||||||
pub INDIRECT_STRUCTURAL_MATCH,
|
pub INDIRECT_STRUCTURAL_MATCH,
|
||||||
// defaulting to allow until rust-lang/rust#62614 is fixed.
|
Warn,
|
||||||
Allow,
|
"constant used in pattern contains value of non-structural-match type in a field or a variant",
|
||||||
"pattern with const indirectly referencing non-structural-match type",
|
|
||||||
@future_incompatible = FutureIncompatibleInfo {
|
@future_incompatible = FutureIncompatibleInfo {
|
||||||
reference: "issue #62411 <https://github.com/rust-lang/rust/issues/62411>",
|
reference: "issue #62411 <https://github.com/rust-lang/rust/issues/62411>",
|
||||||
edition: None,
|
edition: None,
|
||||||
|
@ -2223,6 +2216,46 @@ declare_lint! {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
declare_lint! {
|
||||||
|
/// The `nontrivial_structural_match` lint detects constants that are used in patterns,
|
||||||
|
/// whose type is not structural-match and whose initializer body actually uses values
|
||||||
|
/// that are not structural-match. So `Option<NotStruturalMatch>` is ok if the constant
|
||||||
|
/// is just `None`.
|
||||||
|
///
|
||||||
|
/// ### Example
|
||||||
|
///
|
||||||
|
/// ```rust,compile_fail
|
||||||
|
/// #![deny(nontrivial_structural_match)]
|
||||||
|
///
|
||||||
|
/// struct Plus(i32, i32);
|
||||||
|
/// const ONE_PLUS_TWO: &&Plus = &&Plus(1, 2);
|
||||||
|
///
|
||||||
|
/// impl PartialEq for Plus {
|
||||||
|
/// fn eq(&self, other: &Self) -> bool {
|
||||||
|
/// self.0 + self.1 == other.0 + other.1
|
||||||
|
/// }
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// impl Eq for Plus {}
|
||||||
|
///
|
||||||
|
/// fn main() {
|
||||||
|
/// if let ONE_PLUS_TWO = &&Plus(3, 0) {
|
||||||
|
/// println!("semantic!");
|
||||||
|
/// } else {
|
||||||
|
/// println!("structural!");
|
||||||
|
/// }
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
pub NONTRIVIAL_STRUCTURAL_MATCH,
|
||||||
|
Warn,
|
||||||
|
"constant used in pattern of non-structural-match type and the constant's initializer \
|
||||||
|
expression contains values of non-structural-match types",
|
||||||
|
@future_incompatible = FutureIncompatibleInfo {
|
||||||
|
reference: "issue #73448 <https://github.com/rust-lang/rust/issues/73448>",
|
||||||
|
edition: None,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
declare_lint! {
|
declare_lint! {
|
||||||
/// The `ambiguous_associated_items` lint detects ambiguity between
|
/// The `ambiguous_associated_items` lint detects ambiguity between
|
||||||
/// [associated items] and [enum variants].
|
/// [associated items] and [enum variants].
|
||||||
|
@ -2657,6 +2690,7 @@ declare_lint_pass! {
|
||||||
MUTABLE_BORROW_RESERVATION_CONFLICT,
|
MUTABLE_BORROW_RESERVATION_CONFLICT,
|
||||||
INDIRECT_STRUCTURAL_MATCH,
|
INDIRECT_STRUCTURAL_MATCH,
|
||||||
POINTER_STRUCTURAL_MATCH,
|
POINTER_STRUCTURAL_MATCH,
|
||||||
|
NONTRIVIAL_STRUCTURAL_MATCH,
|
||||||
SOFT_UNSTABLE,
|
SOFT_UNSTABLE,
|
||||||
INLINE_NO_SANITIZE,
|
INLINE_NO_SANITIZE,
|
||||||
ASM_SUB_REGISTER,
|
ASM_SUB_REGISTER,
|
||||||
|
|
|
@ -1,8 +1,5 @@
|
||||||
// check-pass
|
// check-pass
|
||||||
|
|
||||||
#![warn(indirect_structural_match)]
|
|
||||||
//~^ NOTE lint level is defined here
|
|
||||||
|
|
||||||
struct CustomEq;
|
struct CustomEq;
|
||||||
|
|
||||||
impl Eq for CustomEq {}
|
impl Eq for CustomEq {}
|
||||||
|
@ -32,7 +29,8 @@ fn main() {
|
||||||
BAR_BAZ => panic!(),
|
BAR_BAZ => panic!(),
|
||||||
//~^ WARN must be annotated with `#[derive(PartialEq, Eq)]`
|
//~^ WARN must be annotated with `#[derive(PartialEq, Eq)]`
|
||||||
//~| WARN this was previously accepted
|
//~| WARN this was previously accepted
|
||||||
//~| NOTE see issue #62411
|
//~| NOTE see issue #73448
|
||||||
|
//~| NOTE `#[warn(nontrivial_structural_match)]` on by default
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,16 +1,12 @@
|
||||||
warning: to use a constant of type `CustomEq` in a pattern, `CustomEq` must be annotated with `#[derive(PartialEq, Eq)]`
|
warning: to use a constant of type `Foo` in a pattern, the constant's initializer must be trivial or all types in the constant must be annotated with `#[derive(PartialEq, Eq)]`
|
||||||
--> $DIR/custom-eq-branch-warn.rs:32:9
|
--> $DIR/custom-eq-branch-warn.rs:29:9
|
||||||
|
|
|
|
||||||
LL | BAR_BAZ => panic!(),
|
LL | BAR_BAZ => panic!(),
|
||||||
| ^^^^^^^
|
| ^^^^^^^
|
||||||
|
|
|
|
||||||
note: the lint level is defined here
|
= note: `#[warn(nontrivial_structural_match)]` on by default
|
||||||
--> $DIR/custom-eq-branch-warn.rs:3:9
|
|
||||||
|
|
|
||||||
LL | #![warn(indirect_structural_match)]
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
= 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/62411>
|
= note: for more information, see issue #73448 <https://github.com/rust-lang/rust/issues/73448>
|
||||||
|
|
||||||
warning: 1 warning emitted
|
warning: 1 warning emitted
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
// FIXME: This still ICEs.
|
|
||||||
//
|
|
||||||
// ignore-test
|
|
||||||
|
|
||||||
#![deny(indirect_structural_match)]
|
#![deny(indirect_structural_match)]
|
||||||
|
|
||||||
|
// check-pass
|
||||||
|
|
||||||
#[derive(PartialEq, Eq)]
|
#[derive(PartialEq, Eq)]
|
||||||
enum O<T> {
|
enum O<T> {
|
||||||
Some(*const T), // Can also use PhantomData<T>
|
Some(*const T), // Can also use PhantomData<T>
|
||||||
|
|
|
@ -1,15 +0,0 @@
|
||||||
error[E0601]: `main` function not found in crate `issue_65466`
|
|
||||||
--> $DIR/issue-65466.rs:1:1
|
|
||||||
|
|
|
||||||
LL | / #![deny(indirect_structural_match)]
|
|
||||||
LL | |
|
|
||||||
LL | | #[derive(PartialEq, Eq)]
|
|
||||||
LL | | enum O<T> {
|
|
||||||
... |
|
|
||||||
LL | | }
|
|
||||||
LL | | }
|
|
||||||
| |_^ consider adding a `main` function to `$DIR/issue-65466.rs`
|
|
||||||
|
|
||||||
error: aborting due to previous error
|
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0601`.
|
|
|
@ -27,6 +27,7 @@ fn main() {
|
||||||
match None {
|
match None {
|
||||||
NO_PARTIAL_EQ_NONE => println!("NO_PARTIAL_EQ_NONE"),
|
NO_PARTIAL_EQ_NONE => println!("NO_PARTIAL_EQ_NONE"),
|
||||||
//~^ ERROR must be annotated with `#[derive(PartialEq, Eq)]`
|
//~^ ERROR must be annotated with `#[derive(PartialEq, Eq)]`
|
||||||
|
//~| ERROR must be annotated with `#[derive(PartialEq, Eq)]`
|
||||||
_ => panic!("whoops"),
|
_ => panic!("whoops"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,14 @@
|
||||||
error: to use a constant of type `NoPartialEq` in a pattern, `NoPartialEq` must be annotated with `#[derive(PartialEq, Eq)]`
|
error: to use a constant of type `Option<NoPartialEq>` in a pattern, `Option<NoPartialEq>` must be annotated with `#[derive(PartialEq, Eq)]`
|
||||||
--> $DIR/reject_non_partial_eq.rs:28:9
|
--> $DIR/reject_non_partial_eq.rs:28:9
|
||||||
|
|
|
|
||||||
LL | NO_PARTIAL_EQ_NONE => println!("NO_PARTIAL_EQ_NONE"),
|
LL | NO_PARTIAL_EQ_NONE => println!("NO_PARTIAL_EQ_NONE"),
|
||||||
| ^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: to use a constant of type `Option<NoPartialEq>` in a pattern, `Option<NoPartialEq>` must be annotated with `#[derive(PartialEq, Eq)]`
|
||||||
|
--> $DIR/reject_non_partial_eq.rs:28:9
|
||||||
|
|
|
||||||
|
LL | NO_PARTIAL_EQ_NONE => println!("NO_PARTIAL_EQ_NONE"),
|
||||||
|
| ^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
|
|
@ -1,34 +1,30 @@
|
||||||
warning: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq, Eq)]`
|
warning: to use a constant of type `Option<NoDerive>` in a pattern, the constant's initializer must be trivial or all types in the constant must be annotated with `#[derive(PartialEq, Eq)]`
|
||||||
--> $DIR/warn_corner_cases.rs:26:47
|
--> $DIR/warn_corner_cases.rs:26:47
|
||||||
|
|
|
|
||||||
LL | match None { Some(_) => panic!("whoops"), INDEX => dbg!(INDEX), };
|
LL | match None { Some(_) => panic!("whoops"), INDEX => dbg!(INDEX), };
|
||||||
| ^^^^^
|
| ^^^^^
|
||||||
|
|
|
|
||||||
note: the lint level is defined here
|
= note: `#[warn(nontrivial_structural_match)]` on by default
|
||||||
--> $DIR/warn_corner_cases.rs:15:9
|
|
||||||
|
|
|
||||||
LL | #![warn(indirect_structural_match)]
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
= 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/62411>
|
= note: for more information, see issue #73448 <https://github.com/rust-lang/rust/issues/73448>
|
||||||
|
|
||||||
warning: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq, Eq)]`
|
warning: to use a constant of type `Option<NoDerive>` in a pattern, the constant's initializer must be trivial or all types in the constant must be annotated with `#[derive(PartialEq, Eq)]`
|
||||||
--> $DIR/warn_corner_cases.rs:32:47
|
--> $DIR/warn_corner_cases.rs:32:47
|
||||||
|
|
|
|
||||||
LL | match None { Some(_) => panic!("whoops"), CALL => dbg!(CALL), };
|
LL | match None { Some(_) => panic!("whoops"), CALL => dbg!(CALL), };
|
||||||
| ^^^^
|
| ^^^^
|
||||||
|
|
|
|
||||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
= 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/62411>
|
= note: for more information, see issue #73448 <https://github.com/rust-lang/rust/issues/73448>
|
||||||
|
|
||||||
warning: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq, Eq)]`
|
warning: to use a constant of type `Option<NoDerive>` in a pattern, the constant's initializer must be trivial or all types in the constant must be annotated with `#[derive(PartialEq, Eq)]`
|
||||||
--> $DIR/warn_corner_cases.rs:38:47
|
--> $DIR/warn_corner_cases.rs:38:47
|
||||||
|
|
|
|
||||||
LL | match None { Some(_) => panic!("whoops"), METHOD_CALL => dbg!(METHOD_CALL), };
|
LL | match None { Some(_) => panic!("whoops"), METHOD_CALL => dbg!(METHOD_CALL), };
|
||||||
| ^^^^^^^^^^^
|
| ^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
= 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/62411>
|
= note: for more information, see issue #73448 <https://github.com/rust-lang/rust/issues/73448>
|
||||||
|
|
||||||
warning: 3 warnings emitted
|
warning: 3 warnings emitted
|
||||||
|
|
||||||
|
|
|
@ -8,8 +8,10 @@ struct T;
|
||||||
fn main() {
|
fn main() {
|
||||||
const C: &S = &S;
|
const C: &S = &S;
|
||||||
match C {
|
match C {
|
||||||
|
//~^ non-exhaustive patterns: `&S` not covered
|
||||||
C => {}
|
C => {}
|
||||||
//~^ ERROR to use a constant of type `S` in a pattern, `S` must be annotated with
|
//~^ WARN must be annotated with `#[derive(PartialEq, Eq)]`
|
||||||
|
//~| WARN was previously accepted by the compiler
|
||||||
}
|
}
|
||||||
const K: &T = &T;
|
const K: &T = &T;
|
||||||
match K {
|
match K {
|
||||||
|
|
|
@ -1,8 +1,25 @@
|
||||||
error: to use a constant of type `S` in a pattern, `S` must be annotated with `#[derive(PartialEq, Eq)]`
|
warning: to use a constant of type `&S` in a pattern, the constant's initializer must be trivial or all types in the constant must be annotated with `#[derive(PartialEq, Eq)]`
|
||||||
--> $DIR/match_ice.rs:11:9
|
--> $DIR/match_ice.rs:12:9
|
||||||
|
|
|
|
||||||
LL | C => {}
|
LL | C => {}
|
||||||
| ^
|
| ^
|
||||||
|
|
|
||||||
|
= note: `#[warn(nontrivial_structural_match)]` on by default
|
||||||
|
= 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 #73448 <https://github.com/rust-lang/rust/issues/73448>
|
||||||
|
|
||||||
error: aborting due to previous error
|
error[E0004]: non-exhaustive patterns: `&S` not covered
|
||||||
|
--> $DIR/match_ice.rs:10:11
|
||||||
|
|
|
||||||
|
LL | struct S;
|
||||||
|
| --------- `S` defined here
|
||||||
|
...
|
||||||
|
LL | match C {
|
||||||
|
| ^ pattern `&S` not covered
|
||||||
|
|
|
||||||
|
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
|
||||||
|
= note: the matched value is of type `&S`
|
||||||
|
|
||||||
|
error: aborting due to previous error; 1 warning emitted
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0004`.
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
// run-pass
|
// run-pass
|
||||||
|
|
||||||
|
#![warn(pointer_structural_match)]
|
||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
const C: *const u8 = &0;
|
const C: *const u8 = &0;
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,8 @@ fn main() {
|
||||||
let a: &dyn Send = &7u32;
|
let a: &dyn Send = &7u32;
|
||||||
match a {
|
match a {
|
||||||
F => panic!(),
|
F => panic!(),
|
||||||
//~^ ERROR trait objects cannot be used in patterns
|
//~^ ERROR `&dyn Send` cannot be used in patterns
|
||||||
|
//~| ERROR `&dyn Send` cannot be used in patterns
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,14 @@
|
||||||
error: trait objects cannot be used in patterns
|
error: `&dyn Send` cannot be used in patterns
|
||||||
--> $DIR/issue-70972-dyn-trait.rs:6:9
|
--> $DIR/issue-70972-dyn-trait.rs:6:9
|
||||||
|
|
|
|
||||||
LL | F => panic!(),
|
LL | F => panic!(),
|
||||||
| ^
|
| ^
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: `&dyn Send` cannot be used in patterns
|
||||||
|
--> $DIR/issue-70972-dyn-trait.rs:6:9
|
||||||
|
|
|
||||||
|
LL | F => panic!(),
|
||||||
|
| ^
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,8 @@
|
||||||
fn main() {
|
fn main() {
|
||||||
const C: impl Copy = 0;
|
const C: impl Copy = 0;
|
||||||
match C {
|
match C {
|
||||||
C | _ => {} //~ ERROR: opaque types cannot be used in patterns
|
C => {} //~ ERROR: `impl Copy` cannot be used in patterns
|
||||||
|
//~^ ERROR: `impl Copy` cannot be used in patterns
|
||||||
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,14 @@
|
||||||
error: opaque types cannot be used in patterns
|
error: `impl Copy` cannot be used in patterns
|
||||||
--> $DIR/issue-71042-opaquely-typed-constant-used-in-pattern.rs:7:9
|
--> $DIR/issue-71042-opaquely-typed-constant-used-in-pattern.rs:7:9
|
||||||
|
|
|
|
||||||
LL | C | _ => {}
|
LL | C => {}
|
||||||
| ^
|
| ^
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: `impl Copy` cannot be used in patterns
|
||||||
|
--> $DIR/issue-71042-opaquely-typed-constant-used-in-pattern.rs:7:9
|
||||||
|
|
|
||||||
|
LL | C => {}
|
||||||
|
| ^
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
|
|
||||||
// run-pass
|
// run-pass
|
||||||
|
|
||||||
|
#![warn(pointer_structural_match)]
|
||||||
|
|
||||||
struct NoDerive(i32);
|
struct NoDerive(i32);
|
||||||
|
|
||||||
// This impl makes NoDerive irreflexive
|
// This impl makes NoDerive irreflexive
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
|
|
||||||
// run-pass
|
// run-pass
|
||||||
|
|
||||||
|
#![warn(pointer_structural_match)]
|
||||||
|
|
||||||
struct NoDerive(i32);
|
struct NoDerive(i32);
|
||||||
|
|
||||||
// This impl makes NoDerive irreflexive
|
// This impl makes NoDerive irreflexive
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
|
|
||||||
// run-pass
|
// run-pass
|
||||||
|
|
||||||
|
#![warn(pointer_structural_match)]
|
||||||
|
|
||||||
struct NoDerive(i32);
|
struct NoDerive(i32);
|
||||||
|
|
||||||
// This impl makes NoDerive irreflexive
|
// This impl makes NoDerive irreflexive
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
|
|
||||||
// run-pass
|
// run-pass
|
||||||
|
|
||||||
|
#![warn(pointer_structural_match)]
|
||||||
|
|
||||||
struct NoDerive(i32);
|
struct NoDerive(i32);
|
||||||
|
|
||||||
// This impl makes NoDerive irreflexive
|
// This impl makes NoDerive irreflexive
|
||||||
|
|
|
@ -1,16 +1,12 @@
|
||||||
warning: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq, Eq)]`
|
warning: to use a constant of type `&&WrapInline` in a pattern, the constant's initializer must be trivial or all types in the constant must be annotated with `#[derive(PartialEq, Eq)]`
|
||||||
--> $DIR/cant-hide-behind-doubly-indirect-embedded.rs:24:9
|
--> $DIR/cant-hide-behind-doubly-indirect-embedded.rs:24:9
|
||||||
|
|
|
|
||||||
LL | WRAP_DOUBLY_INDIRECT_INLINE => { panic!("WRAP_DOUBLY_INDIRECT_INLINE matched itself"); }
|
LL | WRAP_DOUBLY_INDIRECT_INLINE => { panic!("WRAP_DOUBLY_INDIRECT_INLINE matched itself"); }
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
note: the lint level is defined here
|
= note: `#[warn(nontrivial_structural_match)]` on by default
|
||||||
--> $DIR/cant-hide-behind-doubly-indirect-embedded.rs:7:9
|
|
||||||
|
|
|
||||||
LL | #![warn(indirect_structural_match)]
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
= 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/62411>
|
= note: for more information, see issue #73448 <https://github.com/rust-lang/rust/issues/73448>
|
||||||
|
|
||||||
warning: 1 warning emitted
|
warning: 1 warning emitted
|
||||||
|
|
||||||
|
|
|
@ -1,16 +1,12 @@
|
||||||
warning: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq, Eq)]`
|
warning: to use a constant of type `&&WrapParam<NoDerive>` in a pattern, the constant's initializer must be trivial or all types in the constant must be annotated with `#[derive(PartialEq, Eq)]`
|
||||||
--> $DIR/cant-hide-behind-doubly-indirect-param.rs:24:9
|
--> $DIR/cant-hide-behind-doubly-indirect-param.rs:24:9
|
||||||
|
|
|
|
||||||
LL | WRAP_DOUBLY_INDIRECT_PARAM => { panic!("WRAP_DOUBLY_INDIRECT_PARAM matched itself"); }
|
LL | WRAP_DOUBLY_INDIRECT_PARAM => { panic!("WRAP_DOUBLY_INDIRECT_PARAM matched itself"); }
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
note: the lint level is defined here
|
= note: `#[warn(nontrivial_structural_match)]` on by default
|
||||||
--> $DIR/cant-hide-behind-doubly-indirect-param.rs:7:9
|
|
||||||
|
|
|
||||||
LL | #![warn(indirect_structural_match)]
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
= 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/62411>
|
= note: for more information, see issue #73448 <https://github.com/rust-lang/rust/issues/73448>
|
||||||
|
|
||||||
warning: 1 warning emitted
|
warning: 1 warning emitted
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
|
|
||||||
// Issue 62307 pointed out a case where the structural-match checking
|
// Issue 62307 pointed out a case where the structural-match checking
|
||||||
// was too shallow.
|
// was too shallow.
|
||||||
#![warn(indirect_structural_match)]
|
#![warn(indirect_structural_match, nontrivial_structural_match)]
|
||||||
// run-pass
|
// run-pass
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
|
|
@ -1,25 +1,25 @@
|
||||||
warning: to use a constant of type `B` in a pattern, `B` must be annotated with `#[derive(PartialEq, Eq)]`
|
warning: to use a constant of type `&&B` in a pattern, the constant's initializer must be trivial or all types in the constant must be annotated with `#[derive(PartialEq, Eq)]`
|
||||||
--> $DIR/issue-62307-match-ref-ref-forbidden-without-eq.rs:31:9
|
--> $DIR/issue-62307-match-ref-ref-forbidden-without-eq.rs:31:9
|
||||||
|
|
|
|
||||||
LL | RR_B1 => { println!("CLAIM RR0: {:?} matches {:?}", RR_B1, RR_B0); }
|
LL | RR_B1 => { println!("CLAIM RR0: {:?} matches {:?}", RR_B1, RR_B0); }
|
||||||
| ^^^^^
|
| ^^^^^
|
||||||
|
|
|
|
||||||
note: the lint level is defined here
|
note: the lint level is defined here
|
||||||
--> $DIR/issue-62307-match-ref-ref-forbidden-without-eq.rs:13:9
|
--> $DIR/issue-62307-match-ref-ref-forbidden-without-eq.rs:13:36
|
||||||
|
|
|
|
||||||
LL | #![warn(indirect_structural_match)]
|
LL | #![warn(indirect_structural_match, nontrivial_structural_match)]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
= 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/62411>
|
= note: for more information, see issue #73448 <https://github.com/rust-lang/rust/issues/73448>
|
||||||
|
|
||||||
warning: to use a constant of type `B` in a pattern, `B` must be annotated with `#[derive(PartialEq, Eq)]`
|
warning: to use a constant of type `&&B` in a pattern, the constant's initializer must be trivial or all types in the constant must be annotated with `#[derive(PartialEq, Eq)]`
|
||||||
--> $DIR/issue-62307-match-ref-ref-forbidden-without-eq.rs:38:9
|
--> $DIR/issue-62307-match-ref-ref-forbidden-without-eq.rs:38:9
|
||||||
|
|
|
|
||||||
LL | RR_B1 => { println!("CLAIM RR1: {:?} matches {:?}", RR_B1, RR_B1); }
|
LL | RR_B1 => { println!("CLAIM RR1: {:?} matches {:?}", RR_B1, RR_B1); }
|
||||||
| ^^^^^
|
| ^^^^^
|
||||||
|
|
|
|
||||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
= 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/62411>
|
= note: for more information, see issue #73448 <https://github.com/rust-lang/rust/issues/73448>
|
||||||
|
|
||||||
warning: 2 warnings emitted
|
warning: 2 warnings emitted
|
||||||
|
|
||||||
|
|
|
@ -12,9 +12,10 @@ const LEAK_FREE: Bar = leak_free();
|
||||||
fn leak_free_test() {
|
fn leak_free_test() {
|
||||||
match todo!() {
|
match todo!() {
|
||||||
LEAK_FREE => (),
|
LEAK_FREE => (),
|
||||||
//~^ opaque types cannot be used in patterns
|
//~^ `impl Send` cannot be used in patterns
|
||||||
|
//~| `impl Send` cannot be used in patterns
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() { }
|
fn main() {}
|
||||||
|
|
|
@ -1,8 +1,14 @@
|
||||||
error: opaque types cannot be used in patterns
|
error: `impl Send` cannot be used in patterns
|
||||||
--> $DIR/structural-match-no-leak.rs:14:9
|
--> $DIR/structural-match-no-leak.rs:14:9
|
||||||
|
|
|
|
||||||
LL | LEAK_FREE => (),
|
LL | LEAK_FREE => (),
|
||||||
| ^^^^^^^^^
|
| ^^^^^^^^^
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: `impl Send` cannot be used in patterns
|
||||||
|
--> $DIR/structural-match-no-leak.rs:14:9
|
||||||
|
|
|
||||||
|
LL | LEAK_FREE => (),
|
||||||
|
| ^^^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
|
|
@ -13,9 +13,10 @@ const VALUE: Foo = value();
|
||||||
fn test() {
|
fn test() {
|
||||||
match todo!() {
|
match todo!() {
|
||||||
VALUE => (),
|
VALUE => (),
|
||||||
//~^ opaque types cannot be used in patterns
|
//~^ `impl Send` cannot be used in patterns
|
||||||
|
//~| `impl Send` cannot be used in patterns
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() { }
|
fn main() {}
|
||||||
|
|
|
@ -1,8 +1,14 @@
|
||||||
error: opaque types cannot be used in patterns
|
error: `impl Send` cannot be used in patterns
|
||||||
--> $DIR/structural-match.rs:15:9
|
--> $DIR/structural-match.rs:15:9
|
||||||
|
|
|
|
||||||
LL | VALUE => (),
|
LL | VALUE => (),
|
||||||
| ^^^^^
|
| ^^^^^
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: `impl Send` cannot be used in patterns
|
||||||
|
--> $DIR/structural-match.rs:15:9
|
||||||
|
|
|
||||||
|
LL | VALUE => (),
|
||||||
|
| ^^^^^
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue