Add additional context for non-sructural type constant used in pattern
- Point at type that should derive `PartialEq` to be structural. - Point at manual `impl PartialEq`, explaining that it is not sufficient to be structural. ``` 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 `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 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ```
This commit is contained in:
parent
fb2f6a44c0
commit
335d05aee5
33 changed files with 343 additions and 175 deletions
|
@ -322,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 `{$non_sm_ty}` in a pattern
|
||||
.label = constant of non-structural type
|
||||
mir_build_type_not_structural_def = `{$non_sm_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
|
||||
|
|
|
@ -882,12 +882,17 @@ pub(crate) struct UnionPattern {
|
|||
|
||||
#[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,
|
||||
#[label(mir_build_type_not_structural_def)]
|
||||
pub(crate) ty_def_span: Span,
|
||||
pub(crate) non_sm_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)]
|
||||
|
|
|
@ -254,7 +254,22 @@ 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 ty_def_span = tcx.def_span(adt_def.did());
|
||||
let mut manual_partialeq_impl_span = None;
|
||||
let partial_eq_trait_id =
|
||||
tcx.require_lang_item(hir::LangItem::PartialEq, Some(self.span));
|
||||
tcx.for_each_relevant_impl(partial_eq_trait_id, ty, |def_id| {
|
||||
if def_id.is_local() {
|
||||
manual_partialeq_impl_span = Some(tcx.def_span(def_id));
|
||||
}
|
||||
});
|
||||
let err = TypeNotStructural {
|
||||
span,
|
||||
non_sm_ty: ty,
|
||||
ty_def_span,
|
||||
manual_partialeq_impl_span,
|
||||
manual_partialeq_impl_note: manual_partialeq_impl_span.is_none(),
|
||||
};
|
||||
return Err(tcx.dcx().create_err(err));
|
||||
}
|
||||
ty::Adt(adt_def, args) if adt_def.is_enum() => {
|
||||
|
@ -269,7 +284,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)),
|
||||
),
|
||||
),
|
||||
}
|
||||
|
@ -278,7 +293,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)),
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
@ -377,7 +392,7 @@ impl<'tcx> ConstToPat<'tcx> {
|
|||
let err = InvalidPattern {
|
||||
span,
|
||||
non_sm_ty: ty,
|
||||
prefix: ty.prefix_string(self.tcx).to_string(),
|
||||
prefix: ty.prefix_string(tcx).to_string(),
|
||||
};
|
||||
return Err(tcx.dcx().create_err(err));
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue