Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 9a7e66a

Browse files
committed
Make sure we don't hide errors just because a lint has been emitted
1 parent 177d0ce commit 9a7e66a

8 files changed

+34
-28
lines changed

compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,16 @@ struct ConstToPat<'a, 'tcx> {
4343
span: Span,
4444
param_env: ty::ParamEnv<'tcx>,
4545

46-
// This tracks if we saw some error or lint for a given const value, so that
46+
// This tracks if we emitted some hard error for a given const value, so that
4747
// we will not subsequently issue an irrelevant lint for the same const
4848
// value.
4949
saw_const_match_error: Cell<bool>,
5050

51+
// This tracks if we emitted some diagnostic for a given const value, so that
52+
// we will not subsequently issue an irrelevant lint for the same const
53+
// value.
54+
saw_const_match_lint: Cell<bool>,
55+
5156
// For backcompat we need to keep allowing non-structurally-eq types behind references.
5257
// See also all the `cant-hide-behind` tests.
5358
behind_reference: Cell<bool>,
@@ -75,6 +80,7 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
7580
param_env: pat_ctxt.param_env,
7681
include_lint_checks: pat_ctxt.include_lint_checks,
7782
saw_const_match_error: Cell::new(false),
83+
saw_const_match_lint: Cell::new(false),
7884
behind_reference: Cell::new(false),
7985
}
8086
}
@@ -165,7 +171,7 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
165171
if !self.type_has_partial_eq_impl(cv.ty) {
166172
// span_fatal avoids ICE from resolution of non-existent method (rare case).
167173
self.tcx().sess.span_fatal(self.span, &msg);
168-
} else if mir_structural_match_violation {
174+
} else if mir_structural_match_violation && !self.saw_const_match_lint.get() {
169175
self.tcx().struct_span_lint_hir(
170176
lint::builtin::INDIRECT_STRUCTURAL_MATCH,
171177
self.id,
@@ -289,8 +295,11 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
289295
// Backwards compatibility hack because we can't cause hard errors on these
290296
// types, so we compare them via `PartialEq::eq` at runtime.
291297
ty::Adt(..) if !self.type_marked_structural(cv.ty) && self.behind_reference.get() => {
292-
if self.include_lint_checks && !self.saw_const_match_error.get() {
293-
self.saw_const_match_error.set(true);
298+
if self.include_lint_checks
299+
&& !self.saw_const_match_error.get()
300+
&& !self.saw_const_match_lint.get()
301+
{
302+
self.saw_const_match_lint.set(true);
294303
let msg = format!(
295304
"to use a constant of type `{}` in a pattern, \
296305
`{}` must be annotated with `#[derive(PartialEq, Eq)]`",
@@ -429,8 +438,11 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
429438
// compilation choices change the runtime behaviour of the match.
430439
// See https://github.com/rust-lang/rust/issues/70861 for examples.
431440
ty::FnPtr(..) | ty::RawPtr(..) => {
432-
if self.include_lint_checks && !self.saw_const_match_error.get() {
433-
self.saw_const_match_error.set(true);
441+
if self.include_lint_checks
442+
&& !self.saw_const_match_error.get()
443+
&& !self.saw_const_match_lint.get()
444+
{
445+
self.saw_const_match_lint.set(true);
434446
let msg = "function pointers and unsized pointers in patterns behave \
435447
unpredictably and should not be relied upon. \
436448
See https://github.com/rust-lang/rust/issues/70861 for details.";
@@ -457,12 +469,13 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
457469

458470
if self.include_lint_checks
459471
&& !self.saw_const_match_error.get()
472+
&& !self.saw_const_match_lint.get()
460473
&& mir_structural_match_violation
461474
// FIXME(#73448): Find a way to bring const qualification into parity with
462475
// `search_for_structural_match_violation` and then remove this condition.
463476
&& self.search_for_structural_match_violation(cv.ty).is_some()
464477
{
465-
self.saw_const_match_error.set(true);
478+
self.saw_const_match_lint.set(true);
466479
let msg = format!(
467480
"to use a constant of type `{}` in a pattern, \
468481
the constant's initializer must be trivial or all types \

src/test/ui/consts/match_ice.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@ struct T;
88
fn main() {
99
const C: &S = &S;
1010
match C {
11-
//~^ non-exhaustive patterns: `&S` not covered
1211
C => {}
13-
//~^ WARN must be annotated with `#[derive(PartialEq, Eq)]`
14-
//~| WARN was previously accepted by the compiler
12+
//~^ ERROR must be annotated with `#[derive(PartialEq, Eq)]`
13+
//~| WARN must be annotated
14+
//~| WARN previously accepted
1515
}
1616
const K: &T = &T;
1717
match K {

src/test/ui/consts/match_ice.stderr

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
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)]`
2-
--> $DIR/match_ice.rs:12:9
2+
--> $DIR/match_ice.rs:11:9
33
|
44
LL | C => {}
55
| ^
@@ -8,18 +8,11 @@ LL | C => {}
88
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
99
= note: for more information, see issue #73448 <https://github.com/rust-lang/rust/issues/73448>
1010

11-
error[E0004]: non-exhaustive patterns: `&S` not covered
12-
--> $DIR/match_ice.rs:10:11
11+
error: to use a constant of type `S` in a pattern, `S` must be annotated with `#[derive(PartialEq, Eq)]`
12+
--> $DIR/match_ice.rs:11:9
1313
|
14-
LL | struct S;
15-
| --------- `S` defined here
16-
...
17-
LL | match C {
18-
| ^ pattern `&S` not covered
19-
|
20-
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
21-
= note: the matched value is of type `&S`
14+
LL | C => {}
15+
| ^
2216

2317
error: aborting due to previous error; 1 warning emitted
2418

25-
For more information about this error, try `rustc --explain E0004`.

src/test/ui/rfc1445/cant-hide-behind-doubly-indirect-embedded.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ fn main() {
2323
match WRAP_DOUBLY_INDIRECT_INLINE {
2424
WRAP_DOUBLY_INDIRECT_INLINE => { panic!("WRAP_DOUBLY_INDIRECT_INLINE matched itself"); }
2525
//~^ WARN must be annotated with `#[derive(PartialEq, Eq)]`
26-
//~| WARN will become a hard error in a future release
26+
//~| WARN this was previously accepted
2727
_ => { println!("WRAP_DOUBLY_INDIRECT_INLINE correctly did not match itself"); }
2828
}
2929
}

src/test/ui/rfc1445/cant-hide-behind-doubly-indirect-param.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ fn main() {
2323
match WRAP_DOUBLY_INDIRECT_PARAM {
2424
WRAP_DOUBLY_INDIRECT_PARAM => { panic!("WRAP_DOUBLY_INDIRECT_PARAM matched itself"); }
2525
//~^ WARN must be annotated with `#[derive(PartialEq, Eq)]`
26-
//~| WARN will become a hard error in a future release
26+
//~| WARN this was previously accepted
2727
_ => { println!("WRAP_DOUBLY_INDIRECT_PARAM correctly did not match itself"); }
2828
}
2929
}

src/test/ui/rfc1445/cant-hide-behind-indirect-struct-embedded.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ fn main() {
2323
match WRAP_INDIRECT_INLINE {
2424
WRAP_INDIRECT_INLINE => { panic!("WRAP_INDIRECT_INLINE matched itself"); }
2525
//~^ WARN must be annotated with `#[derive(PartialEq, Eq)]`
26-
//~| WARN will become a hard error in a future release
26+
//~| WARN this was previously accepted
2727
_ => { println!("WRAP_INDIRECT_INLINE did not match itself"); }
2828
}
2929
}

src/test/ui/rfc1445/cant-hide-behind-indirect-struct-param.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ fn main() {
2323
match WRAP_INDIRECT_PARAM {
2424
WRAP_INDIRECT_PARAM => { panic!("WRAP_INDIRECT_PARAM matched itself"); }
2525
//~^ WARN must be annotated with `#[derive(PartialEq, Eq)]`
26-
//~| WARN will become a hard error in a future release
26+
//~| WARN this was previously accepted
2727
_ => { println!("WRAP_INDIRECT_PARAM correctly did not match itself"); }
2828
}
2929
}

src/test/ui/rfc1445/issue-62307-match-ref-ref-forbidden-without-eq.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,14 @@ fn main() {
3030
match RR_B0 {
3131
RR_B1 => { println!("CLAIM RR0: {:?} matches {:?}", RR_B1, RR_B0); }
3232
//~^ WARN must be annotated with `#[derive(PartialEq, Eq)]`
33-
//~| WARN will become a hard error in a future release
33+
//~| WARN this was previously accepted
3434
_ => { }
3535
}
3636

3737
match RR_B1 {
3838
RR_B1 => { println!("CLAIM RR1: {:?} matches {:?}", RR_B1, RR_B1); }
3939
//~^ WARN must be annotated with `#[derive(PartialEq, Eq)]`
40-
//~| WARN will become a hard error in a future release
40+
//~| WARN this was previously accepted
4141
_ => { }
4242
}
4343
}

0 commit comments

Comments
 (0)