Skip to content

Commit 857918e

Browse files
committed
review comments
Replace tuple with struct and remove unnecessary early return.
1 parent 919f672 commit 857918e

File tree

1 file changed

+67
-57
lines changed

1 file changed

+67
-57
lines changed

Diff for: compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs

+67-57
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use core::ops::ControlFlow;
2+
13
use rustc_abi::{FieldIdx, VariantIdx};
24
use rustc_apfloat::Float;
35
use rustc_data_structures::fx::FxHashSet;
@@ -187,7 +189,7 @@ impl<'tcx> ConstToPat<'tcx> {
187189

188190
if !inlined_const_as_pat.references_error() {
189191
// Always check for `PartialEq` if we had no other errors yet.
190-
if !type_has_partial_eq_impl(self.tcx, typing_env, ty).0 {
192+
if !type_has_partial_eq_impl(self.tcx, typing_env, ty).has_impl {
191193
let mut err = self.tcx.dcx().create_err(TypeNotPartialEq { span: self.span, ty });
192194
extend_type_not_partial_eq(self.tcx, typing_env, ty, &mut err);
193195
return self.mk_err(err, ty);
@@ -221,12 +223,13 @@ impl<'tcx> ConstToPat<'tcx> {
221223
// Extremely important check for all ADTs! Make sure they opted-in to be used in
222224
// patterns.
223225
debug!("adt_def {:?} has !type_marked_structural for cv.ty: {:?}", adt_def, ty);
224-
let (_impls_partial_eq, derived, structural, impl_def_id) =
225-
type_has_partial_eq_impl(self.tcx, self.typing_env, ty);
226+
let PartialEqImplStatus {
227+
is_derived, structural_partial_eq, non_blanket_impl, ..
228+
} = type_has_partial_eq_impl(self.tcx, self.typing_env, ty);
226229
let (manual_partialeq_impl_span, manual_partialeq_impl_note) =
227-
match (structural, impl_def_id) {
230+
match (structural_partial_eq, non_blanket_impl) {
228231
(true, _) => (None, false),
229-
(_, Some(def_id)) if def_id.is_local() && !derived => {
232+
(_, Some(def_id)) if def_id.is_local() && !is_derived => {
230233
(Some(tcx.def_span(def_id)), false)
231234
}
232235
_ => (None, true),
@@ -385,40 +388,46 @@ fn extend_type_not_partial_eq<'tcx>(
385388
/// The type has no `PartialEq` implementation, neither manual or derived, but
386389
/// we don't have a span to point at, so we'll just add them as a `note`.
387390
without: FxHashSet<Ty<'tcx>>,
388-
/// If any of the subtypes has escaping bounds (`for<'a>`), we won't emit a note.
389-
has_escaping_bound_vars: bool,
390391
}
391392

392393
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for UsedParamsNeedInstantiationVisitor<'tcx> {
394+
type Result = ControlFlow<()>;
393395
fn visit_ty(&mut self, ty: Ty<'tcx>) -> Self::Result {
394-
if ty.has_escaping_bound_vars() {
395-
self.has_escaping_bound_vars = true;
396-
} else if let ty::Adt(def, _args) = ty.kind() {
397-
let ty_def_id = def.did();
398-
let ty_def_span = self.tcx.def_span(ty_def_id);
399-
let (impls_partial_eq, derived, structural, impl_def_id) =
400-
type_has_partial_eq_impl(self.tcx, self.typing_env, ty);
401-
match (impls_partial_eq, derived, structural, impl_def_id) {
402-
(_, _, true, _) => {}
403-
(true, false, _, Some(def_id)) if def_id.is_local() => {
404-
self.adts_with_manual_partialeq.insert(self.tcx.def_span(def_id));
405-
}
406-
(true, false, _, _) if ty_def_id.is_local() => {
407-
self.adts_with_manual_partialeq.insert(ty_def_span);
408-
}
409-
(false, _, _, _) if ty_def_id.is_local() => {
410-
self.adts_without_partialeq.insert(ty_def_span);
411-
}
412-
(true, false, _, _) => {
413-
self.manual.insert(ty);
414-
}
415-
(false, _, _, _) => {
416-
self.without.insert(ty);
417-
}
418-
_ => {}
419-
};
396+
match ty.kind() {
397+
ty::Dynamic(..) => return ControlFlow::Break(()),
398+
ty::FnPtr(..) => return ControlFlow::Continue(()),
399+
ty::Adt(def, _args) => {
400+
let ty_def_id = def.did();
401+
let ty_def_span = self.tcx.def_span(ty_def_id);
402+
let PartialEqImplStatus {
403+
has_impl,
404+
is_derived,
405+
structural_partial_eq,
406+
non_blanket_impl,
407+
} = type_has_partial_eq_impl(self.tcx, self.typing_env, ty);
408+
match (has_impl, is_derived, structural_partial_eq, non_blanket_impl) {
409+
(_, _, true, _) => {}
410+
(true, false, _, Some(def_id)) if def_id.is_local() => {
411+
self.adts_with_manual_partialeq.insert(self.tcx.def_span(def_id));
412+
}
413+
(true, false, _, _) if ty_def_id.is_local() => {
414+
self.adts_with_manual_partialeq.insert(ty_def_span);
415+
}
416+
(false, _, _, _) if ty_def_id.is_local() => {
417+
self.adts_without_partialeq.insert(ty_def_span);
418+
}
419+
(true, false, _, _) => {
420+
self.manual.insert(ty);
421+
}
422+
(false, _, _, _) => {
423+
self.without.insert(ty);
424+
}
425+
_ => {}
426+
};
427+
ty.super_visit_with(self)
428+
}
429+
_ => ty.super_visit_with(self),
420430
}
421-
ty.super_visit_with(self)
422431
}
423432
}
424433
let mut v = UsedParamsNeedInstantiationVisitor {
@@ -428,10 +437,8 @@ fn extend_type_not_partial_eq<'tcx>(
428437
adts_without_partialeq: FxHashSet::default(),
429438
manual: FxHashSet::default(),
430439
without: FxHashSet::default(),
431-
has_escaping_bound_vars: false,
432440
};
433-
v.visit_ty(ty);
434-
if v.has_escaping_bound_vars {
441+
if v.visit_ty(ty).is_break() {
435442
return;
436443
}
437444
#[allow(rustc::potential_query_instability)] // Span labels will be sorted by the rendering
@@ -445,31 +452,38 @@ fn extend_type_not_partial_eq<'tcx>(
445452
"must be annotated with `#[derive(PartialEq)]` to be usable in patterns",
446453
);
447454
}
448-
#[allow(rustc::potential_query_instability)] // Span labels will be sorted by the rendering
449-
for ty in v.manual {
455+
#[allow(rustc::potential_query_instability)]
456+
let mut manual: Vec<_> = v.manual.into_iter().map(|t| t.to_string()).collect();
457+
manual.sort();
458+
for ty in manual {
450459
err.note(format!(
451460
"`{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"
452461
));
453462
}
454-
#[allow(rustc::potential_query_instability)] // Span labels will be sorted by the rendering
455-
for ty in v.without {
463+
#[allow(rustc::potential_query_instability)]
464+
let mut without: Vec<_> = v.without.into_iter().map(|t| t.to_string()).collect();
465+
without.sort();
466+
for ty in without {
456467
err.note(format!(
457468
"`{ty}` must be annotated with `#[derive(PartialEq)]` to be usable in patterns"
458469
));
459470
}
460471
}
461472

473+
#[derive(Debug)]
474+
struct PartialEqImplStatus {
475+
has_impl: bool,
476+
is_derived: bool,
477+
structural_partial_eq: bool,
478+
non_blanket_impl: Option<DefId>,
479+
}
480+
462481
#[instrument(level = "trace", skip(tcx), ret)]
463482
fn type_has_partial_eq_impl<'tcx>(
464483
tcx: TyCtxt<'tcx>,
465484
typing_env: ty::TypingEnv<'tcx>,
466485
ty: Ty<'tcx>,
467-
) -> (
468-
/* has impl */ bool,
469-
/* is derived */ bool,
470-
/* structural partial eq */ bool,
471-
/* non-blanket impl */ Option<DefId>,
472-
) {
486+
) -> PartialEqImplStatus {
473487
let (infcx, param_env) = tcx.infer_ctxt().build_with_typing_env(typing_env);
474488
// double-check there even *is* a semantic `PartialEq` to dispatch to.
475489
//
@@ -479,10 +493,6 @@ fn type_has_partial_eq_impl<'tcx>(
479493
let partial_eq_trait_id = tcx.require_lang_item(hir::LangItem::PartialEq, None);
480494
let structural_partial_eq_trait_id = tcx.require_lang_item(hir::LangItem::StructuralPeq, None);
481495

482-
if ty.has_escaping_bound_vars() {
483-
return (false, false, false, None);
484-
}
485-
486496
let partial_eq_obligation = Obligation::new(
487497
tcx,
488498
ObligationCause::dummy(),
@@ -510,10 +520,10 @@ fn type_has_partial_eq_impl<'tcx>(
510520
// that patterns can only do things that the code could also do without patterns, but it is
511521
// needed for backwards compatibility. The actual pattern matching compares primitive values,
512522
// `PartialEq::eq` never gets invoked, so there's no risk of us running non-const code.
513-
(
514-
infcx.predicate_must_hold_modulo_regions(&partial_eq_obligation),
515-
automatically_derived,
516-
structural_peq,
517-
impl_def_id,
518-
)
523+
PartialEqImplStatus {
524+
has_impl: infcx.predicate_must_hold_modulo_regions(&partial_eq_obligation),
525+
is_derived: automatically_derived,
526+
structural_partial_eq: structural_peq,
527+
non_blanket_impl: impl_def_id,
528+
}
519529
}

0 commit comments

Comments
 (0)