Rollup merge of #133233 - estebank:const-errors, r=Nadrieril

Add context to "const in pattern" errors

*Each commit addresses specific diagnostics.*

- Add primary span labels
- Point at `const` item, and `const` generic param definition
- Reword messages and notes
- Point at generic param through which an associated `const` is being referenced
- Silence const in pattern with evaluation errors when they come from `const` items that already emit a diagnostic
- On non-structural type in const used as pattern, point at the type that should derive `PartialEq`
This commit is contained in:
León Orell Valerian Liehr 2024-12-05 07:29:54 +01:00 committed by GitHub
commit 626db06409
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
88 changed files with 1123 additions and 517 deletions

View File

@ -84,12 +84,17 @@ mir_build_call_to_unsafe_fn_requires_unsafe_unsafe_op_in_unsafe_fn_allowed =
mir_build_confused = missing patterns are not covered because `{$variable}` is interpreted as a constant pattern, not a new variable
mir_build_const_param_in_pattern = const parameters cannot be referenced in patterns
mir_build_const_defined_here = constant defined here
mir_build_const_pattern_depends_on_generic_parameter =
constant pattern depends on a generic parameter
mir_build_const_param_in_pattern = constant parameters cannot be referenced in patterns
.label = can't be used in patterns
mir_build_const_param_in_pattern_def = constant defined here
mir_build_const_pattern_depends_on_generic_parameter = constant pattern cannot depend on generic parameters
.label = `const` depends on a generic parameter
mir_build_could_not_eval_const_pattern = could not evaluate constant pattern
.label = could not evaluate constant
mir_build_deref_raw_pointer_requires_unsafe =
dereference of raw pointer is unsafe and requires unsafe block
@ -147,7 +152,8 @@ mir_build_inline_assembly_requires_unsafe_unsafe_op_in_unsafe_fn_allowed =
mir_build_interpreted_as_const = introduce a variable instead
mir_build_invalid_pattern = `{$non_sm_ty}` cannot be used in patterns
mir_build_invalid_pattern = {$prefix} `{$non_sm_ty}` cannot be used in patterns
.label = {$prefix} can't be used in patterns
mir_build_irrefutable_let_patterns_if_let = irrefutable `if let` {$count ->
[one] pattern
@ -244,10 +250,12 @@ mir_build_mutation_of_layout_constrained_field_requires_unsafe_unsafe_op_in_unsa
.label = mutation of layout constrained field
mir_build_nan_pattern = cannot use NaN in patterns
.label = evaluates to `NaN`, which is not allowed in patterns
.note = NaNs compare inequal to everything, even themselves, so this pattern would never match
.help = try using the `is_nan` method instead
mir_build_non_const_path = runtime values cannot be referenced in patterns
.label = references a runtime value
mir_build_non_empty_never_pattern =
mismatched types
@ -265,13 +273,15 @@ mir_build_non_exhaustive_patterns_type_not_empty = non-exhaustive patterns: type
.suggestion = ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
.help = ensure that all possible cases are being handled by adding a match arm with a wildcard pattern
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_non_partial_eq_match = constant of non-structural type `{$ty}` in a pattern
.label = constant of non-structural type
mir_build_pattern_not_covered = refutable pattern in {$origin}
.pattern_ty = the matched value is of type `{$pattern_ty}`
mir_build_pointer_pattern = function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
mir_build_pointer_pattern = function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon
.label = can't be used in patterns
.note = see https://github.com/rust-lang/rust/issues/70861 for details
mir_build_privately_uninhabited = pattern `{$witness_1}` is currently uninhabited, but this variant contains private fields which may become inhabited in the future
@ -283,6 +293,8 @@ mir_build_rustc_box_attribute_error = `#[rustc_box]` attribute used incorrectly
.missing_box = `#[rustc_box]` requires the `owned_box` lang item
mir_build_static_in_pattern = statics cannot be referenced in patterns
.label = can't be used in patterns
mir_build_static_in_pattern_def = `static` defined here
mir_build_suggest_attempted_int_lit = alternatively, you could prepend the pattern with an underscore to define a new named variable; identifiers cannot begin with digits
@ -310,12 +322,12 @@ mir_build_trailing_irrefutable_let_patterns = trailing irrefutable {$count ->
*[other] them
} into the body
mir_build_type_not_structural =
to use a constant of type `{$non_sm_ty}` in a pattern, `{$non_sm_ty}` must be annotated with `#[derive(PartialEq)]`
mir_build_type_not_structural = constant of non-structural type `{$ty}` in a pattern
.label = constant of non-structural type
mir_build_type_not_structural_def = `{$ty}` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
mir_build_type_not_structural_more_info = see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
mir_build_type_not_structural_tip = the traits must be derived, manual `impl`s are not sufficient
mir_build_type_not_structural_tip =
the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
mir_build_unconditional_recursion = function cannot return without recursing
.label = cannot return without recursing
@ -334,6 +346,7 @@ mir_build_union_field_requires_unsafe_unsafe_op_in_unsafe_fn_allowed =
.label = access to union field
mir_build_union_pattern = cannot use unions in constant patterns
.label = can't use a `union` here
mir_build_unreachable_making_this_unreachable = collectively making this unreachable

View File

@ -631,20 +631,27 @@ pub(crate) struct NonExhaustiveMatchAllArmsGuarded;
#[diag(mir_build_static_in_pattern, code = E0158)]
pub(crate) struct StaticInPattern {
#[primary_span]
#[label]
pub(crate) span: Span,
#[label(mir_build_static_in_pattern_def)]
pub(crate) static_span: Span,
}
#[derive(Diagnostic)]
#[diag(mir_build_const_param_in_pattern, code = E0158)]
pub(crate) struct ConstParamInPattern {
#[primary_span]
#[label]
pub(crate) span: Span,
#[label(mir_build_const_param_in_pattern_def)]
pub(crate) const_span: Span,
}
#[derive(Diagnostic)]
#[diag(mir_build_non_const_path, code = E0080)]
pub(crate) struct NonConstPath {
#[primary_span]
#[label]
pub(crate) span: Span,
}
@ -695,6 +702,7 @@ pub(crate) struct WantedConstant {
#[diag(mir_build_const_pattern_depends_on_generic_parameter, code = E0158)]
pub(crate) struct ConstPatternDependsOnGenericParameter {
#[primary_span]
#[label]
pub(crate) span: Span,
}
@ -702,6 +710,7 @@ pub(crate) struct ConstPatternDependsOnGenericParameter {
#[diag(mir_build_could_not_eval_const_pattern)]
pub(crate) struct CouldNotEvalConstPattern {
#[primary_span]
#[label]
pub(crate) span: Span,
}
@ -867,33 +876,43 @@ pub(crate) enum Conflict {
#[diag(mir_build_union_pattern)]
pub(crate) struct UnionPattern {
#[primary_span]
#[label]
pub(crate) span: Span,
}
#[derive(Diagnostic)]
#[diag(mir_build_type_not_structural)]
#[note(mir_build_type_not_structural_tip)]
#[note(mir_build_type_not_structural_more_info)]
pub(crate) struct TypeNotStructural<'tcx> {
#[primary_span]
#[label]
pub(crate) span: Span,
pub(crate) non_sm_ty: Ty<'tcx>,
#[label(mir_build_type_not_structural_def)]
pub(crate) ty_def_span: Span,
pub(crate) ty: Ty<'tcx>,
#[note(mir_build_type_not_structural_tip)]
pub(crate) manual_partialeq_impl_span: Option<Span>,
#[note(mir_build_type_not_structural_more_info)]
pub(crate) manual_partialeq_impl_note: bool,
}
#[derive(Diagnostic)]
#[diag(mir_build_non_partial_eq_match)]
#[note(mir_build_type_not_structural_more_info)]
pub(crate) struct TypeNotPartialEq<'tcx> {
#[primary_span]
#[label]
pub(crate) span: Span,
pub(crate) non_peq_ty: Ty<'tcx>,
pub(crate) ty: Ty<'tcx>,
}
#[derive(Diagnostic)]
#[diag(mir_build_invalid_pattern)]
pub(crate) struct InvalidPattern<'tcx> {
#[primary_span]
#[label]
pub(crate) span: Span,
pub(crate) non_sm_ty: Ty<'tcx>,
pub(crate) prefix: String,
}
#[derive(Diagnostic)]
@ -910,13 +929,16 @@ pub(crate) struct UnsizedPattern<'tcx> {
#[help]
pub(crate) struct NaNPattern {
#[primary_span]
#[label]
pub(crate) span: Span,
}
#[derive(Diagnostic)]
#[diag(mir_build_pointer_pattern)]
#[note]
pub(crate) struct PointerPattern {
#[primary_span]
#[label]
pub(crate) span: Span,
}

View File

@ -1,14 +1,17 @@
use rustc_abi::{FieldIdx, VariantIdx};
use rustc_apfloat::Float;
use rustc_data_structures::fx::FxHashSet;
use rustc_errors::Diag;
use rustc_hir as hir;
use rustc_index::Idx;
use rustc_infer::infer::TyCtxtInferExt;
use rustc_infer::traits::Obligation;
use rustc_middle::mir::interpret::ErrorHandled;
use rustc_middle::thir::{FieldPat, Pat, PatKind};
use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt, ValTree};
use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt, TypeVisitor, ValTree};
use rustc_middle::{mir, span_bug};
use rustc_span::Span;
use rustc_span::def_id::DefId;
use rustc_span::{Span, sym};
use rustc_trait_selection::traits::ObligationCause;
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
use tracing::{debug, instrument, trace};
@ -35,7 +38,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
id: hir::HirId,
span: Span,
) -> Box<Pat<'tcx>> {
let mut convert = ConstToPat::new(self, id, span);
let mut convert = ConstToPat::new(self, id, span, c);
match c.kind() {
ty::ConstKind::Unevaluated(uv) => convert.unevaluated_to_pat(uv, ty),
@ -49,21 +52,26 @@ struct ConstToPat<'tcx> {
tcx: TyCtxt<'tcx>,
typing_env: ty::TypingEnv<'tcx>,
span: Span,
id: hir::HirId,
treat_byte_string_as_slice: bool,
c: ty::Const<'tcx>,
}
impl<'tcx> ConstToPat<'tcx> {
fn new(pat_ctxt: &PatCtxt<'_, 'tcx>, id: hir::HirId, span: Span) -> Self {
fn new(pat_ctxt: &PatCtxt<'_, 'tcx>, id: hir::HirId, span: Span, c: ty::Const<'tcx>) -> Self {
trace!(?pat_ctxt.typeck_results.hir_owner);
ConstToPat {
tcx: pat_ctxt.tcx,
typing_env: pat_ctxt.typing_env,
span,
id,
treat_byte_string_as_slice: pat_ctxt
.typeck_results
.treat_byte_string_as_slice
.contains(&id.local_id),
c,
}
}
@ -71,13 +79,32 @@ impl<'tcx> ConstToPat<'tcx> {
ty.is_structural_eq_shallow(self.tcx)
}
/// We errored. Signal that in the pattern, so that follow up errors can be silenced.
fn mk_err(&self, mut err: Diag<'_>, ty: Ty<'tcx>) -> Box<Pat<'tcx>> {
if let ty::ConstKind::Unevaluated(uv) = self.c.kind() {
let def_kind = self.tcx.def_kind(uv.def);
if let hir::def::DefKind::AssocConst = def_kind
&& let Some(def_id) = uv.def.as_local()
{
// Include the container item in the output.
err.span_label(self.tcx.def_span(self.tcx.local_parent(def_id)), "");
}
if let hir::def::DefKind::Const | hir::def::DefKind::AssocConst = def_kind {
err.span_label(
self.tcx.def_span(uv.def),
crate::fluent_generated::mir_build_const_defined_here,
);
}
}
Box::new(Pat { span: self.span, ty, kind: PatKind::Error(err.emit()) })
}
fn unevaluated_to_pat(
&mut self,
uv: ty::UnevaluatedConst<'tcx>,
ty: Ty<'tcx>,
) -> Box<Pat<'tcx>> {
trace!(self.treat_byte_string_as_slice);
let pat_from_kind = |kind| Box::new(Pat { span: self.span, ty, kind });
// It's not *technically* correct to be revealing opaque types here as borrowcheck has
// not run yet. However, CTFE itself uses `TypingMode::PostAnalysis` unconditionally even
@ -96,32 +123,60 @@ impl<'tcx> ConstToPat<'tcx> {
Ok(Ok(c)) => c,
Err(ErrorHandled::Reported(_, _)) => {
// Let's tell the use where this failing const occurs.
let e = self.tcx.dcx().emit_err(CouldNotEvalConstPattern { span: self.span });
return pat_from_kind(PatKind::Error(e));
let mut err =
self.tcx.dcx().create_err(CouldNotEvalConstPattern { span: self.span });
// We've emitted an error on the original const, it would be redundant to complain
// on its use as well.
if let ty::ConstKind::Unevaluated(uv) = self.c.kind()
&& let hir::def::DefKind::Const | hir::def::DefKind::AssocConst =
self.tcx.def_kind(uv.def)
{
err.downgrade_to_delayed_bug();
}
return self.mk_err(err, ty);
}
Err(ErrorHandled::TooGeneric(_)) => {
let e = self
let mut e = self
.tcx
.dcx()
.emit_err(ConstPatternDependsOnGenericParameter { span: self.span });
return pat_from_kind(PatKind::Error(e));
.create_err(ConstPatternDependsOnGenericParameter { span: self.span });
for arg in uv.args {
if let ty::GenericArgKind::Type(ty) = arg.unpack()
&& let ty::Param(param_ty) = ty.kind()
{
let def_id = self.tcx.hir().enclosing_body_owner(self.id);
let generics = self.tcx.generics_of(def_id);
let param = generics.type_param(*param_ty, self.tcx);
let span = self.tcx.def_span(param.def_id);
e.span_label(span, "constant depends on this generic parameter");
if let Some(ident) = self.tcx.def_ident_span(def_id)
&& self.tcx.sess.source_map().is_multiline(ident.between(span))
{
// Display the `fn` name as well in the diagnostic, as the generic isn't
// in the same line and it could be confusing otherwise.
e.span_label(ident, "");
}
}
}
return self.mk_err(e, ty);
}
Ok(Err(bad_ty)) => {
// The pattern cannot be turned into a valtree.
let e = match bad_ty.kind() {
ty::Adt(def, ..) => {
assert!(def.is_union());
self.tcx.dcx().emit_err(UnionPattern { span: self.span })
self.tcx.dcx().create_err(UnionPattern { span: self.span })
}
ty::FnPtr(..) | ty::RawPtr(..) => {
self.tcx.dcx().emit_err(PointerPattern { span: self.span })
self.tcx.dcx().create_err(PointerPattern { span: self.span })
}
_ => self
.tcx
.dcx()
.emit_err(InvalidPattern { span: self.span, non_sm_ty: bad_ty }),
_ => self.tcx.dcx().create_err(InvalidPattern {
span: self.span,
non_sm_ty: bad_ty,
prefix: bad_ty.prefix_string(self.tcx).to_string(),
}),
};
return pat_from_kind(PatKind::Error(e));
return self.mk_err(e, ty);
}
};
@ -130,42 +185,16 @@ impl<'tcx> ConstToPat<'tcx> {
if !inlined_const_as_pat.references_error() {
// Always check for `PartialEq` if we had no other errors yet.
if !self.type_has_partial_eq_impl(ty) {
let err = TypeNotPartialEq { span: self.span, non_peq_ty: ty };
let e = self.tcx.dcx().emit_err(err);
return pat_from_kind(PatKind::Error(e));
if !type_has_partial_eq_impl(self.tcx, typing_env, ty).0 {
let mut err = self.tcx.dcx().create_err(TypeNotPartialEq { span: self.span, ty });
extend_type_not_partial_eq(self.tcx, typing_env, ty, &mut err);
return self.mk_err(err, ty);
}
}
inlined_const_as_pat
}
#[instrument(level = "trace", skip(self), ret)]
fn type_has_partial_eq_impl(&self, ty: Ty<'tcx>) -> bool {
let (infcx, param_env) = self.tcx.infer_ctxt().build_with_typing_env(self.typing_env);
// double-check there even *is* a semantic `PartialEq` to dispatch to.
//
// (If there isn't, then we can safely issue a hard
// error, because that's never worked, due to compiler
// using `PartialEq::eq` in this scenario in the past.)
let partial_eq_trait_id =
self.tcx.require_lang_item(hir::LangItem::PartialEq, Some(self.span));
let partial_eq_obligation = Obligation::new(
self.tcx,
ObligationCause::dummy(),
param_env,
ty::TraitRef::new(self.tcx, partial_eq_trait_id, [ty, ty]),
);
// This *could* accept a type that isn't actually `PartialEq`, because region bounds get
// ignored. However that should be pretty much impossible since consts that do not depend on
// generics can only mention the `'static` lifetime, and how would one have a type that's
// `PartialEq` for some lifetime but *not* for `'static`? If this ever becomes a problem
// we'll need to leave some sort of trace of this requirement in the MIR so that borrowck
// can ensure that the type really implements `PartialEq`.
infcx.predicate_must_hold_modulo_regions(&partial_eq_obligation)
}
fn field_pats(
&self,
vals: impl Iterator<Item = (ValTree<'tcx>, Ty<'tcx>)>,
@ -190,10 +219,25 @@ impl<'tcx> ConstToPat<'tcx> {
// Extremely important check for all ADTs! Make sure they opted-in to be used in
// patterns.
debug!("adt_def {:?} has !type_marked_structural for cv.ty: {:?}", adt_def, ty);
let err = TypeNotStructural { span, non_sm_ty: ty };
let e = tcx.dcx().emit_err(err);
// We errored. Signal that in the pattern, so that follow up errors can be silenced.
PatKind::Error(e)
let (_impls_partial_eq, derived, structural, impl_def_id) =
type_has_partial_eq_impl(self.tcx, self.typing_env, ty);
let (manual_partialeq_impl_span, manual_partialeq_impl_note) =
match (structural, impl_def_id) {
(true, _) => (None, false),
(_, Some(def_id)) if def_id.is_local() && !derived => {
(Some(tcx.def_span(def_id)), false)
}
_ => (None, true),
};
let ty_def_span = tcx.def_span(adt_def.did());
let err = TypeNotStructural {
span,
ty,
ty_def_span,
manual_partialeq_impl_span,
manual_partialeq_impl_note,
};
return self.mk_err(tcx.dcx().create_err(err), ty);
}
ty::Adt(adt_def, args) if adt_def.is_enum() => {
let (&variant_index, fields) = cv.unwrap_branch().split_first().unwrap();
@ -207,7 +251,7 @@ impl<'tcx> ConstToPat<'tcx> {
adt_def.variants()[variant_index]
.fields
.iter()
.map(|field| field.ty(self.tcx, args)),
.map(|field| field.ty(tcx, args)),
),
),
}
@ -216,7 +260,7 @@ impl<'tcx> ConstToPat<'tcx> {
assert!(!def.is_union()); // Valtree construction would never succeed for unions.
PatKind::Leaf {
subpatterns: self.field_pats(cv.unwrap_branch().iter().copied().zip(
def.non_enum_variant().fields.iter().map(|field| field.ty(self.tcx, args)),
def.non_enum_variant().fields.iter().map(|field| field.ty(tcx, args)),
)),
}
}
@ -252,10 +296,10 @@ impl<'tcx> ConstToPat<'tcx> {
// deref pattern.
_ => {
if !pointee_ty.is_sized(tcx, self.typing_env) && !pointee_ty.is_slice() {
let err = UnsizedPattern { span, non_sm_ty: *pointee_ty };
let e = tcx.dcx().emit_err(err);
// We errored. Signal that in the pattern, so that follow up errors can be silenced.
PatKind::Error(e)
return self.mk_err(
tcx.dcx().create_err(UnsizedPattern { span, non_sm_ty: *pointee_ty }),
ty,
);
} else {
// `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.
@ -286,8 +330,7 @@ impl<'tcx> ConstToPat<'tcx> {
if is_nan {
// NaNs are not ever equal to anything so they make no sense as patterns.
// Also see <https://github.com/rust-lang/rfcs/pull/3535>.
let e = tcx.dcx().emit_err(NaNPattern { span });
PatKind::Error(e)
return self.mk_err(tcx.dcx().create_err(NaNPattern { span }), ty);
} else {
PatKind::Constant {
value: mir::Const::Ty(ty, ty::Const::new_value(tcx, cv, ty)),
@ -305,13 +348,153 @@ impl<'tcx> ConstToPat<'tcx> {
)
}
_ => {
let err = InvalidPattern { span, non_sm_ty: ty };
let e = tcx.dcx().emit_err(err);
// We errored. Signal that in the pattern, so that follow up errors can be silenced.
PatKind::Error(e)
let err = InvalidPattern {
span,
non_sm_ty: ty,
prefix: ty.prefix_string(tcx).to_string(),
};
return self.mk_err(tcx.dcx().create_err(err), ty);
}
};
Box::new(Pat { span, ty, kind })
}
}
/// Given a type with type parameters, visit every ADT looking for types that need to
/// `#[derive(PartialEq)]` for it to be a structural type.
fn extend_type_not_partial_eq<'tcx>(
tcx: TyCtxt<'tcx>,
typing_env: ty::TypingEnv<'tcx>,
ty: Ty<'tcx>,
err: &mut Diag<'_>,
) {
/// Collect all types that need to be `StructuralPartialEq`.
struct UsedParamsNeedInstantiationVisitor<'tcx> {
tcx: TyCtxt<'tcx>,
typing_env: ty::TypingEnv<'tcx>,
/// The user has written `impl PartialEq for Ty` which means it's non-structual.
adts_with_manual_partialeq: FxHashSet<Span>,
/// The type has no `PartialEq` implementation, neither manual or derived.
adts_without_partialeq: FxHashSet<Span>,
/// The user has written `impl PartialEq for Ty` which means it's non-structual,
/// but we don't have a span to point at, so we'll just add them as a `note`.
manual: Vec<Ty<'tcx>>,
/// The type has no `PartialEq` implementation, neither manual or derived, but
/// we don't have a span to point at, so we'll just add them as a `note`.
without: Vec<Ty<'tcx>>,
}
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for UsedParamsNeedInstantiationVisitor<'tcx> {
fn visit_ty(&mut self, ty: Ty<'tcx>) -> Self::Result {
if let ty::Adt(def, _args) = ty.kind() {
let ty_def_id = def.did();
let ty_def_span = self.tcx.def_span(ty_def_id);
let (impls_partial_eq, derived, structural, impl_def_id) =
type_has_partial_eq_impl(self.tcx, self.typing_env, ty);
match (impls_partial_eq, derived, structural, impl_def_id) {
(_, _, true, _) => {}
(true, false, _, Some(def_id)) if def_id.is_local() => {
self.adts_with_manual_partialeq.insert(self.tcx.def_span(def_id));
}
(true, false, _, _) if ty_def_id.is_local() => {
self.adts_with_manual_partialeq.insert(ty_def_span);
}
(false, _, _, _) if ty_def_id.is_local() => {
self.adts_without_partialeq.insert(ty_def_span);
}
(true, false, _, _) => {
self.manual.push(ty);
}
(false, _, _, _) => {
self.without.push(ty);
}
_ => {}
};
}
use rustc_middle::ty::TypeSuperVisitable;
ty.super_visit_with(self)
}
}
let mut v = UsedParamsNeedInstantiationVisitor {
tcx,
typing_env,
adts_with_manual_partialeq: FxHashSet::default(),
adts_without_partialeq: FxHashSet::default(),
manual: vec![],
without: vec![],
};
v.visit_ty(ty);
#[allow(rustc::potential_query_instability)] // Span labels will be sorted by the rendering
for span in v.adts_with_manual_partialeq {
err.span_note(span, "the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details");
}
#[allow(rustc::potential_query_instability)] // Span labels will be sorted by the rendering
for span in v.adts_without_partialeq {
err.span_label(
span,
"must be annotated with `#[derive(PartialEq)]` to be usable in patterns",
);
}
for ty in v.manual {
err.note(format!(
"`{ty}` must be annotated with `#[derive(PartialEq)]` to be usable in patterns, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details"
));
}
for ty in v.without {
err.note(format!(
"`{ty}` must be annotated with `#[derive(PartialEq)]` to be usable in patterns"
));
}
}
#[instrument(level = "trace", skip(tcx), ret)]
fn type_has_partial_eq_impl<'tcx>(
tcx: TyCtxt<'tcx>,
typing_env: ty::TypingEnv<'tcx>,
ty: Ty<'tcx>,
) -> (
/* has impl */ bool,
/* is derived */ bool,
/* structural partial eq */ bool,
/* non-blanket impl */ Option<DefId>,
) {
let (infcx, param_env) = tcx.infer_ctxt().build_with_typing_env(typing_env);
// double-check there even *is* a semantic `PartialEq` to dispatch to.
//
// (If there isn't, then we can safely issue a hard
// error, because that's never worked, due to compiler
// using `PartialEq::eq` in this scenario in the past.)
let partial_eq_trait_id = tcx.require_lang_item(hir::LangItem::PartialEq, None);
let structural_partial_eq_trait_id = tcx.require_lang_item(hir::LangItem::StructuralPeq, None);
let partial_eq_obligation = Obligation::new(
tcx,
ObligationCause::dummy(),
param_env,
ty::TraitRef::new(tcx, partial_eq_trait_id, [ty, ty]),
);
let mut automatically_derived = false;
let mut structural_peq = false;
let mut impl_def_id = None;
for def_id in tcx.non_blanket_impls_for_ty(partial_eq_trait_id, ty) {
automatically_derived = tcx.has_attr(def_id, sym::automatically_derived);
impl_def_id = Some(def_id);
}
for _ in tcx.non_blanket_impls_for_ty(structural_partial_eq_trait_id, ty) {
structural_peq = true;
}
// This *could* accept a type that isn't actually `PartialEq`, because region bounds get
// ignored. However that should be pretty much impossible since consts that do not depend on
// generics can only mention the `'static` lifetime, and how would one have a type that's
// `PartialEq` for some lifetime but *not* for `'static`? If this ever becomes a problem
// we'll need to leave some sort of trace of this requirement in the MIR so that borrowck
// can ensure that the type really implements `PartialEq`.
(
infcx.predicate_must_hold_modulo_regions(&partial_eq_obligation),
automatically_derived,
structural_peq,
impl_def_id,
)
}

