span: Span,
param_env: ty::ParamEnv<'tcx>,
- // This tracks if we saw some error or lint for a given const value, so that
+ // This tracks if we emitted some hard error for a given const value, so that
// we will not subsequently issue an irrelevant lint for the same const
// value.
saw_const_match_error: Cell<bool>,
+ // This tracks if we emitted some diagnostic for a given const value, so that
+ // we will not subsequently issue an irrelevant lint for the same const
+ // value.
+ saw_const_match_lint: Cell<bool>,
+
// For backcompat we need to keep allowing non-structurally-eq types behind references.
// See also all the `cant-hide-behind` tests.
behind_reference: Cell<bool>,
param_env: pat_ctxt.param_env,
include_lint_checks: pat_ctxt.include_lint_checks,
saw_const_match_error: Cell::new(false),
+ saw_const_match_lint: Cell::new(false),
behind_reference: Cell::new(false),
}
}
if !self.type_has_partial_eq_impl(cv.ty) {
// span_fatal avoids ICE from resolution of non-existent method (rare case).
self.tcx().sess.span_fatal(self.span, &msg);
- } else if mir_structural_match_violation {
+ } else if mir_structural_match_violation && !self.saw_const_match_lint.get() {
self.tcx().struct_span_lint_hir(
lint::builtin::INDIRECT_STRUCTURAL_MATCH,
self.id,
// Backwards compatibility hack because we can't cause hard errors on these
// types, so we compare them via `PartialEq::eq` at runtime.
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);
+ if self.include_lint_checks
+ && !self.saw_const_match_error.get()
+ && !self.saw_const_match_lint.get()
+ {
+ self.saw_const_match_lint.set(true);
let msg = format!(
"to use a constant of type `{}` in a pattern, \
`{}` must be annotated with `#[derive(PartialEq, Eq)]`",
// compilation choices change the runtime behaviour of the match.
// See https://github.com/rust-lang/rust/issues/70861 for examples.
ty::FnPtr(..) | ty::RawPtr(..) => {
- if self.include_lint_checks && !self.saw_const_match_error.get() {
- self.saw_const_match_error.set(true);
+ if self.include_lint_checks
+ && !self.saw_const_match_error.get()
+ && !self.saw_const_match_lint.get()
+ {
+ self.saw_const_match_lint.set(true);
let msg = "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.";
if self.include_lint_checks
&& !self.saw_const_match_error.get()
+ && !self.saw_const_match_lint.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);
+ self.saw_const_match_lint.set(true);
let msg = format!(
"to use a constant of type `{}` in a pattern, \
the constant's initializer must be trivial or all types \
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:12:9
+ --> $DIR/match_ice.rs:11: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 #73448 <https://github.com/rust-lang/rust/issues/73448>
-error[E0004]: non-exhaustive patterns: `&S` not covered
- --> $DIR/match_ice.rs:10:11
+error: to use a constant of type `S` in a pattern, `S` must be annotated with `#[derive(PartialEq, Eq)]`
+ --> $DIR/match_ice.rs:11:9
|
-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`
+LL | C => {}
+ | ^
error: aborting due to previous error; 1 warning emitted
-For more information about this error, try `rustc --explain E0004`.