diff options
| author | Ralf Jung <post@ralfj.de> | 2024-05-03 15:24:53 +0200 |
|---|---|---|
| committer | Ralf Jung <post@ralfj.de> | 2024-05-03 15:56:59 +0200 |
| commit | 179a6a08b127c7670ec648c245d8c31c6ac2419c (patch) | |
| tree | abd968e641e7e134599649ab366c36a0e9359dfc /compiler | |
| parent | 79734f1db8dbe322192dea32c0f6b80ab14c4c1d (diff) | |
| download | rust-179a6a08b127c7670ec648c245d8c31c6ac2419c.tar.gz rust-179a6a08b127c7670ec648c245d8c31c6ac2419c.zip | |
remove IndirectStructuralMatch lint, emit the usual hard error instead
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/rustc_lint/src/lib.rs | 5 | ||||
| -rw-r--r-- | compiler/rustc_lint_defs/src/builtin.rs | 47 | ||||
| -rw-r--r-- | compiler/rustc_mir_build/messages.ftl | 6 | ||||
| -rw-r--r-- | compiler/rustc_mir_build/src/errors.rs | 16 | ||||
| -rw-r--r-- | compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs | 76 |
5 files changed, 8 insertions, 142 deletions
diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index a78b410f500..b3a7f50e8ea 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -539,6 +539,11 @@ fn register_builtins(store: &mut LintStore) { "converted into hard error, see RFC #3535 \ <https://rust-lang.github.io/rfcs/3535-constants-in-patterns.html> for more information", ); + store.register_removed( + "indirect_structural_match", + "converted into hard error, see RFC #3535 \ + <https://rust-lang.github.io/rfcs/3535-constants-in-patterns.html> for more information", + ); } fn register_internals(store: &mut LintStore) { diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index c7996c27c2f..6da6b39bac1 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -50,7 +50,6 @@ declare_lint_pass! { HIDDEN_GLOB_REEXPORTS, ILL_FORMED_ATTRIBUTE_INPUT, INCOMPLETE_INCLUDE, - INDIRECT_STRUCTURAL_MATCH, INEFFECTIVE_UNSTABLE_TRAIT_IMPL, INLINE_NO_SANITIZE, INVALID_DOC_ATTRIBUTES, @@ -2356,52 +2355,6 @@ declare_lint! { } declare_lint! { - /// The `indirect_structural_match` lint detects a `const` in a pattern - /// that manually implements [`PartialEq`] and [`Eq`]. - /// - /// [`PartialEq`]: https://doc.rust-lang.org/std/cmp/trait.PartialEq.html - /// [`Eq`]: https://doc.rust-lang.org/std/cmp/trait.Eq.html - /// - /// ### Example - /// - /// ```rust,compile_fail - /// #![deny(indirect_structural_match)] - /// - /// struct NoDerive(i32); - /// impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } } - /// impl Eq for NoDerive { } - /// #[derive(PartialEq, Eq)] - /// struct WrapParam<T>(T); - /// const WRAP_INDIRECT_PARAM: & &WrapParam<NoDerive> = & &WrapParam(NoDerive(0)); - /// fn main() { - /// match WRAP_INDIRECT_PARAM { - /// WRAP_INDIRECT_PARAM => { } - /// _ => { } - /// } - /// } - /// ``` - /// - /// {{produces}} - /// - /// ### Explanation - /// - /// The compiler unintentionally accepted this form in the past. This is a - /// [future-incompatible] lint to transition this to a hard error in the - /// future. See [issue #62411] for a complete description of the problem, - /// and some possible solutions. - /// - /// [issue #62411]: https://github.com/rust-lang/rust/issues/62411 - /// [future-incompatible]: ../index.md#future-incompatible-lints - pub INDIRECT_STRUCTURAL_MATCH, - Warn, - "constant used in pattern contains value of non-structural-match type in a field or a variant", - @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::FutureReleaseErrorReportInDeps, - reference: "issue #120362 <https://github.com/rust-lang/rust/issues/120362>", - }; -} - -declare_lint! { /// The `deprecated_in_future` lint is internal to rustc and should not be /// used by user code. /// diff --git a/compiler/rustc_mir_build/messages.ftl b/compiler/rustc_mir_build/messages.ftl index 34440c60cf3..c1d340fa2d1 100644 --- a/compiler/rustc_mir_build/messages.ftl +++ b/compiler/rustc_mir_build/messages.ftl @@ -109,9 +109,6 @@ mir_build_extern_static_requires_unsafe_unsafe_op_in_unsafe_fn_allowed = .note = extern statics are not controlled by the Rust type system: invalid data, aliasing violations or data races will cause undefined behavior .label = use of extern static -mir_build_indirect_structural_match = - to use a constant of type `{$non_sm_ty}` in a pattern, `{$non_sm_ty}` must be annotated with `#[derive(PartialEq)]` - mir_build_inform_irrefutable = `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant mir_build_initializing_type_with_requires_unsafe = @@ -257,9 +254,6 @@ mir_build_non_exhaustive_patterns_type_not_empty = non-exhaustive patterns: type mir_build_non_partial_eq_match = to use a constant of type `{$non_peq_ty}` in a pattern, the type must implement `PartialEq` -mir_build_nontrivial_structural_match = - to use a constant of type `{$non_sm_ty}` in a pattern, the constant's initializer must be trivial or `{$non_sm_ty}` must be annotated with `#[derive(PartialEq)]` - mir_build_pattern_not_covered = refutable pattern in {$origin} .pattern_ty = the matched value is of type `{$pattern_ty}` diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs index f67113afd6d..1d52c2723aa 100644 --- a/compiler/rustc_mir_build/src/errors.rs +++ b/compiler/rustc_mir_build/src/errors.rs @@ -802,22 +802,6 @@ pub struct NonEmptyNeverPattern<'tcx> { pub ty: Ty<'tcx>, } -#[derive(LintDiagnostic)] -#[diag(mir_build_indirect_structural_match)] -#[note(mir_build_type_not_structural_tip)] -#[note(mir_build_type_not_structural_more_info)] -pub struct IndirectStructuralMatch<'tcx> { - pub non_sm_ty: Ty<'tcx>, -} - -#[derive(LintDiagnostic)] -#[diag(mir_build_nontrivial_structural_match)] -#[note(mir_build_type_not_structural_tip)] -#[note(mir_build_type_not_structural_more_info)] -pub struct NontrivialStructuralMatch<'tcx> { - pub non_sm_ty: Ty<'tcx>, -} - #[derive(Diagnostic)] #[diag(mir_build_exceeds_mcdc_condition_num_limit)] pub(crate) struct MCDCExceedsConditionNumLimit { 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 65c53be8ddd..6d2e740af40 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 @@ -16,8 +16,8 @@ use std::cell::Cell; use super::PatCtxt; use crate::errors::{ - IndirectStructuralMatch, InvalidPattern, NaNPattern, PointerPattern, TypeNotPartialEq, - TypeNotStructural, UnionPattern, UnsizedPattern, + InvalidPattern, NaNPattern, PointerPattern, TypeNotPartialEq, TypeNotStructural, UnionPattern, + UnsizedPattern, }; impl<'a, 'tcx> PatCtxt<'a, 'tcx> { @@ -49,15 +49,6 @@ struct ConstToPat<'tcx> { // value. saw_const_match_error: Cell<Option<ErrorGuaranteed>>, - // 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>, - // inference context used for checking `T: Structural` bounds. infcx: InferCtxt<'tcx>, @@ -84,8 +75,6 @@ impl<'tcx> ConstToPat<'tcx> { infcx, param_env: pat_ctxt.param_env, saw_const_match_error: Cell::new(None), - saw_const_match_lint: Cell::new(false), - behind_reference: Cell::new(false), treat_byte_string_as_slice: pat_ctxt .typeck_results .treat_byte_string_as_slice @@ -197,7 +186,7 @@ impl<'tcx> ConstToPat<'tcx> { // complained about structural match violations there, so we don't // have to check anything any more. } - } else if !have_valtree && !self.saw_const_match_lint.get() { + } else if !have_valtree { // The only way valtree construction can fail without the structural match // checker finding a violation is if there is a pointer somewhere. self.tcx().emit_node_span_lint( @@ -274,36 +263,11 @@ impl<'tcx> ConstToPat<'tcx> { cv: ValTree<'tcx>, ty: Ty<'tcx>, ) -> Result<Box<Pat<'tcx>>, FallbackToOpaqueConst> { - let id = self.id; let span = self.span; let tcx = self.tcx(); let param_env = self.param_env; let kind = match ty.kind() { - // 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. - // So instead of specific errors, you just get blanket errors about the whole - // const type. See - // https://github.com/rust-lang/rust/pull/70743#discussion_r404701963 for - // details. - // 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(ty) && self.behind_reference.get() => { - if self.saw_const_match_error.get().is_none() && !self.saw_const_match_lint.get() { - self.saw_const_match_lint.set(true); - tcx.emit_node_span_lint( - lint::builtin::INDIRECT_STRUCTURAL_MATCH, - id, - span, - IndirectStructuralMatch { non_sm_ty: ty }, - ); - } - // Since we are behind a reference, we can just bubble the error up so we get a - // constant at reference type, making it easy to let the fallback call - // `PartialEq::eq` on it. - return Err(FallbackToOpaqueConst); - } ty::FnDef(..) => { let e = tcx.dcx().emit_err(InvalidPattern { span, non_sm_ty: ty }); self.saw_const_match_error.set(Some(e)); @@ -377,38 +341,6 @@ impl<'tcx> ConstToPat<'tcx> { ty::Str => { PatKind::Constant { value: mir::Const::Ty(ty::Const::new_value(tcx, cv, ty)) } } - // Backwards compatibility hack: support references to non-structural types, - // but hard error if we aren't behind a double reference. We could just use - // the fallback code path below, but that would allow *more* of this fishy - // code to compile, as then it only goes through the future incompat lint - // instead of a hard error. - ty::Adt(_, _) if !self.type_marked_structural(*pointee_ty) => { - if self.behind_reference.get() { - if self.saw_const_match_error.get().is_none() - && !self.saw_const_match_lint.get() - { - self.saw_const_match_lint.set(true); - tcx.emit_node_span_lint( - lint::builtin::INDIRECT_STRUCTURAL_MATCH, - self.id, - span, - IndirectStructuralMatch { non_sm_ty: *pointee_ty }, - ); - } - return Err(FallbackToOpaqueConst); - } else { - if let Some(e) = self.saw_const_match_error.get() { - // We already errored. Signal that in the pattern, so that follow up errors can be silenced. - PatKind::Error(e) - } else { - let err = TypeNotStructural { span, non_sm_ty: *pointee_ty }; - let e = tcx.dcx().emit_err(err); - self.saw_const_match_error.set(Some(e)); - // We errored. Signal that in the pattern, so that follow up errors can be silenced. - PatKind::Error(e) - } - } - } // 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. @@ -419,7 +351,6 @@ impl<'tcx> ConstToPat<'tcx> { // We errored. Signal that in the pattern, so that follow up errors can be silenced. PatKind::Error(e) } else { - let old = self.behind_reference.replace(true); // `b"foo"` produces a `&[u8; 3]`, but you can't use constants of array type when // matching against references, you can only use byte string literals. // The typechecker has a special case for byte string literals, by treating them @@ -434,7 +365,6 @@ impl<'tcx> ConstToPat<'tcx> { }; // References have the same valtree representation as their pointee. let subpattern = self.recur(cv, pointee_ty)?; - self.behind_reference.set(old); PatKind::Deref { subpattern } } } |
