mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-17 09:23:05 +00:00
Remove non-descriptive boolean from search_for_structural_match_violation
This commit is contained in:
parent
c1f54c30bb
commit
10b69ab0d2
@ -226,7 +226,7 @@ impl Qualif for CustomEq {
|
||||
// because that component may be part of an enum variant (e.g.,
|
||||
// `Option::<NonStructuralMatchTy>::Some`), in which case some values of this type may be
|
||||
// structural-match (`Option::None`).
|
||||
traits::search_for_structural_match_violation(cx.body.span, cx.tcx, ty, false).is_some()
|
||||
traits::search_for_structural_match_violation(cx.body.span, cx.tcx, ty).is_some()
|
||||
}
|
||||
|
||||
fn in_adt_inherently<'tcx>(
|
||||
|
@ -120,37 +120,35 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
|
||||
}
|
||||
|
||||
fn search_for_structural_match_violation(&self, ty: Ty<'tcx>) -> Option<String> {
|
||||
traits::search_for_structural_match_violation(self.span, self.tcx(), ty, false).map(
|
||||
|non_sm_ty| {
|
||||
with_no_trimmed_paths!(match non_sm_ty.kind() {
|
||||
ty::Adt(adt, _) => self.adt_derive_msg(*adt),
|
||||
ty::Dynamic(..) => {
|
||||
"trait objects cannot be used in patterns".to_string()
|
||||
}
|
||||
ty::Opaque(..) => {
|
||||
"opaque types cannot be used in patterns".to_string()
|
||||
}
|
||||
ty::Closure(..) => {
|
||||
"closures cannot be used in patterns".to_string()
|
||||
}
|
||||
ty::Generator(..) | ty::GeneratorWitness(..) => {
|
||||
"generators cannot be used in patterns".to_string()
|
||||
}
|
||||
ty::Float(..) => {
|
||||
"floating-point numbers cannot be used in patterns".to_string()
|
||||
}
|
||||
ty::FnPtr(..) => {
|
||||
"function pointers cannot be used in patterns".to_string()
|
||||
}
|
||||
ty::RawPtr(..) => {
|
||||
"raw pointers cannot be used in patterns".to_string()
|
||||
}
|
||||
_ => {
|
||||
bug!("use of a value of `{non_sm_ty}` inside a pattern")
|
||||
}
|
||||
})
|
||||
},
|
||||
)
|
||||
traits::search_for_structural_match_violation(self.span, self.tcx(), ty).map(|non_sm_ty| {
|
||||
with_no_trimmed_paths!(match non_sm_ty.kind() {
|
||||
ty::Adt(adt, _) => self.adt_derive_msg(*adt),
|
||||
ty::Dynamic(..) => {
|
||||
"trait objects cannot be used in patterns".to_string()
|
||||
}
|
||||
ty::Opaque(..) => {
|
||||
"opaque types cannot be used in patterns".to_string()
|
||||
}
|
||||
ty::Closure(..) => {
|
||||
"closures cannot be used in patterns".to_string()
|
||||
}
|
||||
ty::Generator(..) | ty::GeneratorWitness(..) => {
|
||||
"generators cannot be used in patterns".to_string()
|
||||
}
|
||||
ty::Float(..) => {
|
||||
"floating-point numbers cannot be used in patterns".to_string()
|
||||
}
|
||||
ty::FnPtr(..) => {
|
||||
"function pointers cannot be used in patterns".to_string()
|
||||
}
|
||||
ty::RawPtr(..) => {
|
||||
"raw pointers cannot be used in patterns".to_string()
|
||||
}
|
||||
_ => {
|
||||
bug!("use of a value of `{non_sm_ty}` inside a pattern")
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
fn type_marked_structural(&self, ty: Ty<'tcx>) -> bool {
|
||||
|
@ -60,7 +60,9 @@ pub use self::select::{EvaluationResult, IntercrateAmbiguityCause, OverflowError
|
||||
pub use self::specialize::specialization_graph::FutureCompatOverlapError;
|
||||
pub use self::specialize::specialization_graph::FutureCompatOverlapErrorKind;
|
||||
pub use self::specialize::{specialization_graph, translate_substs, OverlapError};
|
||||
pub use self::structural_match::search_for_structural_match_violation;
|
||||
pub use self::structural_match::{
|
||||
search_for_adt_const_param_violation, search_for_structural_match_violation,
|
||||
};
|
||||
pub use self::util::{
|
||||
elaborate_obligations, elaborate_predicates, elaborate_predicates_with_span,
|
||||
elaborate_trait_ref, elaborate_trait_refs,
|
||||
|
@ -35,16 +35,28 @@ use std::ops::ControlFlow;
|
||||
/// For more background on why Rust has this requirement, and issues
|
||||
/// that arose when the requirement was not enforced completely, see
|
||||
/// Rust RFC 1445, rust-lang/rust#61188, and rust-lang/rust#62307.
|
||||
///
|
||||
/// When the `valtree_semantics` flag is set, then we also deny additional
|
||||
/// types that are not evaluatable to valtrees, such as floats and fn ptrs.
|
||||
pub fn search_for_structural_match_violation<'tcx>(
|
||||
span: Span,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
ty: Ty<'tcx>,
|
||||
valtree_semantics: bool,
|
||||
) -> Option<Ty<'tcx>> {
|
||||
ty.visit_with(&mut Search { tcx, span, seen: FxHashSet::default(), valtree_semantics })
|
||||
ty.visit_with(&mut Search { tcx, span, seen: FxHashSet::default(), adt_const_param: false })
|
||||
.break_value()
|
||||
}
|
||||
|
||||
/// This method traverses the structure of `ty`, trying to find any
|
||||
/// types that are not allowed to be used in a const generic.
|
||||
///
|
||||
/// This is either because the type does not implement `StructuralEq`
|
||||
/// and `StructuralPartialEq`, or because the type is intentionally
|
||||
/// not supported in const generics (such as floats and raw pointers,
|
||||
/// which are allowed in match blocks).
|
||||
pub fn search_for_adt_const_param_violation<'tcx>(
|
||||
span: Span,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
ty: Ty<'tcx>,
|
||||
) -> Option<Ty<'tcx>> {
|
||||
ty.visit_with(&mut Search { tcx, span, seen: FxHashSet::default(), adt_const_param: true })
|
||||
.break_value()
|
||||
}
|
||||
|
||||
@ -108,8 +120,9 @@ struct Search<'tcx> {
|
||||
seen: FxHashSet<hir::def_id::DefId>,
|
||||
|
||||
// Additionally deny things that have been allowed in patterns,
|
||||
// but are not evaluatable to a valtree, such as floats and fn ptrs.
|
||||
valtree_semantics: bool,
|
||||
// but are not allowed in adt const params, such as floats and
|
||||
// fn ptrs.
|
||||
adt_const_param: bool,
|
||||
}
|
||||
|
||||
impl<'tcx> Search<'tcx> {
|
||||
@ -167,7 +180,7 @@ impl<'tcx> TypeVisitor<'tcx> for Search<'tcx> {
|
||||
}
|
||||
|
||||
ty::FnPtr(..) => {
|
||||
if !self.valtree_semantics {
|
||||
if !self.adt_const_param {
|
||||
return ControlFlow::CONTINUE;
|
||||
} else {
|
||||
return ControlFlow::Break(ty);
|
||||
@ -175,7 +188,7 @@ impl<'tcx> TypeVisitor<'tcx> for Search<'tcx> {
|
||||
}
|
||||
|
||||
ty::RawPtr(..) => {
|
||||
if !self.valtree_semantics {
|
||||
if !self.adt_const_param {
|
||||
// structural-match ignores substructure of
|
||||
// `*const _`/`*mut _`, so skip `super_visit_with`.
|
||||
//
|
||||
@ -197,7 +210,7 @@ impl<'tcx> TypeVisitor<'tcx> for Search<'tcx> {
|
||||
}
|
||||
|
||||
ty::Float(_) => {
|
||||
if !self.valtree_semantics {
|
||||
if !self.adt_const_param {
|
||||
return ControlFlow::CONTINUE;
|
||||
} else {
|
||||
return ControlFlow::Break(ty);
|
||||
|
@ -849,7 +849,7 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) {
|
||||
|
||||
if tcx.features().adt_const_params {
|
||||
if let Some(non_structural_match_ty) =
|
||||
traits::search_for_structural_match_violation(param.span, tcx, ty, true)
|
||||
traits::search_for_adt_const_param_violation(param.span, tcx, ty)
|
||||
{
|
||||
// We use the same error code in both branches, because this is really the same
|
||||
// issue: we just special-case the message for type parameters to make it
|
||||
|
Loading…
Reference in New Issue
Block a user