diff --git a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs index 6ca1ff2c5f2e..ad0bcfeb367f 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs @@ -43,7 +43,7 @@ struct ConstToPat<'a, 'tcx> { span: Span, 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 // value. saw_const_match_error: Cell, @@ -103,7 +103,7 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> { // once indirect_structural_match is a full fledged error, this // 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 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). - 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 span = self.span; let tcx = self.tcx(); @@ -227,7 +227,7 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> { .enumerate() .map(|(idx, val)| { let field = Field::new(idx); - FieldPat { field, pattern: self.recur(val) } + FieldPat { field, pattern: self.recur(val, false) } }) .collect() }; @@ -248,6 +248,21 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> { tcx.sess.span_err(span, "cannot use unions in constant patterns"); 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, // causing the pattern match code to treat it opaquely. // 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 // 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); + 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 } } 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)) .fields .iter() - .map(|val| self.recur(val)) + .map(|val| self.recur(val, false)) .collect(), slice: None, suffix: Vec::new(), }, ty::Ref(_, pointee_ty, ..) => match *pointee_ty.kind() { // 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 // optimization for now. ty::Str => PatKind::Constant { value: cv }, @@ -321,7 +354,7 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> { .destructure_const(param_env.and(array)) .fields .iter() - .map(|val| self.recur(val)) + .map(|val| self.recur(val, false)) .collect(), slice: None, suffix: vec![], @@ -333,16 +366,21 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> { self.behind_reference.set(old); val } - // Backwards compatibility hack. Don't take away the reference, since - // `PartialEq::eq` takes a reference, this makes the rest of the matching logic - // simpler. + // Backwards compatibility hack: support references to non-structural types. + // We'll lower + // 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) => { 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 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); val @@ -373,11 +411,34 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> { 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 } }; + 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) } } } diff --git a/compiler/rustc_session/src/lint/builtin.rs b/compiler/rustc_session/src/lint/builtin.rs index c72b97fa1cab..919aaf81ed20 100644 --- a/compiler/rustc_session/src/lint/builtin.rs +++ b/compiler/rustc_session/src/lint/builtin.rs @@ -2138,22 +2138,16 @@ declare_lint! { /// ```rust,compile_fail /// #![deny(indirect_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 {} - /// + /// struct NoDerive(i32); + /// impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } } + /// impl Eq for NoDerive { } + /// #[derive(PartialEq, Eq)] + /// struct WrapParam(T); + /// const WRAP_INDIRECT_PARAM: & &WrapParam = & &WrapParam(NoDerive(0)); /// fn main() { - /// if let ONE_PLUS_TWO = &&Plus(3, 0) { - /// println!("semantic!"); - /// } else { - /// println!("structural!"); + /// match WRAP_INDIRECT_PARAM { + /// WRAP_INDIRECT_PARAM => { } + /// _ => { } /// } /// } /// ``` @@ -2170,9 +2164,8 @@ declare_lint! { /// [issue #62411]: https://github.com/rust-lang/rust/issues/62411 /// [future-incompatible]: ../index.md#future-incompatible-lints pub INDIRECT_STRUCTURAL_MATCH, - // defaulting to allow until rust-lang/rust#62614 is fixed. - Allow, - "pattern with const indirectly referencing non-structural-match type", + Warn, + "constant used in pattern contains value of non-structural-match type in a field or a variant", @future_incompatible = FutureIncompatibleInfo { reference: "issue #62411 ", 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` 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 ", + edition: None, + }; +} + declare_lint! { /// The `ambiguous_associated_items` lint detects ambiguity between /// [associated items] and [enum variants]. @@ -2657,6 +2690,7 @@ declare_lint_pass! { MUTABLE_BORROW_RESERVATION_CONFLICT, INDIRECT_STRUCTURAL_MATCH, POINTER_STRUCTURAL_MATCH, + NONTRIVIAL_STRUCTURAL_MATCH, SOFT_UNSTABLE, INLINE_NO_SANITIZE, ASM_SUB_REGISTER, diff --git a/src/test/ui/consts/const_in_pattern/custom-eq-branch-warn.rs b/src/test/ui/consts/const_in_pattern/custom-eq-branch-warn.rs index a1f9838ca088..856d204178d4 100644 --- a/src/test/ui/consts/const_in_pattern/custom-eq-branch-warn.rs +++ b/src/test/ui/consts/const_in_pattern/custom-eq-branch-warn.rs @@ -1,8 +1,5 @@ // check-pass -#![warn(indirect_structural_match)] -//~^ NOTE lint level is defined here - struct CustomEq; impl Eq for CustomEq {} @@ -32,7 +29,8 @@ fn main() { BAR_BAZ => panic!(), //~^ WARN must be annotated with `#[derive(PartialEq, Eq)]` //~| WARN this was previously accepted - //~| NOTE see issue #62411 + //~| NOTE see issue #73448 + //~| NOTE `#[warn(nontrivial_structural_match)]` on by default _ => {} } } diff --git a/src/test/ui/consts/const_in_pattern/custom-eq-branch-warn.stderr b/src/test/ui/consts/const_in_pattern/custom-eq-branch-warn.stderr index 0be1cca806ed..fd6732195e49 100644 --- a/src/test/ui/consts/const_in_pattern/custom-eq-branch-warn.stderr +++ b/src/test/ui/consts/const_in_pattern/custom-eq-branch-warn.stderr @@ -1,16 +1,12 @@ -warning: to use a constant of type `CustomEq` in a pattern, `CustomEq` must be annotated with `#[derive(PartialEq, Eq)]` - --> $DIR/custom-eq-branch-warn.rs:32:9 +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:29:9 | LL | BAR_BAZ => panic!(), | ^^^^^^^ | -note: the lint level is defined here - --> $DIR/custom-eq-branch-warn.rs:3:9 - | -LL | #![warn(indirect_structural_match)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ + = 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 #62411 + = note: for more information, see issue #73448 warning: 1 warning emitted diff --git a/src/test/ui/consts/const_in_pattern/issue-65466.rs b/src/test/ui/consts/const_in_pattern/issue-65466.rs index 0e3e0f6dd883..2b421f4c705e 100644 --- a/src/test/ui/consts/const_in_pattern/issue-65466.rs +++ b/src/test/ui/consts/const_in_pattern/issue-65466.rs @@ -1,9 +1,7 @@ -// FIXME: This still ICEs. -// -// ignore-test - #![deny(indirect_structural_match)] +// check-pass + #[derive(PartialEq, Eq)] enum O { Some(*const T), // Can also use PhantomData diff --git a/src/test/ui/consts/const_in_pattern/issue-65466.stderr b/src/test/ui/consts/const_in_pattern/issue-65466.stderr deleted file mode 100644 index 9fe3049d1d85..000000000000 --- a/src/test/ui/consts/const_in_pattern/issue-65466.stderr +++ /dev/null @@ -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 { -... | -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`. diff --git a/src/test/ui/consts/const_in_pattern/reject_non_partial_eq.rs b/src/test/ui/consts/const_in_pattern/reject_non_partial_eq.rs index a8216901c027..b2b2daa830f8 100644 --- a/src/test/ui/consts/const_in_pattern/reject_non_partial_eq.rs +++ b/src/test/ui/consts/const_in_pattern/reject_non_partial_eq.rs @@ -27,6 +27,7 @@ fn main() { match 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)]` _ => panic!("whoops"), } } diff --git a/src/test/ui/consts/const_in_pattern/reject_non_partial_eq.stderr b/src/test/ui/consts/const_in_pattern/reject_non_partial_eq.stderr index 95cfa4a9ebe9..dc830d360031 100644 --- a/src/test/ui/consts/const_in_pattern/reject_non_partial_eq.stderr +++ b/src/test/ui/consts/const_in_pattern/reject_non_partial_eq.stderr @@ -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` in a pattern, `Option` 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 previous error +error: to use a constant of type `Option` in a pattern, `Option` 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 diff --git a/src/test/ui/consts/const_in_pattern/warn_corner_cases.stderr b/src/test/ui/consts/const_in_pattern/warn_corner_cases.stderr index 3e7ed573c74d..a4feaff55b2e 100644 --- a/src/test/ui/consts/const_in_pattern/warn_corner_cases.stderr +++ b/src/test/ui/consts/const_in_pattern/warn_corner_cases.stderr @@ -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` 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 | LL | match None { Some(_) => panic!("whoops"), INDEX => dbg!(INDEX), }; | ^^^^^ | -note: the lint level is defined here - --> $DIR/warn_corner_cases.rs:15:9 - | -LL | #![warn(indirect_structural_match)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ + = 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 #62411 + = note: for more information, see issue #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` 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 | 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! - = note: for more information, see issue #62411 + = note: for more information, see issue #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` 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 | 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! - = note: for more information, see issue #62411 + = note: for more information, see issue #73448 warning: 3 warnings emitted diff --git a/src/test/ui/consts/match_ice.rs b/src/test/ui/consts/match_ice.rs index 008c03ecddcc..db76e2300708 100644 --- a/src/test/ui/consts/match_ice.rs +++ b/src/test/ui/consts/match_ice.rs @@ -8,8 +8,10 @@ struct T; fn main() { const C: &S = &S; match C { + //~^ non-exhaustive patterns: `&S` not covered 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; match K { diff --git a/src/test/ui/consts/match_ice.stderr b/src/test/ui/consts/match_ice.stderr index 699b4a5e200e..6cc79dbca7cc 100644 --- a/src/test/ui/consts/match_ice.stderr +++ b/src/test/ui/consts/match_ice.stderr @@ -1,8 +1,25 @@ -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 +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 | 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 -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`. diff --git a/src/test/ui/issues/issue-34784.rs b/src/test/ui/issues/issue-34784.rs index d3206e994300..98d943470a7f 100644 --- a/src/test/ui/issues/issue-34784.rs +++ b/src/test/ui/issues/issue-34784.rs @@ -1,4 +1,6 @@ // run-pass + +#![warn(pointer_structural_match)] #![allow(dead_code)] const C: *const u8 = &0; diff --git a/src/test/ui/match/issue-70972-dyn-trait.rs b/src/test/ui/match/issue-70972-dyn-trait.rs index a9b2699cafdc..b69e2dab2650 100644 --- a/src/test/ui/match/issue-70972-dyn-trait.rs +++ b/src/test/ui/match/issue-70972-dyn-trait.rs @@ -4,7 +4,8 @@ fn main() { let a: &dyn Send = &7u32; match a { 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 _ => {} } } diff --git a/src/test/ui/match/issue-70972-dyn-trait.stderr b/src/test/ui/match/issue-70972-dyn-trait.stderr index a4e827357de6..985799b3c835 100644 --- a/src/test/ui/match/issue-70972-dyn-trait.stderr +++ b/src/test/ui/match/issue-70972-dyn-trait.stderr @@ -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 | 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 diff --git a/src/test/ui/pattern/issue-71042-opaquely-typed-constant-used-in-pattern.rs b/src/test/ui/pattern/issue-71042-opaquely-typed-constant-used-in-pattern.rs index c5e4a72fb9ff..0c38b533a16e 100644 --- a/src/test/ui/pattern/issue-71042-opaquely-typed-constant-used-in-pattern.rs +++ b/src/test/ui/pattern/issue-71042-opaquely-typed-constant-used-in-pattern.rs @@ -4,6 +4,8 @@ fn main() { const C: impl Copy = 0; 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 + _ => {} } } diff --git a/src/test/ui/pattern/issue-71042-opaquely-typed-constant-used-in-pattern.stderr b/src/test/ui/pattern/issue-71042-opaquely-typed-constant-used-in-pattern.stderr index 7695223f2cf9..ad6cc0aa3e3e 100644 --- a/src/test/ui/pattern/issue-71042-opaquely-typed-constant-used-in-pattern.stderr +++ b/src/test/ui/pattern/issue-71042-opaquely-typed-constant-used-in-pattern.stderr @@ -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 | -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 diff --git a/src/test/ui/rfc1445/allow-hide-behind-direct-unsafe-ptr-embedded.rs b/src/test/ui/rfc1445/allow-hide-behind-direct-unsafe-ptr-embedded.rs index b90a750cc16c..c6d7166e7406 100644 --- a/src/test/ui/rfc1445/allow-hide-behind-direct-unsafe-ptr-embedded.rs +++ b/src/test/ui/rfc1445/allow-hide-behind-direct-unsafe-ptr-embedded.rs @@ -3,6 +3,8 @@ // run-pass +#![warn(pointer_structural_match)] + struct NoDerive(i32); // This impl makes NoDerive irreflexive diff --git a/src/test/ui/rfc1445/allow-hide-behind-direct-unsafe-ptr-param.rs b/src/test/ui/rfc1445/allow-hide-behind-direct-unsafe-ptr-param.rs index 1076b9f25d89..cc7ea6cde8d7 100644 --- a/src/test/ui/rfc1445/allow-hide-behind-direct-unsafe-ptr-param.rs +++ b/src/test/ui/rfc1445/allow-hide-behind-direct-unsafe-ptr-param.rs @@ -3,6 +3,8 @@ // run-pass +#![warn(pointer_structural_match)] + struct NoDerive(i32); // This impl makes NoDerive irreflexive diff --git a/src/test/ui/rfc1445/allow-hide-behind-indirect-unsafe-ptr-embedded.rs b/src/test/ui/rfc1445/allow-hide-behind-indirect-unsafe-ptr-embedded.rs index a4b832d377d6..86db09cc08fc 100644 --- a/src/test/ui/rfc1445/allow-hide-behind-indirect-unsafe-ptr-embedded.rs +++ b/src/test/ui/rfc1445/allow-hide-behind-indirect-unsafe-ptr-embedded.rs @@ -3,6 +3,8 @@ // run-pass +#![warn(pointer_structural_match)] + struct NoDerive(i32); // This impl makes NoDerive irreflexive diff --git a/src/test/ui/rfc1445/allow-hide-behind-indirect-unsafe-ptr-param.rs b/src/test/ui/rfc1445/allow-hide-behind-indirect-unsafe-ptr-param.rs index 47b70e2e9cc5..99c574d07804 100644 --- a/src/test/ui/rfc1445/allow-hide-behind-indirect-unsafe-ptr-param.rs +++ b/src/test/ui/rfc1445/allow-hide-behind-indirect-unsafe-ptr-param.rs @@ -3,6 +3,8 @@ // run-pass +#![warn(pointer_structural_match)] + struct NoDerive(i32); // This impl makes NoDerive irreflexive diff --git a/src/test/ui/rfc1445/cant-hide-behind-doubly-indirect-embedded.stderr b/src/test/ui/rfc1445/cant-hide-behind-doubly-indirect-embedded.stderr index 659a98126723..eb13eed6ec11 100644 --- a/src/test/ui/rfc1445/cant-hide-behind-doubly-indirect-embedded.stderr +++ b/src/test/ui/rfc1445/cant-hide-behind-doubly-indirect-embedded.stderr @@ -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 | LL | WRAP_DOUBLY_INDIRECT_INLINE => { panic!("WRAP_DOUBLY_INDIRECT_INLINE matched itself"); } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: the lint level is defined here - --> $DIR/cant-hide-behind-doubly-indirect-embedded.rs:7:9 - | -LL | #![warn(indirect_structural_match)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ + = 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 #62411 + = note: for more information, see issue #73448 warning: 1 warning emitted diff --git a/src/test/ui/rfc1445/cant-hide-behind-doubly-indirect-param.stderr b/src/test/ui/rfc1445/cant-hide-behind-doubly-indirect-param.stderr index c8c36510542a..ddee99e76bbb 100644 --- a/src/test/ui/rfc1445/cant-hide-behind-doubly-indirect-param.stderr +++ b/src/test/ui/rfc1445/cant-hide-behind-doubly-indirect-param.stderr @@ -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` 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 | LL | WRAP_DOUBLY_INDIRECT_PARAM => { panic!("WRAP_DOUBLY_INDIRECT_PARAM matched itself"); } | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: the lint level is defined here - --> $DIR/cant-hide-behind-doubly-indirect-param.rs:7:9 - | -LL | #![warn(indirect_structural_match)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ + = 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 #62411 + = note: for more information, see issue #73448 warning: 1 warning emitted diff --git a/src/test/ui/rfc1445/issue-62307-match-ref-ref-forbidden-without-eq.rs b/src/test/ui/rfc1445/issue-62307-match-ref-ref-forbidden-without-eq.rs index 6ebb948d736e..b5e19611da83 100644 --- a/src/test/ui/rfc1445/issue-62307-match-ref-ref-forbidden-without-eq.rs +++ b/src/test/ui/rfc1445/issue-62307-match-ref-ref-forbidden-without-eq.rs @@ -10,7 +10,7 @@ // Issue 62307 pointed out a case where the structural-match checking // was too shallow. -#![warn(indirect_structural_match)] +#![warn(indirect_structural_match, nontrivial_structural_match)] // run-pass #[derive(Debug)] diff --git a/src/test/ui/rfc1445/issue-62307-match-ref-ref-forbidden-without-eq.stderr b/src/test/ui/rfc1445/issue-62307-match-ref-ref-forbidden-without-eq.stderr index ae011dfcdba9..7f4b4923332a 100644 --- a/src/test/ui/rfc1445/issue-62307-match-ref-ref-forbidden-without-eq.stderr +++ b/src/test/ui/rfc1445/issue-62307-match-ref-ref-forbidden-without-eq.stderr @@ -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 | LL | RR_B1 => { println!("CLAIM RR0: {:?} matches {:?}", RR_B1, RR_B0); } | ^^^^^ | 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! - = note: for more information, see issue #62411 + = note: for more information, see issue #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 | 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! - = note: for more information, see issue #62411 + = note: for more information, see issue #73448 warning: 2 warnings emitted diff --git a/src/test/ui/type-alias-impl-trait/structural-match-no-leak.rs b/src/test/ui/type-alias-impl-trait/structural-match-no-leak.rs index 479d6cd9af76..54fc4956b9b2 100644 --- a/src/test/ui/type-alias-impl-trait/structural-match-no-leak.rs +++ b/src/test/ui/type-alias-impl-trait/structural-match-no-leak.rs @@ -12,9 +12,10 @@ const LEAK_FREE: Bar = leak_free(); fn leak_free_test() { match todo!() { 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() {} diff --git a/src/test/ui/type-alias-impl-trait/structural-match-no-leak.stderr b/src/test/ui/type-alias-impl-trait/structural-match-no-leak.stderr index ae0d8e8d4239..90b44f6598df 100644 --- a/src/test/ui/type-alias-impl-trait/structural-match-no-leak.stderr +++ b/src/test/ui/type-alias-impl-trait/structural-match-no-leak.stderr @@ -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 | 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 diff --git a/src/test/ui/type-alias-impl-trait/structural-match.rs b/src/test/ui/type-alias-impl-trait/structural-match.rs index 481448d64b1a..5fe5bb4bdeaa 100644 --- a/src/test/ui/type-alias-impl-trait/structural-match.rs +++ b/src/test/ui/type-alias-impl-trait/structural-match.rs @@ -13,9 +13,10 @@ const VALUE: Foo = value(); fn test() { match todo!() { 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() {} diff --git a/src/test/ui/type-alias-impl-trait/structural-match.stderr b/src/test/ui/type-alias-impl-trait/structural-match.stderr index ad9036a87d1d..7aca3ba8640f 100644 --- a/src/test/ui/type-alias-impl-trait/structural-match.stderr +++ b/src/test/ui/type-alias-impl-trait/structural-match.stderr @@ -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 | 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