View File

@ -528,11 +528,17 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
| Res::SelfCtor(..) => PatKind::Leaf { subpatterns },
_ => {
let e = match res {
Res::Def(DefKind::ConstParam, _) => {
self.tcx.dcx().emit_err(ConstParamInPattern { span })
Res::Def(DefKind::ConstParam, def_id) => {
self.tcx.dcx().emit_err(ConstParamInPattern {
span,
const_span: self.tcx().def_span(def_id),
})
}
Res::Def(DefKind::Static { .. }, _) => {
self.tcx.dcx().emit_err(StaticInPattern { span })
Res::Def(DefKind::Static { .. }, def_id) => {
self.tcx.dcx().emit_err(StaticInPattern {
span,
static_span: self.tcx().def_span(def_id),
})
}
_ => self.tcx.dcx().emit_err(NonConstPath { span }),
};

View File

@ -18,7 +18,6 @@ const ALLOWLIST: &[&str] = &[
"const_eval_validation_failure_note",
"driver_impl_ice",
"incremental_corrupt_file",
"mir_build_pointer_pattern",
];
fn check_period(filename: &str, contents: &str, bad: &mut bool) {

View File

@ -18,17 +18,17 @@ impl Foo for Def {
pub fn test<A: Foo, B: Foo>(arg: EFoo) {
match arg {
A::X => println!("A::X"),
//~^ error: constant pattern depends on a generic parameter
//~^ ERROR constant pattern cannot depend on generic parameters
B::X => println!("B::X"),
//~^ error: constant pattern depends on a generic parameter
//~^ ERROR constant pattern cannot depend on generic parameters
_ => (),
}
}
pub fn test_let_pat<A: Foo, B: Foo>(arg: EFoo, A::X: EFoo) {
//~^ ERROR constant pattern depends on a generic parameter
//~^ ERROR constant pattern cannot depend on generic parameters
let A::X = arg;
//~^ ERROR constant pattern depends on a generic parameter
//~^ ERROR constant pattern cannot depend on generic parameters
}
fn main() {

View File

@ -1,26 +1,57 @@
error[E0158]: constant pattern depends on a generic parameter
error[E0158]: constant pattern cannot depend on generic parameters
--> $DIR/associated-const-type-parameter-pattern.rs:20:9
|
LL | pub trait Foo {
| -------------
LL | const X: EFoo;
| ------------- constant defined here
...
LL | pub fn test<A: Foo, B: Foo>(arg: EFoo) {
| - constant depends on this generic parameter
LL | match arg {
LL | A::X => println!("A::X"),
| ^^^^
| ^^^^ `const` depends on a generic parameter
error[E0158]: constant pattern depends on a generic parameter
error[E0158]: constant pattern cannot depend on generic parameters
--> $DIR/associated-const-type-parameter-pattern.rs:22:9
|
LL | pub trait Foo {
| -------------
LL | const X: EFoo;
| ------------- constant defined here
...
LL | pub fn test<A: Foo, B: Foo>(arg: EFoo) {
| - constant depends on this generic parameter
...
LL | B::X => println!("B::X"),
| ^^^^
| ^^^^ `const` depends on a generic parameter
error[E0158]: constant pattern depends on a generic parameter
error[E0158]: constant pattern cannot depend on generic parameters
--> $DIR/associated-const-type-parameter-pattern.rs:30:9
|
LL | pub trait Foo {
| -------------
LL | const X: EFoo;
| ------------- constant defined here
...
LL | pub fn test_let_pat<A: Foo, B: Foo>(arg: EFoo, A::X: EFoo) {
| - constant depends on this generic parameter
LL |
LL | let A::X = arg;
| ^^^^
| ^^^^ `const` depends on a generic parameter
error[E0158]: constant pattern depends on a generic parameter
error[E0158]: constant pattern cannot depend on generic parameters
--> $DIR/associated-const-type-parameter-pattern.rs:28:48
|
LL | pub trait Foo {
| -------------
LL | const X: EFoo;
| ------------- constant defined here
...
LL | pub fn test_let_pat<A: Foo, B: Foo>(arg: EFoo, A::X: EFoo) {
| ^^^^
| - ^^^^ `const` depends on a generic parameter
| |
| constant depends on this generic parameter
error: aborting due to 4 previous errors

View File

@ -2,7 +2,7 @@
fn check<const N: usize>() {
match 1 {
N => {} //~ ERROR const parameters cannot be referenced in patterns
N => {} //~ ERROR constant parameters cannot be referenced in patterns
_ => {}
}
}

View File

@ -1,8 +1,11 @@
error[E0158]: const parameters cannot be referenced in patterns
error[E0158]: constant parameters cannot be referenced in patterns
--> $DIR/const-param.rs:5:9
|
LL | fn check<const N: usize>() {
| -------------- constant defined here
LL | match 1 {
LL | N => {}
| ^
| ^ can't be used in patterns
error: aborting due to 1 previous error

View File

@ -12,8 +12,7 @@ impl Opcode2 {
pub fn example2(msg_type: Opcode2) -> impl FnMut(&[u8]) {
move |i| match msg_type {
Opcode2::OP2 => unimplemented!(),
//~^ ERROR: could not evaluate constant pattern
Opcode2::OP2 => unimplemented!(), // ok, `const` already emitted an error
}
}

View File

@ -17,13 +17,7 @@ help: you might be missing a type parameter
LL | pub struct Opcode2<S>(&'a S);
| +++
error: could not evaluate constant pattern
--> $DIR/ice-type-mismatch-when-copying-112824.rs:15:9
|
LL | Opcode2::OP2 => unimplemented!(),
| ^^^^^^^^^^^^
error: aborting due to 3 previous errors
error: aborting due to 2 previous errors
Some errors have detailed explanations: E0261, E0412.
For more information about an error, try `rustc --explain E0261`.

View File

@ -12,8 +12,7 @@ const NEG_NEG_128: i8 = -NEG_128; //~ ERROR constant
fn main() {
match -128i8 {
NEG_NEG_128 => println!("A"),
//~^ ERROR could not evaluate constant pattern
NEG_NEG_128 => println!("A"), // ok, `const` error already emitted
_ => println!("B"),
}
}

View File

@ -4,12 +4,6 @@ error[E0080]: evaluation of constant value failed
LL | const NEG_NEG_128: i8 = -NEG_128;
| ^^^^^^^^ attempt to negate `i8::MIN`, which would overflow
error: could not evaluate constant pattern
--> $DIR/const-eval-overflow-2.rs:15:9
|
LL | NEG_NEG_128 => println!("A"),
| ^^^^^^^^^^^
error: aborting due to 2 previous errors
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0080`.

View File

@ -7,12 +7,6 @@ LL | const BAR: Int = unsafe { Foo { r: &42 }.f };
= help: this code performed an operation that depends on the underlying bytes representing a pointer
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
error: could not evaluate constant pattern
--> $DIR/ref_to_int_match.rs:7:14
|
LL | 10..=BAR => {},
| ^^^
error: aborting due to 2 previous errors
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0080`.

View File

@ -7,12 +7,6 @@ LL | const BAR: Int = unsafe { Foo { r: &42 }.f };
= help: this code performed an operation that depends on the underlying bytes representing a pointer
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
error: could not evaluate constant pattern
--> $DIR/ref_to_int_match.rs:7:14
|
LL | 10..=BAR => {},
| ^^^
error: aborting due to 2 previous errors
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0080`.

View File

@ -4,7 +4,7 @@ fn main() {
let n: Int = 40;
match n {
0..=10 => {},
10..=BAR => {}, //~ ERROR could not evaluate constant pattern
10..=BAR => {}, // ok, `const` error already emitted
_ => {},
}
}

View File

@ -9,15 +9,13 @@ fn main() {
let _ = Defaulted;
match None {
consts::SOME => panic!(),
//~^ must be annotated with `#[derive(PartialEq)]`
//~^ ERROR constant of non-structural type `CustomEq` in a pattern
_ => {}
}
match None {
<Defaulted as consts::AssocConst>::SOME => panic!(),
//~^ must be annotated with `#[derive(PartialEq)]`
//~^ ERROR constant of non-structural type `CustomEq` in a pattern
_ => {}
}
}

View File

@ -1,19 +1,33 @@
error: to use a constant of type `CustomEq` in a pattern, `CustomEq` must be annotated with `#[derive(PartialEq)]`
error: constant of non-structural type `CustomEq` in a pattern
--> $DIR/cross-crate-fail.rs:11:9
|
LL | consts::SOME => panic!(),
| ^^^^^^^^^^^^
| ^^^^^^^^^^^^ constant of non-structural type
|
::: $DIR/auxiliary/consts.rs:1:1
|
LL | pub struct CustomEq;
| ------------------- `CustomEq` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
...
LL | pub const SOME: Option<CustomEq> = Some(CustomEq);
| -------------------------------- constant defined here
|
= note: the traits must be derived, manual `impl`s are not sufficient
= note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
error: to use a constant of type `CustomEq` in a pattern, `CustomEq` must be annotated with `#[derive(PartialEq)]`
--> $DIR/cross-crate-fail.rs:18:9
error: constant of non-structural type `CustomEq` in a pattern
--> $DIR/cross-crate-fail.rs:17:9
|
LL | <Defaulted as consts::AssocConst>::SOME => panic!(),
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constant of non-structural type
|
::: $DIR/auxiliary/consts.rs:1:1
|
LL | pub struct CustomEq;
| ------------------- `CustomEq` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
...
LL | const SOME: Option<CustomEq> = Some(CustomEq);
| ---------------------------- constant defined here
|
= note: the traits must be derived, manual `impl`s are not sufficient
= note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
error: aborting due to 2 previous errors

View File

@ -1,26 +1,46 @@
error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon
--> $DIR/issue-34784-match-on-non-int-raw-ptr.rs:9:9
|
LL | const C: *const u8 = &0;
| ------------------ constant defined here
...
LL | C => {}
| ^
| ^ can't be used in patterns
|
= note: see https://github.com/rust-lang/rust/issues/70861 for details
error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon
--> $DIR/issue-34784-match-on-non-int-raw-ptr.rs:16:9
|
LL | const C_INNER: (*const u8, u8) = (C, 0);
| ------------------------------ constant defined here
...
LL | C_INNER => {}
| ^^^^^^^
| ^^^^^^^ can't be used in patterns
|
= note: see https://github.com/rust-lang/rust/issues/70861 for details
error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon
--> $DIR/issue-34784-match-on-non-int-raw-ptr.rs:27:9
|
LL | const D: *const [u8; 4] = b"abcd";
| ----------------------- constant defined here
...
LL | D => {}
| ^
| ^ can't be used in patterns
|
= note: see https://github.com/rust-lang/rust/issues/70861 for details
error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon
--> $DIR/issue-34784-match-on-non-int-raw-ptr.rs:32:9
|
LL | const STR: *const str = "abcd";
| --------------------- constant defined here
...
LL | STR => {}
| ^^^
| ^^^ can't be used in patterns
|
= note: see https://github.com/rust-lang/rust/issues/70861 for details
error: aborting due to 4 previous errors

View File

@ -1,14 +1,24 @@
error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon
--> $DIR/issue-44333.rs:15:9
|
LL | const FOO: Func = foo;
| --------------- constant defined here
...
LL | FOO => println!("foo"),
| ^^^
| ^^^ can't be used in patterns
|
= note: see https://github.com/rust-lang/rust/issues/70861 for details
error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon
--> $DIR/issue-44333.rs:16:9
|
LL | const BAR: Func = bar;
| --------------- constant defined here
...
LL | BAR => println!("bar"),
| ^^^
| ^^^ can't be used in patterns
|
= note: see https://github.com/rust-lang/rust/issues/70861 for details
error: aborting due to 2 previous errors

View File

@ -11,7 +11,7 @@ const C: &[O<B>] = &[O::None];
fn main() {
let x = O::None;
match &[x][..] {
C => (), //~ERROR: the type must implement `PartialEq`
C => (), //~ ERROR constant of non-structural type `&[O<B>]` in a pattern
_ => (),
}
}

View File

@ -1,8 +1,16 @@
error: to use a constant of type `&[O<B>]` in a pattern, the type must implement `PartialEq`
error: constant of non-structural type `&[O<B>]` in a pattern
--> $DIR/issue-65466.rs:14:9
|
LL | struct B;
| -------- must be annotated with `#[derive(PartialEq)]` to be usable in patterns
LL |
LL | const C: &[O<B>] = &[O::None];
| ---------------- constant defined here
...
LL | C => (),
| ^
| ^ constant of non-structural type
|
= note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
error: aborting due to 1 previous error

View File

@ -16,8 +16,7 @@ const BAR_BAZ: Foo = if 42 == 42 {
fn main() {
match Foo::Qux(NoEq) {
BAR_BAZ => panic!(),
//~^ ERROR must be annotated with `#[derive(PartialEq)]`
BAR_BAZ => panic!(), //~ ERROR constant of non-structural type `Foo` in a pattern
_ => {}
}
}

View File

@ -1,10 +1,15 @@
error: to use a constant of type `Foo` in a pattern, `Foo` must be annotated with `#[derive(PartialEq)]`
error: constant of non-structural type `Foo` in a pattern
--> $DIR/no-eq-branch-fail.rs:19:9
|
LL | enum Foo {
| -------- `Foo` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
...
LL | const BAR_BAZ: Foo = if 42 == 42 {
| ------------------ constant defined here
...
LL | BAR_BAZ => panic!(),
| ^^^^^^^
| ^^^^^^^ constant of non-structural type
|
= note: the traits must be derived, manual `impl`s are not sufficient
= note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
error: aborting due to 1 previous error

View File

@ -26,7 +26,7 @@ fn main() {
match None {
NO_PARTIAL_EQ_NONE => println!("NO_PARTIAL_EQ_NONE"),
//~^ ERROR must implement `PartialEq`
//~^ ERROR constant of non-structural type `Option<NoPartialEq>` in a pattern
_ => panic!("whoops"),
}
}

View File

@ -1,8 +1,16 @@
error: to use a constant of type `Option<NoPartialEq>` in a pattern, the type must implement `PartialEq`
error: constant of non-structural type `Option<NoPartialEq>` in a pattern
--> $DIR/reject_non_partial_eq.rs:28:9
|
LL | struct NoPartialEq(u32);
| ------------------ must be annotated with `#[derive(PartialEq)]` to be usable in patterns
...
LL | const NO_PARTIAL_EQ_NONE: Option<NoPartialEq> = None;
| --------------------------------------------- constant defined here
...
LL | NO_PARTIAL_EQ_NONE => println!("NO_PARTIAL_EQ_NONE"),
| ^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^ constant of non-structural type
|
= note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
error: aborting due to 1 previous error

View File

@ -17,9 +17,29 @@ struct NoPartialEq;
#[derive(Copy, Clone, Debug)]
struct NoDerive;
//~^ NOTE must be annotated with `#[derive(PartialEq)]`
//~| NOTE must be annotated with `#[derive(PartialEq)]`
//~| NOTE must be annotated with `#[derive(PartialEq)]`
//~| NOTE must be annotated with `#[derive(PartialEq)]`
//~| NOTE must be annotated with `#[derive(PartialEq)]`
//~| NOTE must be annotated with `#[derive(PartialEq)]`
//~| NOTE must be annotated with `#[derive(PartialEq)]`
//~| NOTE must be annotated with `#[derive(PartialEq)]`
//~| NOTE must be annotated with `#[derive(PartialEq)]`
//~| NOTE must be annotated with `#[derive(PartialEq)]`
// This impl makes `NoDerive` irreflexive.
impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } }
//~^ NOTE StructuralPartialEq.html for details
//~| NOTE StructuralPartialEq.html for details
//~| NOTE StructuralPartialEq.html for details
//~| NOTE StructuralPartialEq.html for details
//~| NOTE StructuralPartialEq.html for details
//~| NOTE StructuralPartialEq.html for details
//~| NOTE StructuralPartialEq.html for details
//~| NOTE StructuralPartialEq.html for details
//~| NOTE StructuralPartialEq.html for details
//~| NOTE StructuralPartialEq.html for details
impl Eq for NoDerive { }
@ -36,65 +56,55 @@ fn main() {
#[derive(PartialEq, Eq, Debug)]
enum Derive<X> { Some(X), None, }
const ENUM: Derive<NoDerive> = Derive::Some(NoDerive);
const ENUM: Derive<NoDerive> = Derive::Some(NoDerive); //~ NOTE constant defined here
match Derive::Some(NoDerive) { ENUM => dbg!(ENUM), _ => panic!("whoops"), };
//~^ ERROR must be annotated with `#[derive(PartialEq)]`
//~| NOTE the traits must be derived
//~| NOTE StructuralPartialEq.html for details
//~^ ERROR constant of non-structural type `NoDerive` in a pattern
//~| NOTE constant of non-structural type
const FIELD: OND = TrivialEq(Some(NoDerive)).0;
const FIELD: OND = TrivialEq(Some(NoDerive)).0; //~ NOTE constant defined here
match Some(NoDerive) { FIELD => dbg!(FIELD), _ => panic!("whoops"), };
//~^ ERROR must be annotated with `#[derive(PartialEq)]`
//~| NOTE the traits must be derived
//~| NOTE StructuralPartialEq.html for details
//~^ ERROR constant of non-structural type `NoDerive` in a pattern
//~| NOTE constant of non-structural type
const NO_DERIVE_SOME: OND = Some(NoDerive);
const INDIRECT: OND = NO_DERIVE_SOME;
const INDIRECT: OND = NO_DERIVE_SOME; //~ NOTE constant defined here
match Some(NoDerive) {INDIRECT => dbg!(INDIRECT), _ => panic!("whoops"), };
//~^ ERROR must be annotated with `#[derive(PartialEq)]`
//~| NOTE the traits must be derived
//~| NOTE StructuralPartialEq.html for details
//~^ ERROR constant of non-structural type `NoDerive` in a pattern
//~| NOTE constant of non-structural type
const TUPLE: (OND, OND) = (None, Some(NoDerive));
const TUPLE: (OND, OND) = (None, Some(NoDerive)); //~ NOTE constant defined here
match (None, Some(NoDerive)) { TUPLE => dbg!(TUPLE), _ => panic!("whoops"), };
//~^ ERROR must be annotated with `#[derive(PartialEq)]`
//~| NOTE the traits must be derived
//~| NOTE StructuralPartialEq.html for details
//~^ ERROR constant of non-structural type `NoDerive` in a pattern
//~| NOTE constant of non-structural type
const TYPE_ASCRIPTION: OND = type_ascribe!(Some(NoDerive), OND);
const TYPE_ASCRIPTION: OND = type_ascribe!(Some(NoDerive), OND); //~ NOTE constant defined here
match Some(NoDerive) { TYPE_ASCRIPTION => dbg!(TYPE_ASCRIPTION), _ => panic!("whoops"), };
//~^ ERROR must be annotated with `#[derive(PartialEq)]`
//~| NOTE the traits must be derived
//~| NOTE StructuralPartialEq.html for details
//~^ ERROR constant of non-structural type `NoDerive` in a pattern
//~| NOTE constant of non-structural type
const ARRAY: [OND; 2] = [None, Some(NoDerive)];
const ARRAY: [OND; 2] = [None, Some(NoDerive)]; //~ NOTE constant defined here
match [None, Some(NoDerive)] { ARRAY => dbg!(ARRAY), _ => panic!("whoops"), };
//~^ ERROR must be annotated with `#[derive(PartialEq)]`
//~| NOTE the traits must be derived
//~| NOTE StructuralPartialEq.html for details
//~^ ERROR constant of non-structural type `NoDerive` in a pattern
//~| NOTE constant of non-structural type
const REPEAT: [OND; 2] = [Some(NoDerive); 2];
const REPEAT: [OND; 2] = [Some(NoDerive); 2]; //~ NOTE constant defined here
match [Some(NoDerive); 2] { REPEAT => dbg!(REPEAT), _ => panic!("whoops"), };
//~^ ERROR must be annotated with `#[derive(PartialEq)]`
//~| NOTE the traits must be derived
//~| NOTE StructuralPartialEq.html for details
//~^ ERROR constant of non-structural type `NoDerive` in a pattern
//~| NOTE constant of non-structural type
trait Trait: Sized { const ASSOC: Option<Self>; }
trait Trait: Sized { const ASSOC: Option<Self>; } //~ NOTE constant defined here
impl Trait for NoDerive { const ASSOC: Option<NoDerive> = Some(NoDerive); }
match Some(NoDerive) { NoDerive::ASSOC => dbg!(NoDerive::ASSOC), _ => panic!("whoops"), };
//~^ ERROR must be annotated with `#[derive(PartialEq)]`
//~| NOTE the traits must be derived
//~| NOTE StructuralPartialEq.html for details
//~^ ERROR constant of non-structural type `NoDerive` in a pattern
//~| NOTE constant of non-structural type
const BLOCK: OND = { NoDerive; Some(NoDerive) };
const BLOCK: OND = { NoDerive; Some(NoDerive) }; //~ NOTE constant defined here
match Some(NoDerive) { BLOCK => dbg!(BLOCK), _ => panic!("whoops"), };
//~^ ERROR must be annotated with `#[derive(PartialEq)]`
//~| NOTE the traits must be derived
//~| NOTE StructuralPartialEq.html for details
//~^ ERROR constant of non-structural type `NoDerive` in a pattern
//~| NOTE constant of non-structural type
const ADDR_OF: &OND = &Some(NoDerive);
const ADDR_OF: &OND = &Some(NoDerive); //~ NOTE constant defined here
match &Some(NoDerive) { ADDR_OF => dbg!(ADDR_OF), _ => panic!("whoops"), };
//~^ ERROR must be annotated with `#[derive(PartialEq)]`
//~| NOTE the traits must be derived
//~| NOTE StructuralPartialEq.html for details
//~^ ERROR constant of non-structural type `NoDerive` in a pattern
//~| NOTE constant of non-structural type
}

View File

@ -1,92 +1,173 @@
error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]`
--> $DIR/reject_non_structural.rs:40:36
error: constant of non-structural type `NoDerive` in a pattern
--> $DIR/reject_non_structural.rs:60:36
|
LL | struct NoDerive;
| --------------- `NoDerive` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
...
LL | const ENUM: Derive<NoDerive> = Derive::Some(NoDerive);
| ---------------------------- constant defined here
LL | match Derive::Some(NoDerive) { ENUM => dbg!(ENUM), _ => panic!("whoops"), };
| ^^^^
| ^^^^ constant of non-structural type
|
= note: the traits must be derived, manual `impl`s are not sufficient
= note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
--> $DIR/reject_non_structural.rs:32:1
|
LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]`
--> $DIR/reject_non_structural.rs:46:28
|
LL | match Some(NoDerive) { FIELD => dbg!(FIELD), _ => panic!("whoops"), };
| ^^^^^
|
= note: the traits must be derived, manual `impl`s are not sufficient
= note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]`
--> $DIR/reject_non_structural.rs:53:27
|
LL | match Some(NoDerive) {INDIRECT => dbg!(INDIRECT), _ => panic!("whoops"), };
| ^^^^^^^^
|
= note: the traits must be derived, manual `impl`s are not sufficient
= note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]`
--> $DIR/reject_non_structural.rs:59:36
|
LL | match (None, Some(NoDerive)) { TUPLE => dbg!(TUPLE), _ => panic!("whoops"), };
| ^^^^^
|
= note: the traits must be derived, manual `impl`s are not sufficient
= note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]`
error: constant of non-structural type `NoDerive` in a pattern
--> $DIR/reject_non_structural.rs:65:28
|
LL | struct NoDerive;
| --------------- `NoDerive` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
...
LL | const FIELD: OND = TrivialEq(Some(NoDerive)).0;
| ---------------- constant defined here
LL | match Some(NoDerive) { FIELD => dbg!(FIELD), _ => panic!("whoops"), };
| ^^^^^ constant of non-structural type
|
note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
--> $DIR/reject_non_structural.rs:32:1
|
LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: constant of non-structural type `NoDerive` in a pattern
--> $DIR/reject_non_structural.rs:71:27
|
LL | struct NoDerive;
| --------------- `NoDerive` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
...
LL | const INDIRECT: OND = NO_DERIVE_SOME;
| ------------------- constant defined here
LL | match Some(NoDerive) {INDIRECT => dbg!(INDIRECT), _ => panic!("whoops"), };
| ^^^^^^^^ constant of non-structural type
|
note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
--> $DIR/reject_non_structural.rs:32:1
|
LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: constant of non-structural type `NoDerive` in a pattern
--> $DIR/reject_non_structural.rs:76:36
|
LL | struct NoDerive;
| --------------- `NoDerive` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
...
LL | const TUPLE: (OND, OND) = (None, Some(NoDerive));
| ----------------------- constant defined here
LL | match (None, Some(NoDerive)) { TUPLE => dbg!(TUPLE), _ => panic!("whoops"), };
| ^^^^^ constant of non-structural type
|
note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
--> $DIR/reject_non_structural.rs:32:1
|
LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: constant of non-structural type `NoDerive` in a pattern
--> $DIR/reject_non_structural.rs:81:28
|
LL | struct NoDerive;
| --------------- `NoDerive` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
...
LL | const TYPE_ASCRIPTION: OND = type_ascribe!(Some(NoDerive), OND);
| -------------------------- constant defined here
LL | match Some(NoDerive) { TYPE_ASCRIPTION => dbg!(TYPE_ASCRIPTION), _ => panic!("whoops"), };
| ^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^ constant of non-structural type
|
= note: the traits must be derived, manual `impl`s are not sufficient
= note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
--> $DIR/reject_non_structural.rs:32:1
|
LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]`
--> $DIR/reject_non_structural.rs:71:36
error: constant of non-structural type `NoDerive` in a pattern
--> $DIR/reject_non_structural.rs:86:36
|
LL | struct NoDerive;
| --------------- `NoDerive` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
...
LL | const ARRAY: [OND; 2] = [None, Some(NoDerive)];
| --------------------- constant defined here
LL | match [None, Some(NoDerive)] { ARRAY => dbg!(ARRAY), _ => panic!("whoops"), };
| ^^^^^
| ^^^^^ constant of non-structural type
|
= note: the traits must be derived, manual `impl`s are not sufficient
= note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
--> $DIR/reject_non_structural.rs:32:1
|
LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]`
--> $DIR/reject_non_structural.rs:77:33
error: constant of non-structural type `NoDerive` in a pattern
--> $DIR/reject_non_structural.rs:91:33
|
LL | struct NoDerive;
| --------------- `NoDerive` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
...
LL | const REPEAT: [OND; 2] = [Some(NoDerive); 2];
| ---------------------- constant defined here
LL | match [Some(NoDerive); 2] { REPEAT => dbg!(REPEAT), _ => panic!("whoops"), };
| ^^^^^^
| ^^^^^^ constant of non-structural type
|
= note: the traits must be derived, manual `impl`s are not sufficient
= note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
--> $DIR/reject_non_structural.rs:32:1
|
LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]`
--> $DIR/reject_non_structural.rs:84:28
error: constant of non-structural type `NoDerive` in a pattern
--> $DIR/reject_non_structural.rs:97:28
|
LL | struct NoDerive;
| --------------- `NoDerive` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
...
LL | trait Trait: Sized { const ASSOC: Option<Self>; }
| ------------------ ------------------------- constant defined here
LL | impl Trait for NoDerive { const ASSOC: Option<NoDerive> = Some(NoDerive); }
LL | match Some(NoDerive) { NoDerive::ASSOC => dbg!(NoDerive::ASSOC), _ => panic!("whoops"), };
| ^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^ constant of non-structural type
|
= note: the traits must be derived, manual `impl`s are not sufficient
= note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
--> $DIR/reject_non_structural.rs:32:1
|
LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]`
--> $DIR/reject_non_structural.rs:90:28
error: constant of non-structural type `NoDerive` in a pattern
--> $DIR/reject_non_structural.rs:102:28
|
LL | struct NoDerive;
| --------------- `NoDerive` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
...
LL | const BLOCK: OND = { NoDerive; Some(NoDerive) };
| ---------------- constant defined here
LL | match Some(NoDerive) { BLOCK => dbg!(BLOCK), _ => panic!("whoops"), };
| ^^^^^
| ^^^^^ constant of non-structural type
|
= note: the traits must be derived, manual `impl`s are not sufficient
= note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
--> $DIR/reject_non_structural.rs:32:1
|
LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]`
--> $DIR/reject_non_structural.rs:96:29
error: constant of non-structural type `NoDerive` in a pattern
--> $DIR/reject_non_structural.rs:107:29
|
LL | struct NoDerive;
| --------------- `NoDerive` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
...
LL | const ADDR_OF: &OND = &Some(NoDerive);
| ------------------- constant defined here
LL | match &Some(NoDerive) { ADDR_OF => dbg!(ADDR_OF), _ => panic!("whoops"), };
| ^^^^^^^
| ^^^^^^^ constant of non-structural type
|
= note: the traits must be derived, manual `impl`s are not sufficient
= note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
--> $DIR/reject_non_structural.rs:32:1
|
LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 10 previous errors

View File

@ -11,7 +11,7 @@ fn invalid() {
// This must be rejected here (or earlier), since it's not a valid `&bool`.
match &true {
C => {} //~ERROR: could not evaluate constant pattern
C => {} // ok, `const` already emitted an error
_ => {}
}
}
@ -27,7 +27,7 @@ fn extern_() {
// This must be rejected here (or earlier), since the pattern cannot be read.
match &0 {
C => {} //~ERROR: could not evaluate constant pattern
C => {} // ok, `const` already emitted an error
_ => {}
}
}
@ -42,7 +42,7 @@ fn mutable() {
// This *must not build*, the constant we are matching against
// could change its value!
match &42 {
C => {} //~ERROR: could not evaluate constant pattern
C => {} // ok, `const` already emitted an error
_ => {}
}
}

View File

@ -31,24 +31,6 @@ LL | const C: &i32 = unsafe { &S_MUT };
HEX_DUMP
}
error: could not evaluate constant pattern
--> $DIR/const_refs_to_static_fail_invalid.rs:14:9
|
LL | C => {}
| ^
error: could not evaluate constant pattern
--> $DIR/const_refs_to_static_fail_invalid.rs:30:9
|
LL | C => {}
| ^
error: could not evaluate constant pattern
--> $DIR/const_refs_to_static_fail_invalid.rs:45:9
|
LL | C => {}
| ^
error: aborting due to 6 previous errors
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0080`.

View File

@ -11,7 +11,7 @@ error: could not evaluate constant pattern
--> $DIR/invalid-inline-const-in-match-arm.rs:5:9
|
LL | const { (|| {})() } => {}
| ^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^ could not evaluate constant
error: aborting due to 2 previous errors

View File

@ -5,8 +5,7 @@ const NUM: u8 = xyz();
fn main() {
match 1 {
NUM => unimplemented!(),
//~^ ERROR could not evaluate constant pattern
NUM => unimplemented!(), // ok, the `const` already emitted an error
_ => unimplemented!(),
}
}

View File

@ -6,12 +6,6 @@ LL | const NUM: u8 = xyz();
|
= note: calls in constants are limited to constant functions, tuple structs and tuple variants
error: could not evaluate constant pattern
--> $DIR/issue-43105.rs:8:9
|
LL | NUM => unimplemented!(),
| ^^^
error: aborting due to 2 previous errors
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0015`.

View File

@ -18,7 +18,7 @@ impl<T: 'static> GetTypeId<T> {
const fn check_type_id<T: 'static>() -> bool {
matches!(GetTypeId::<T>::VALUE, GetTypeId::<T>::VALUE)
//~^ ERROR constant pattern depends on a generic parameter
//~^ ERROR constant pattern cannot depend on generic parameters
}
pub struct GetTypeNameLen<T>(T);
@ -29,7 +29,7 @@ impl<T: 'static> GetTypeNameLen<T> {
const fn check_type_name_len<T: 'static>() -> bool {
matches!(GetTypeNameLen::<T>::VALUE, GetTypeNameLen::<T>::VALUE)
//~^ ERROR constant pattern depends on a generic parameter
//~^ ERROR constant pattern cannot depend on generic parameters
}
fn main() {

View File

@ -1,14 +1,28 @@
error[E0158]: constant pattern depends on a generic parameter
error[E0158]: constant pattern cannot depend on generic parameters
--> $DIR/issue-73976-polymorphic.rs:20:37
|
LL | impl<T: 'static> GetTypeId<T> {
| -----------------------------
LL | pub const VALUE: TypeId = TypeId::of::<T>();
| ----------------------- constant defined here
...
LL | const fn check_type_id<T: 'static>() -> bool {
| - constant depends on this generic parameter
LL | matches!(GetTypeId::<T>::VALUE, GetTypeId::<T>::VALUE)
| ^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^ `const` depends on a generic parameter
error[E0158]: constant pattern depends on a generic parameter
error[E0158]: constant pattern cannot depend on generic parameters
--> $DIR/issue-73976-polymorphic.rs:31:42
|
LL | impl<T: 'static> GetTypeNameLen<T> {
| ----------------------------------
LL | pub const VALUE: usize = any::type_name::<T>().len();
| ---------------------- constant defined here
...
LL | const fn check_type_name_len<T: 'static>() -> bool {
| - constant depends on this generic parameter
LL | matches!(GetTypeNameLen::<T>::VALUE, GetTypeNameLen::<T>::VALUE)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ `const` depends on a generic parameter
error: aborting due to 2 previous errors

View File

@ -4,6 +4,5 @@ const FOO: *const u32 = {
};
fn main() {
let FOO = FOO;
//~^ ERROR could not evaluate constant pattern
let FOO = FOO; // ok, the `const` already emitted an error
}

View File

@ -11,12 +11,6 @@ help: consider assigning a value
LL | let x = 42;
| ++++
error: could not evaluate constant pattern
--> $DIR/issue-78655.rs:7:9
|
LL | let FOO = FOO;
| ^^^
error: aborting due to 2 previous errors
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0381`.

View File

@ -10,7 +10,7 @@ impl<T> GetVariantCount<T> {
const fn check_variant_count<T>() -> bool {
matches!(GetVariantCount::<T>::VALUE, GetVariantCount::<T>::VALUE)
//~^ ERROR constant pattern depends on a generic parameter
//~^ ERROR constant pattern cannot depend on generic parameters
}
fn main() {

View File

@ -1,8 +1,15 @@
error[E0158]: constant pattern depends on a generic parameter
error[E0158]: constant pattern cannot depend on generic parameters
--> $DIR/issue-79137-toogeneric.rs:12:43
|
LL | impl<T> GetVariantCount<T> {
| --------------------------
LL | pub const VALUE: usize = std::mem::variant_count::<T>();
| ---------------------- constant defined here
...
LL | const fn check_variant_count<T>() -> bool {
| - constant depends on this generic parameter
LL | matches!(GetVariantCount::<T>::VALUE, GetVariantCount::<T>::VALUE)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `const` depends on a generic parameter
error: aborting due to 1 previous error

View File

@ -1,6 +1,9 @@
error: cannot use unsized non-slice type `Username` in constant patterns
--> $DIR/issue-87046.rs:28:13
|
LL | pub const ROOT_USER: &Username = Username::from_str("root");
| ------------------------------ constant defined here
...
LL | ROOT_USER => true,
| ^^^^^^^^^

View File

@ -13,7 +13,7 @@ fn main() {
let var = A::Field(Cow::Borrowed("bar"));
match &var {
FOO => todo!(), //~ERROR derive(PartialEq)
FOO => todo!(), //~ ERROR constant of non-structural type `Cow<'_, str>` in a pattern
_ => todo!()
}
}

View File

@ -1,10 +1,15 @@
error: to use a constant of type `Cow<'_, str>` in a pattern, `Cow<'_, str>` must be annotated with `#[derive(PartialEq)]`
error: constant of non-structural type `Cow<'_, str>` in a pattern
--> $DIR/issue-89088.rs:16:9
|
LL | const FOO: &A = &A::Field(Cow::Borrowed("foo"));
| ------------- constant defined here
...
LL | FOO => todo!(),
| ^^^
| ^^^ constant of non-structural type
--> $SRC_DIR/alloc/src/borrow.rs:LL:COL
|
= note: `Cow<'_, str>` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
|
= note: the traits must be derived, manual `impl`s are not sufficient
= note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
error: aborting due to 1 previous error

View File

@ -8,8 +8,7 @@ struct T;
fn main() {
const C: &S = &S;
match C {
C => {}
//~^ ERROR must be annotated with `#[derive(PartialEq)]`
C => {} //~ ERROR constant of non-structural type `S` in a pattern
}
const K: &T = &T;
match K {

View File

@ -1,10 +1,15 @@
error: to use a constant of type `S` in a pattern, `S` must be annotated with `#[derive(PartialEq)]`
error: constant of non-structural type `S` in a pattern
--> $DIR/match_ice.rs:11:9
|
LL | struct S;
| -------- `S` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
...
LL | const C: &S = &S;
| ----------- constant defined here
LL | match C {
LL | C => {}
| ^
| ^ constant of non-structural type
|
= note: the traits must be derived, manual `impl`s are not sufficient
= note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
error: aborting due to 1 previous error

View File

@ -37,16 +37,14 @@ const U8_MUT3: &u8 = {
pub fn test(x: &[u8; 1]) -> bool {
match x {
SLICE_MUT => true,
//~^ ERROR could not evaluate constant pattern
SLICE_MUT => true, // ok, `const` error already emitted
&[1..] => false,
}
}
pub fn test2(x: &u8) -> bool {
match x {
U8_MUT => true,
//~^ ERROR could not evaluate constant pattern
U8_MUT => true, // ok, `const` error already emitted
&(1..) => false,
}
}
@ -55,15 +53,13 @@ pub fn test2(x: &u8) -> bool {
// the errors above otherwise stop compilation too early?
pub fn test3(x: &u8) -> bool {
match x {
U8_MUT2 => true,
//~^ ERROR could not evaluate constant pattern
U8_MUT2 => true, // ok, `const` error already emitted
&(1..) => false,
}
}
pub fn test4(x: &u8) -> bool {
match x {
U8_MUT3 => true,
//~^ ERROR could not evaluate constant pattern
U8_MUT3 => true, // ok, `const` error already emitted
&(1..) => false,
}
}

View File

@ -37,30 +37,6 @@ error[E0080]: evaluation of constant value failed
LL | match static_cross_crate::OPT_ZERO {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constant accesses mutable global memory
error: could not evaluate constant pattern
--> $DIR/const_refers_to_static_cross_crate.rs:40:9
|
LL | SLICE_MUT => true,
| ^^^^^^^^^
error: could not evaluate constant pattern
--> $DIR/const_refers_to_static_cross_crate.rs:48:9
|
LL | U8_MUT => true,
| ^^^^^^
error: could not evaluate constant pattern
--> $DIR/const_refers_to_static_cross_crate.rs:58:9
|
LL | U8_MUT2 => true,
| ^^^^^^^
error: could not evaluate constant pattern
--> $DIR/const_refers_to_static_cross_crate.rs:65:9
|
LL | U8_MUT3 => true,
| ^^^^^^^
error: aborting due to 8 previous errors
error: aborting due to 4 previous errors
For more information about this error, try `rustc --explain E0080`.

View File

@ -9,14 +9,13 @@ trait Range {
struct TwoDigits;
impl Range for TwoDigits {
const FIRST: = 10;
//~^ ERROR: missing type for `const` item
const FIRST: = 10; //~ ERROR missing type for `const` item
const LAST: u8 = 99;
}
const fn digits(x: u8) -> usize {
match x {
TwoDigits::FIRST..=TwoDigits::LAST => 0, //~ ERROR: could not evaluate constant pattern
TwoDigits::FIRST..=TwoDigits::LAST => 0, // ok, `const` error already emitted
0..=9 | 100..=255 => panic!(),
}
}

View File

@ -4,11 +4,5 @@ error: missing type for `const` item
LL | const FIRST: = 10;
| ^ help: provide a type for the associated constant: `u8`
error: could not evaluate constant pattern
--> $DIR/missing_assoc_const_type.rs:19:9
|
LL | TwoDigits::FIRST..=TwoDigits::LAST => 0,
| ^^^^^^^^^^^^^^^^
error: aborting due to 2 previous errors
error: aborting due to 1 previous error

View File

@ -5,7 +5,7 @@
fn main() {
match &b""[..] {
ZST => {} //~ ERROR: could not evaluate constant pattern
ZST => {} // ok, `const` error already emitted
}
}

View File

@ -7,12 +7,6 @@ LL | const ZST: &[u8] = unsafe { std::mem::transmute(1usize) };
= note: source type: `usize` (word size)
= note: target type: `&[u8]` (2 * word size)
error: could not evaluate constant pattern
--> $DIR/transmute-size-mismatch-before-typeck.rs:8:9
|
LL | ZST => {}
| ^^^
error: aborting due to 2 previous errors
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0512`.

View File

@ -5,7 +5,7 @@
fn foo<const V: usize>() {
match 0 {
const { V } => {},
//~^ ERROR constant pattern depends on a generic parameter
//~^ ERROR constant pattern cannot depend on generic parameters
_ => {},
}
}
@ -17,7 +17,7 @@ const fn f(x: usize) -> usize {
fn bar<const V: usize>() {
match 0 {
const { f(V) } => {},
//~^ ERROR constant pattern depends on a generic parameter
//~^ ERROR constant pattern cannot depend on generic parameters
_ => {},
}
}

View File

@ -1,14 +1,14 @@
error[E0158]: constant pattern depends on a generic parameter
error[E0158]: constant pattern cannot depend on generic parameters
--> $DIR/const-match-pat-generic.rs:7:9
|
LL | const { V } => {},
| ^^^^^^^^^^^
| ^^^^^^^^^^^ `const` depends on a generic parameter
error[E0158]: constant pattern depends on a generic parameter
error[E0158]: constant pattern cannot depend on generic parameters
--> $DIR/const-match-pat-generic.rs:19:9
|
LL | const { f(V) } => {},
| ^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^ `const` depends on a generic parameter
error: aborting due to 2 previous errors

View File

@ -1,8 +1,8 @@
error: `fn() {uwu}` cannot be used in patterns
error: fn item `fn() {uwu}` cannot be used in patterns
--> $DIR/pat-match-fndef.rs:8:9
|
LL | const { uwu } => {}
| ^^^^^^^^^^^^^
| ^^^^^^^^^^^^^ fn item can't be used in patterns
error: aborting due to 1 previous error

View File

@ -1,8 +1,11 @@
error: `dyn Send` cannot be used in patterns
error: trait object `dyn Send` cannot be used in patterns
--> $DIR/issue-70972-dyn-trait.rs:6:9
|
LL | const F: &'static dyn Send = &7u32;
| -------------------------- constant defined here
...
LL | F => panic!(),
| ^
| ^ trait object can't be used in patterns
error: aborting due to 1 previous error

View File

@ -16,7 +16,7 @@ const CONST_SET: EnumSet<Enum8> = EnumSet { __enumset_underlying: 3 };
fn main() {
match CONST_SET {
CONST_SET => { /* ok */ } //~ERROR: must implement `PartialEq`
CONST_SET => { /* ok */ } //~ ERROR constant of non-structural type `EnumSet<Enum8>` in a pattern
_ => panic!("match fell through?"),
}
}

View File

@ -1,8 +1,16 @@
error: to use a constant of type `EnumSet<Enum8>` in a pattern, the type must implement `PartialEq`
error: constant of non-structural type `EnumSet<Enum8>` in a pattern
--> $DIR/issue-72896-non-partial-eq-const.rs:19:9
|
LL | enum Enum8 { }
| ---------- must be annotated with `#[derive(PartialEq)]` to be usable in patterns
...
LL | const CONST_SET: EnumSet<Enum8> = EnumSet { __enumset_underlying: 3 };
| ------------------------------- constant defined here
...
LL | CONST_SET => { /* ok */ }
| ^^^^^^^^^
| ^^^^^^^^^ constant of non-structural type
|
= note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
error: aborting due to 1 previous error

View File

@ -3,5 +3,5 @@ const CONST_STRING: String = String::new();
fn main() {
let empty_str = String::from("");
if let CONST_STRING = empty_str {}
//~^ ERROR to use a constant of type `Vec<u8>` in a pattern, `Vec<u8>` must be annotated with `#[derive(PartialEq)]`
//~^ ERROR constant of non-structural type `Vec<u8>` in a pattern
}

View File

@ -1,10 +1,15 @@
error: to use a constant of type `Vec<u8>` in a pattern, `Vec<u8>` must be annotated with `#[derive(PartialEq)]`
error: constant of non-structural type `Vec<u8>` in a pattern
--> $DIR/issue-115599.rs:5:12
|
LL | const CONST_STRING: String = String::new();
| -------------------------- constant defined here
...
LL | if let CONST_STRING = empty_str {}
| ^^^^^^^^^^^^
| ^^^^^^^^^^^^ constant of non-structural type
--> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
|
= note: `Vec<u8>` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
|
= note: the traits must be derived, manual `impl`s are not sufficient
= note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
error: aborting due to 1 previous error

View File

@ -1,8 +1,11 @@
error: `dyn PartialEq<u32>` cannot be used in patterns
error: trait object `dyn PartialEq<u32>` cannot be used in patterns
--> $DIR/issue-72565.rs:6:9
|
LL | const F: &'static dyn PartialEq<u32> = &7u32;
| ------------------------------------ constant defined here
...
LL | F => panic!(),
| ^
| ^ trait object can't be used in patterns
error: aborting due to 1 previous error

View File

@ -2,25 +2,31 @@ error[E0080]: runtime values cannot be referenced in patterns
--> $DIR/non-constant-in-const-path.rs:8:15
|
LL | let 0u8..=x = 0;
| ^
| ^ references a runtime value
error[E0158]: statics cannot be referenced in patterns
--> $DIR/non-constant-in-const-path.rs:10:15
|
LL | static FOO: u8 = 10;
| -------------- `static` defined here
...
LL | let 0u8..=FOO = 0;
| ^^^
| ^^^ can't be used in patterns
error[E0080]: runtime values cannot be referenced in patterns
--> $DIR/non-constant-in-const-path.rs:13:15
|
LL | 0 ..= x => {}
| ^
| ^ references a runtime value
error[E0158]: statics cannot be referenced in patterns
--> $DIR/non-constant-in-const-path.rs:15:15
|
LL | static FOO: u8 = 10;
| -------------- `static` defined here
...
LL | 0 ..= FOO => {}
| ^^^
| ^^^ can't be used in patterns
error: aborting due to 4 previous errors

View File

@ -1,14 +1,14 @@
error: `{closure@$DIR/non-structural-match-types.rs:9:17: 9:19}` cannot be used in patterns
error: closure `{closure@$DIR/non-structural-match-types.rs:9:17: 9:19}` cannot be used in patterns
--> $DIR/non-structural-match-types.rs:9:9
|
LL | const { || {} } => {}
| ^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^ closure can't be used in patterns
error: `{async block@$DIR/non-structural-match-types.rs:12:17: 12:22}` cannot be used in patterns
error: `async` block `{async block@$DIR/non-structural-match-types.rs:12:17: 12:22}` cannot be used in patterns
--> $DIR/non-structural-match-types.rs:12:9
|
LL | const { async {} } => {}
| ^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^ `async` block can't be used in patterns
error: aborting due to 2 previous errors

View File

@ -12,7 +12,7 @@ const CONSTANT: &&MyType = &&MyType;
fn main() {
if let CONSTANT = &&MyType {
//~^ ERROR must be annotated with `#[derive(PartialEq)]`
//~^ ERROR constant of non-structural type `MyType` in a pattern
println!("did match!");
}
}

View File

@ -1,11 +1,20 @@
error: to use a constant of type `MyType` in a pattern, `MyType` must be annotated with `#[derive(PartialEq)]`
error: constant of non-structural type `MyType` in a pattern
--> $DIR/const-partial_eq-fallback-ice.rs:14:12
|
LL | struct MyType;
| ------------- `MyType` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
...
LL | const CONSTANT: &&MyType = &&MyType;
| ------------------------ constant defined here
...
LL | if let CONSTANT = &&MyType {
| ^^^^^^^^
| ^^^^^^^^ constant of non-structural type
|
= note: the traits must be derived, manual `impl`s are not sufficient
= note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
--> $DIR/const-partial_eq-fallback-ice.rs:5:1
|
LL | impl PartialEq<usize> for MyType {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 1 previous error

View File

@ -1,50 +1,90 @@
error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon
--> $DIR/consts-opaque.rs:96:9
|
LL | const QUUX: Quux = quux;
| ---------------- constant defined here
...
LL | QUUX => {}
| ^^^^
| ^^^^ can't be used in patterns
|
= note: see https://github.com/rust-lang/rust/issues/70861 for details
error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon
--> $DIR/consts-opaque.rs:97:9
|
LL | const QUUX: Quux = quux;
| ---------------- constant defined here
...
LL | QUUX => {}
| ^^^^
| ^^^^ can't be used in patterns
|
= note: see https://github.com/rust-lang/rust/issues/70861 for details
error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon
--> $DIR/consts-opaque.rs:106:9
|
LL | const WRAPQUUX: Wrap<Quux> = Wrap(quux);
| -------------------------- constant defined here
...
LL | WRAPQUUX => {}
| ^^^^^^^^
| ^^^^^^^^ can't be used in patterns
|
= note: see https://github.com/rust-lang/rust/issues/70861 for details
error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon
--> $DIR/consts-opaque.rs:107:9
|
LL | const WRAPQUUX: Wrap<Quux> = Wrap(quux);
| -------------------------- constant defined here
...
LL | WRAPQUUX => {}
| ^^^^^^^^
| ^^^^^^^^ can't be used in patterns
|
= note: see https://github.com/rust-lang/rust/issues/70861 for details
error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon
--> $DIR/consts-opaque.rs:113:9
|
LL | const WRAPQUUX: Wrap<Quux> = Wrap(quux);
| -------------------------- constant defined here
...
LL | WRAPQUUX => {}
| ^^^^^^^^
| ^^^^^^^^ can't be used in patterns
|
= note: see https://github.com/rust-lang/rust/issues/70861 for details
error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon
--> $DIR/consts-opaque.rs:121:9
|
LL | const WRAPQUUX: Wrap<Quux> = Wrap(quux);
| -------------------------- constant defined here
...
LL | WRAPQUUX => {}
| ^^^^^^^^
| ^^^^^^^^ can't be used in patterns
|
= note: see https://github.com/rust-lang/rust/issues/70861 for details
error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon
--> $DIR/consts-opaque.rs:132:9
|
LL | const WHOKNOWSQUUX: WhoKnows<Quux> = WhoKnows::Yay(quux);
| ---------------------------------- constant defined here
...
LL | WHOKNOWSQUUX => {}
| ^^^^^^^^^^^^
| ^^^^^^^^^^^^ can't be used in patterns
|
= note: see https://github.com/rust-lang/rust/issues/70861 for details
error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon
--> $DIR/consts-opaque.rs:134:9
|
LL | const WHOKNOWSQUUX: WhoKnows<Quux> = WhoKnows::Yay(quux);
| ---------------------------------- constant defined here
...
LL | WHOKNOWSQUUX => {}
| ^^^^^^^^^^^^
| ^^^^^^^^^^^^ can't be used in patterns
|
= note: see https://github.com/rust-lang/rust/issues/70861 for details
error: unreachable pattern
--> $DIR/consts-opaque.rs:48:9

View File

@ -20,7 +20,7 @@ const WRAP_DIRECT_INLINE: WrapInline = WrapInline(NoDerive(0));
fn main() {
match WRAP_DIRECT_INLINE {
WRAP_DIRECT_INLINE => { panic!("WRAP_DIRECT_INLINE matched itself"); }
//~^ ERROR must be annotated with `#[derive(PartialEq)]`
//~^ ERROR constant of non-structural type `NoDerive` in a pattern
_ => { println!("WRAP_DIRECT_INLINE did not match itself"); }
}
}

View File

@ -1,11 +1,20 @@
error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]`
error: constant of non-structural type `NoDerive` in a pattern
--> $DIR/cant-hide-behind-direct-struct-embedded.rs:22:9
|
LL | struct NoDerive(#[allow(dead_code)] i32);
| --------------- `NoDerive` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
...
LL | const WRAP_DIRECT_INLINE: WrapInline = WrapInline(NoDerive(0));
| ------------------------------------ constant defined here
...
LL | WRAP_DIRECT_INLINE => { panic!("WRAP_DIRECT_INLINE matched itself"); }
| ^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^ constant of non-structural type
|
= note: the traits must be derived, manual `impl`s are not sufficient
= note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
--> $DIR/cant-hide-behind-direct-struct-embedded.rs:11:1
|
LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 1 previous error

View File

@ -19,7 +19,7 @@ const WRAP_DIRECT_PARAM: WrapParam<NoDerive> = WrapParam(NoDerive(0));
fn main() {
match WRAP_DIRECT_PARAM {
WRAP_DIRECT_PARAM => { panic!("WRAP_DIRECT_PARAM matched itself"); }
//~^ ERROR must be annotated with `#[derive(PartialEq)]`
//~^ ERROR constant of non-structural type `NoDerive` in a pattern
_ => { println!("WRAP_DIRECT_PARAM did not match itself"); }
}
}

View File

@ -1,11 +1,20 @@
error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]`
error: constant of non-structural type `NoDerive` in a pattern
--> $DIR/cant-hide-behind-direct-struct-param.rs:21:9
|
LL | struct NoDerive(i32);
| --------------- `NoDerive` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
...
LL | const WRAP_DIRECT_PARAM: WrapParam<NoDerive> = WrapParam(NoDerive(0));
| -------------------------------------------- constant defined here
...
LL | WRAP_DIRECT_PARAM => { panic!("WRAP_DIRECT_PARAM matched itself"); }
| ^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^ constant of non-structural type
|
= note: the traits must be derived, manual `impl`s are not sufficient
= note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
--> $DIR/cant-hide-behind-direct-struct-param.rs:10:1
|
LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 1 previous error

View File

@ -20,7 +20,7 @@ const WRAP_DOUBLY_INDIRECT_INLINE: & &WrapInline = & &WrapInline(& & NoDerive(0)
fn main() {
match WRAP_DOUBLY_INDIRECT_INLINE {
WRAP_DOUBLY_INDIRECT_INLINE => { panic!("WRAP_DOUBLY_INDIRECT_INLINE matched itself"); }
//~^ ERROR must be annotated with `#[derive(PartialEq)]`
//~^ ERROR constant of non-structural type `NoDerive` in a pattern
_ => { println!("WRAP_DOUBLY_INDIRECT_INLINE correctly did not match itself"); }
}
}

View File

@ -1,11 +1,20 @@
error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]`
error: constant of non-structural type `NoDerive` in a pattern
--> $DIR/cant-hide-behind-doubly-indirect-embedded.rs:22:9
|
LL | struct NoDerive(#[allow(dead_code)] i32);
| --------------- `NoDerive` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
...
LL | const WRAP_DOUBLY_INDIRECT_INLINE: & &WrapInline = & &WrapInline(& & NoDerive(0));
| ------------------------------------------------ constant defined here
...
LL | WRAP_DOUBLY_INDIRECT_INLINE => { panic!("WRAP_DOUBLY_INDIRECT_INLINE matched itself"); }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ constant of non-structural type
|
= note: the traits must be derived, manual `impl`s are not sufficient
= note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
--> $DIR/cant-hide-behind-doubly-indirect-embedded.rs:11:1
|
LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 1 previous error

View File

@ -20,7 +20,7 @@ const WRAP_DOUBLY_INDIRECT_PARAM: & &WrapParam<NoDerive> = & &WrapParam(& & NoDe
fn main() {
match WRAP_DOUBLY_INDIRECT_PARAM {
WRAP_DOUBLY_INDIRECT_PARAM => { panic!("WRAP_DOUBLY_INDIRECT_PARAM matched itself"); }
//~^ ERROR must be annotated with `#[derive(PartialEq)]`
//~^ ERROR constant of non-structural type `NoDerive` in a pattern
_ => { println!("WRAP_DOUBLY_INDIRECT_PARAM correctly did not match itself"); }
}
}

View File

@ -1,11 +1,20 @@
error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]`
error: constant of non-structural type `NoDerive` in a pattern
--> $DIR/cant-hide-behind-doubly-indirect-param.rs:22:9
|
LL | struct NoDerive(#[allow(dead_code)] i32);
| --------------- `NoDerive` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
...
LL | const WRAP_DOUBLY_INDIRECT_PARAM: & &WrapParam<NoDerive> = & &WrapParam(& & NoDerive(0));
| -------------------------------------------------------- constant defined here
...
LL | WRAP_DOUBLY_INDIRECT_PARAM => { panic!("WRAP_DOUBLY_INDIRECT_PARAM matched itself"); }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ constant of non-structural type
|
= note: the traits must be derived, manual `impl`s are not sufficient
= note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
--> $DIR/cant-hide-behind-doubly-indirect-param.rs:11:1
|
LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 1 previous error

View File

@ -20,7 +20,7 @@ const WRAP_INDIRECT_INLINE: & &WrapInline = & &WrapInline(NoDerive(0));
fn main() {
match WRAP_INDIRECT_INLINE {
WRAP_INDIRECT_INLINE => { panic!("WRAP_INDIRECT_INLINE matched itself"); }
//~^ ERROR must be annotated with `#[derive(PartialEq)]`
//~^ ERROR constant of non-structural type `NoDerive` in a pattern
_ => { println!("WRAP_INDIRECT_INLINE did not match itself"); }
}
}

View File

@ -1,11 +1,20 @@
error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]`
error: constant of non-structural type `NoDerive` in a pattern
--> $DIR/cant-hide-behind-indirect-struct-embedded.rs:22:9
|
LL | struct NoDerive(#[allow(dead_code)] i32);
| --------------- `NoDerive` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
...
LL | const WRAP_INDIRECT_INLINE: & &WrapInline = & &WrapInline(NoDerive(0));
| ----------------------------------------- constant defined here
...
LL | WRAP_INDIRECT_INLINE => { panic!("WRAP_INDIRECT_INLINE matched itself"); }
| ^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^ constant of non-structural type
|
= note: the traits must be derived, manual `impl`s are not sufficient
= note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
--> $DIR/cant-hide-behind-indirect-struct-embedded.rs:11:1
|
LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 1 previous error

View File

@ -20,7 +20,7 @@ const WRAP_INDIRECT_PARAM: & &WrapParam<NoDerive> = & &WrapParam(NoDerive(0));
fn main() {
match WRAP_INDIRECT_PARAM {
WRAP_INDIRECT_PARAM => { panic!("WRAP_INDIRECT_PARAM matched itself"); }
//~^ ERROR must be annotated with `#[derive(PartialEq)]`
//~^ ERROR constant of non-structural type `NoDerive` in a pattern
_ => { println!("WRAP_INDIRECT_PARAM correctly did not match itself"); }
}
}

View File

@ -1,11 +1,20 @@
error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]`
error: constant of non-structural type `NoDerive` in a pattern
--> $DIR/cant-hide-behind-indirect-struct-param.rs:22:9
|
LL | struct NoDerive(#[allow(dead_code)] i32);
| --------------- `NoDerive` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
...
LL | const WRAP_INDIRECT_PARAM: & &WrapParam<NoDerive> = & &WrapParam(NoDerive(0));
| ------------------------------------------------- constant defined here
...
LL | WRAP_INDIRECT_PARAM => { panic!("WRAP_INDIRECT_PARAM matched itself"); }
| ^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^ constant of non-structural type
|
= note: the traits must be derived, manual `impl`s are not sufficient
= note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
--> $DIR/cant-hide-behind-indirect-struct-param.rs:11:1
|
LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 1 previous error

View File

@ -1,62 +1,112 @@
error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon
--> $DIR/fn-ptr-is-not-structurally-matchable.rs:41:14
|
LL | const CFN1: Wrap<fn()> = Wrap(trivial);
| ---------------------- constant defined here
...
LL | Wrap(CFN1) => count += 1,
| ^^^^
| ^^^^ can't be used in patterns
|
= note: see https://github.com/rust-lang/rust/issues/70861 for details
error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon
--> $DIR/fn-ptr-is-not-structurally-matchable.rs:49:14
|
LL | const CFN2: Wrap<fn(SM)> = Wrap(sm_to);
| ------------------------ constant defined here
...
LL | Wrap(CFN2) => count += 1,
| ^^^^
| ^^^^ can't be used in patterns
|
= note: see https://github.com/rust-lang/rust/issues/70861 for details
error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon
--> $DIR/fn-ptr-is-not-structurally-matchable.rs:57:14
|
LL | const CFN3: Wrap<fn() -> SM> = Wrap(to_sm);
| ---------------------------- constant defined here
...
LL | Wrap(CFN3) => count += 1,
| ^^^^
| ^^^^ can't be used in patterns
|
= note: see https://github.com/rust-lang/rust/issues/70861 for details
error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon
--> $DIR/fn-ptr-is-not-structurally-matchable.rs:65:14
|
LL | const CFN4: Wrap<fn(NotSM)> = Wrap(not_sm_to);
| --------------------------- constant defined here
...
LL | Wrap(CFN4) => count += 1,
| ^^^^
| ^^^^ can't be used in patterns
|
= note: see https://github.com/rust-lang/rust/issues/70861 for details
error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon
--> $DIR/fn-ptr-is-not-structurally-matchable.rs:73:14
|
LL | const CFN5: Wrap<fn() -> NotSM> = Wrap(to_not_sm);
| ------------------------------- constant defined here
...
LL | Wrap(CFN5) => count += 1,
| ^^^^
| ^^^^ can't be used in patterns
|
= note: see https://github.com/rust-lang/rust/issues/70861 for details
error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon
--> $DIR/fn-ptr-is-not-structurally-matchable.rs:81:14
|
LL | const CFN6: Wrap<fn(&SM)> = Wrap(r_sm_to);
| ------------------------- constant defined here
...
LL | Wrap(CFN6) => count += 1,
| ^^^^
| ^^^^ can't be used in patterns
|
= note: see https://github.com/rust-lang/rust/issues/70861 for details
error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon
--> $DIR/fn-ptr-is-not-structurally-matchable.rs:89:14
|
LL | const CFN7: Wrap<fn(&()) -> &SM> = Wrap(r_to_r_sm);
| -------------------------------- constant defined here
...
LL | Wrap(CFN7) => count += 1,
| ^^^^
| ^^^^ can't be used in patterns
|
= note: see https://github.com/rust-lang/rust/issues/70861 for details
error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon
--> $DIR/fn-ptr-is-not-structurally-matchable.rs:97:14
|
LL | const CFN8: Wrap<fn(&NotSM)> = Wrap(r_not_sm_to);
| ---------------------------- constant defined here
...
LL | Wrap(CFN8) => count += 1,
| ^^^^
| ^^^^ can't be used in patterns
|
= note: see https://github.com/rust-lang/rust/issues/70861 for details
error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon
--> $DIR/fn-ptr-is-not-structurally-matchable.rs:105:14
|
LL | const CFN9: Wrap<fn(&()) -> &NotSM> = Wrap(r_to_r_not_sm);
| ----------------------------------- constant defined here
...
LL | Wrap(CFN9) => count += 1,
| ^^^^
| ^^^^ can't be used in patterns
|
= note: see https://github.com/rust-lang/rust/issues/70861 for details
error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon
--> $DIR/fn-ptr-is-not-structurally-matchable.rs:127:9
|
LL | const CFOO: Foo = Foo {
| --------------- constant defined here
...
LL | CFOO => count += 1,
| ^^^^
| ^^^^ can't be used in patterns
|
= note: see https://github.com/rust-lang/rust/issues/70861 for details
error: aborting due to 10 previous errors

View File

@ -12,8 +12,7 @@ const A: &[B] = &[];
pub fn main() {
match &[][..] {
A => (),
//~^ ERROR must implement `PartialEq`
A => (), //~ ERROR constant of non-structural type `&[B]` in a pattern
_ => (),
}
}

View File

@ -1,8 +1,16 @@
error: to use a constant of type `&[B]` in a pattern, the type must implement `PartialEq`
error: constant of non-structural type `&[B]` in a pattern
--> $DIR/issue-61188-match-slice-forbidden-without-eq.rs:15:9
|
LL | struct B(i32);
| -------- must be annotated with `#[derive(PartialEq)]` to be usable in patterns
LL |
LL | const A: &[B] = &[];
| ------------- constant defined here
...
LL | A => (),
| ^
| ^ constant of non-structural type
|
= note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
error: aborting due to 1 previous error

View File

@ -13,27 +13,35 @@
#[derive(Debug)]
struct B(i32);
//~^ NOTE `B` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
//~| NOTE `B` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
// Overriding `PartialEq` to use this strange notion of "equality" exposes
// whether `match` is using structural-equality or method-dispatch
// under the hood, which is the antithesis of rust-lang/rfcs#1445
impl PartialEq for B {
//~^ NOTE the `PartialEq` trait must be derived, manual `impl`s are not sufficient
//~| NOTE the `PartialEq` trait must be derived, manual `impl`s are not sufficient
fn eq(&self, other: &B) -> bool { std::cmp::min(self.0, other.0) == 0 }
}
fn main() {
const RR_B0: & & B = & & B(0);
const RR_B1: & & B = & & B(1);
//~^ NOTE constant defined here
//~| NOTE constant defined here
match RR_B0 {
RR_B1 => { println!("CLAIM RR0: {:?} matches {:?}", RR_B1, RR_B0); }
//~^ ERROR must be annotated with `#[derive(PartialEq)]`
//~^ ERROR constant of non-structural type `B` in a pattern
//~| NOTE constant of non-structural type
_ => { }
}
match RR_B1 {
RR_B1 => { println!("CLAIM RR1: {:?} matches {:?}", RR_B1, RR_B1); }
//~^ ERROR must be annotated with `#[derive(PartialEq)]`
//~^ ERROR constant of non-structural type `B` in a pattern
//~| NOTE constant of non-structural type
_ => { }
}
}

View File

@ -1,20 +1,38 @@
error: to use a constant of type `B` in a pattern, `B` must be annotated with `#[derive(PartialEq)]`
--> $DIR/issue-62307-match-ref-ref-forbidden-without-eq.rs:29:9
|
LL | RR_B1 => { println!("CLAIM RR0: {:?} matches {:?}", RR_B1, RR_B0); }
| ^^^^^
|
= note: the traits must be derived, manual `impl`s are not sufficient
= note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
error: to use a constant of type `B` in a pattern, `B` must be annotated with `#[derive(PartialEq)]`
error: constant of non-structural type `B` in a pattern
--> $DIR/issue-62307-match-ref-ref-forbidden-without-eq.rs:35:9
|
LL | RR_B1 => { println!("CLAIM RR1: {:?} matches {:?}", RR_B1, RR_B1); }
| ^^^^^
LL | struct B(i32);
| -------- `B` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
...
LL | const RR_B1: & & B = & & B(1);
| ------------------ constant defined here
...
LL | RR_B1 => { println!("CLAIM RR0: {:?} matches {:?}", RR_B1, RR_B0); }
| ^^^^^ constant of non-structural type
|
= note: the traits must be derived, manual `impl`s are not sufficient
= note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
--> $DIR/issue-62307-match-ref-ref-forbidden-without-eq.rs:22:1
|
LL | impl PartialEq for B {
| ^^^^^^^^^^^^^^^^^^^^
error: constant of non-structural type `B` in a pattern
--> $DIR/issue-62307-match-ref-ref-forbidden-without-eq.rs:42:9
|
LL | struct B(i32);
| -------- `B` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
...
LL | const RR_B1: & & B = & & B(1);
| ------------------ constant defined here
...
LL | RR_B1 => { println!("CLAIM RR1: {:?} matches {:?}", RR_B1, RR_B1); }
| ^^^^^ constant of non-structural type
|
note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
--> $DIR/issue-62307-match-ref-ref-forbidden-without-eq.rs:22:1
|
LL | impl PartialEq for B {
| ^^^^^^^^^^^^^^^^^^^^
error: aborting due to 2 previous errors

View File

@ -1,14 +1,24 @@
error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon
--> $DIR/issue-63479-match-fnptr.rs:32:7
|
LL | const TEST: Fn = my_fn;
| -------------- constant defined here
...
LL | B(TEST) => println!("matched"),
| ^^^^
| ^^^^ can't be used in patterns
|
= note: see https://github.com/rust-lang/rust/issues/70861 for details
error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon
--> $DIR/issue-63479-match-fnptr.rs:37:5
|
LL | const TEST2: (Fn, u8) = (TEST, 0);
| --------------------- constant defined here
...
LL | TEST2 => println!("matched"),
| ^^^^^
| ^^^^^ can't be used in patterns
|
= note: see https://github.com/rust-lang/rust/issues/70861 for details
error: aborting due to 2 previous errors

View File

@ -1,8 +1,11 @@
error: cannot use NaN in patterns
--> $DIR/issue-6804-nan-match.rs:14:9
|
LL | const NAN: f64 = f64::NAN;
| -------------- constant defined here
...
LL | NAN => {},
| ^^^
| ^^^ evaluates to `NaN`, which is not allowed in patterns
|
= note: NaNs compare inequal to everything, even themselves, so this pattern would never match
= help: try using the `is_nan` method instead
@ -10,8 +13,11 @@ LL | NAN => {},
error: cannot use NaN in patterns
--> $DIR/issue-6804-nan-match.rs:19:10
|
LL | const NAN: f64 = f64::NAN;
| -------------- constant defined here
...
LL | [NAN, _] => {},
| ^^^
| ^^^ evaluates to `NaN`, which is not allowed in patterns
|
= note: NaNs compare inequal to everything, even themselves, so this pattern would never match
= help: try using the `is_nan` method instead
@ -19,8 +25,11 @@ LL | [NAN, _] => {},
error: cannot use NaN in patterns
--> $DIR/issue-6804-nan-match.rs:24:9
|
LL | const C: MyType<f32> = MyType(f32::NAN);
| -------------------- constant defined here
...
LL | C => {},
| ^
| ^ evaluates to `NaN`, which is not allowed in patterns
|
= note: NaNs compare inequal to everything, even themselves, so this pattern would never match
= help: try using the `is_nan` method instead
@ -28,8 +37,11 @@ LL | C => {},
error: cannot use NaN in patterns
--> $DIR/issue-6804-nan-match.rs:30:9
|
LL | const NAN: f64 = f64::NAN;
| -------------- constant defined here
...
LL | NAN..=1.0 => {},
| ^^^
| ^^^ evaluates to `NaN`, which is not allowed in patterns
|
= note: NaNs compare inequal to everything, even themselves, so this pattern would never match
= help: try using the `is_nan` method instead
@ -37,8 +49,11 @@ LL | NAN..=1.0 => {},
error: cannot use NaN in patterns
--> $DIR/issue-6804-nan-match.rs:31:16
|
LL | const NAN: f64 = f64::NAN;
| -------------- constant defined here
...
LL | -1.0..=NAN => {},
| ^^^
| ^^^ evaluates to `NaN`, which is not allowed in patterns
|
= note: NaNs compare inequal to everything, even themselves, so this pattern would never match
= help: try using the `is_nan` method instead
@ -46,8 +61,11 @@ LL | -1.0..=NAN => {},
error: cannot use NaN in patterns
--> $DIR/issue-6804-nan-match.rs:32:9
|
LL | const NAN: f64 = f64::NAN;
| -------------- constant defined here
...
LL | NAN.. => {},
| ^^^
| ^^^ evaluates to `NaN`, which is not allowed in patterns
|
= note: NaNs compare inequal to everything, even themselves, so this pattern would never match
= help: try using the `is_nan` method instead
@ -55,8 +73,11 @@ LL | NAN.. => {},
error: cannot use NaN in patterns
--> $DIR/issue-6804-nan-match.rs:33:11
|
LL | const NAN: f64 = f64::NAN;
| -------------- constant defined here
...
LL | ..NAN => {},
| ^^^
| ^^^ evaluates to `NaN`, which is not allowed in patterns
|
= note: NaNs compare inequal to everything, even themselves, so this pattern would never match
= help: try using the `is_nan` method instead

View File

@ -1,3 +1,5 @@
// Note: It is no longer true that both `Eq` and `PartialEq` must the derived, only the later.
#[derive(Eq)]
struct Foo {
x: u32
@ -15,7 +17,7 @@ fn main() {
let y = Foo { x: 1 };
match y {
FOO => { }
//~^ ERROR must be annotated with `#[derive(PartialEq)]`
//~^ ERROR constant of non-structural type `Foo` in a pattern
_ => { }
}
}

View File

@ -1,11 +1,20 @@
error: to use a constant of type `Foo` in a pattern, `Foo` must be annotated with `#[derive(PartialEq)]`
--> $DIR/match-requires-both-partialeq-and-eq.rs:17:9
error: constant of non-structural type `Foo` in a pattern
--> $DIR/match-requires-both-partialeq-and-eq.rs:19:9
|
LL | struct Foo {
| ---------- `Foo` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
...
LL | const FOO: Foo = Foo { x: 0 };
| -------------- constant defined here
...
LL | FOO => { }
| ^^^
| ^^^ constant of non-structural type
|
= note: the traits must be derived, manual `impl`s are not sufficient
= note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
--> $DIR/match-requires-both-partialeq-and-eq.rs:8:1
|
LL | impl PartialEq for Foo {
| ^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 1 previous error

View File

@ -1,8 +1,11 @@
error: `Bar` cannot be used in patterns
error: opaque type `Bar` cannot be used in patterns
--> $DIR/structural-match-no-leak.rs:16:9
|
LL | const LEAK_FREE: bar::Bar = bar::leak_free();
| ------------------------- constant defined here
...
LL | LEAK_FREE => (),
| ^^^^^^^^^
| ^^^^^^^^^ opaque type can't be used in patterns
error: aborting due to 1 previous error

View File

@ -1,8 +1,11 @@
error: `foo::Foo` cannot be used in patterns
error: opaque type `foo::Foo` cannot be used in patterns
--> $DIR/structural-match.rs:18:9
|
LL | const VALUE: Foo = value();
| ---------------- constant defined here
...
LL | VALUE => (),
| ^^^^^
| ^^^^^ opaque type can't be used in patterns
error: aborting due to 1 previous error

View File

@ -1,8 +1,11 @@
error: cannot use unions in constant patterns
--> $DIR/union-const-pat.rs:10:9
|
LL | const C: U = U { a: 10 };
| ---------- constant defined here
...
LL | C => {}
| ^
| ^ can't use a `union` here
error: aborting due to 1 previous error