Skip to content

Commit 58ae641

Browse files
committed
review comments
Replace tuple with struct and remove unnecessary early return.
1 parent ad52527 commit 58ae641

File tree

1 file changed

+71
-57
lines changed

1 file changed

+71
-57
lines changed

compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs

+71-57
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ impl<'tcx> ConstToPat<'tcx> {
187187

188188
if !inlined_const_as_pat.references_error() {
189189
// Always check for `PartialEq` if we had no other errors yet.
190-
if !type_has_partial_eq_impl(self.tcx, typing_env, ty).0 {
190+
if !type_has_partial_eq_impl(self.tcx, typing_env, ty).has_impl {
191191
let mut err = self.tcx.dcx().create_err(TypeNotPartialEq { span: self.span, ty });
192192
extend_type_not_partial_eq(self.tcx, typing_env, ty, &mut err);
193193
return self.mk_err(err, ty);
@@ -221,12 +221,13 @@ impl<'tcx> ConstToPat<'tcx> {
221221
// Extremely important check for all ADTs! Make sure they opted-in to be used in
222222
// patterns.
223223
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);
224+
let PartialEqImplStatus {
225+
is_derived, structural_partial_eq, non_blanket_impl, ..
226+
} = type_has_partial_eq_impl(self.tcx, self.typing_env, ty);
226227
let (manual_partialeq_impl_span, manual_partialeq_impl_note) =
227-
match (structural, impl_def_id) {
228+
match (structural_partial_eq, non_blanket_impl) {
228229
(true, _) => (None, false),
229-
(_, Some(def_id)) if def_id.is_local() && !derived => {
230+
(_, Some(def_id)) if def_id.is_local() && !is_derived => {
230231
(Some(tcx.def_span(def_id)), false)
231232
}
232233
_ => (None, true),
@@ -385,40 +386,50 @@ fn extend_type_not_partial_eq<'tcx>(
385386
/// The type has no `PartialEq` implementation, neither manual or derived, but
386387
/// we don't have a span to point at, so we'll just add them as a `note`.
387388
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,
389+
/// If any of the subtypes has escaping bounds (`for<'a>`) or involves a trait object, we
390+
/// won't emit a note.
391+
should_note: bool,
390392
}
391393

392394
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for UsedParamsNeedInstantiationVisitor<'tcx> {
393-
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-
};
395+
fn visit_ty(&mut self, ty: Ty<'tcx>) {
396+
match ty.kind() {
397+
ty::Dynamic(..) => {
398+
self.should_note = false;
399+
}
400+
ty::FnPtr(..) => {}
401+
ty::Adt(def, _args) => {
402+
let ty_def_id = def.did();
403+
let ty_def_span = self.tcx.def_span(ty_def_id);
404+
let PartialEqImplStatus {
405+
has_impl,
406+
is_derived,
407+
structural_partial_eq,
408+
non_blanket_impl,
409+
} = type_has_partial_eq_impl(self.tcx, self.typing_env, ty);
410+
match (has_impl, is_derived, structural_partial_eq, non_blanket_impl) {
411+
(_, _, true, _) => {}
412+
(true, false, _, Some(def_id)) if def_id.is_local() => {
413+
self.adts_with_manual_partialeq.insert(self.tcx.def_span(def_id));
414+
}
415+
(true, false, _, _) if ty_def_id.is_local() => {
416+
self.adts_with_manual_partialeq.insert(ty_def_span);
417+
}
418+
(false, _, _, _) if ty_def_id.is_local() => {
419+
self.adts_without_partialeq.insert(ty_def_span);
420+
}
421+
(true, false, _, _) => {
422+
self.manual.insert(ty);
423+
}
424+
(false, _, _, _) => {
425+
self.without.insert(ty);
426+
}
427+
_ => {}
428+
};
429+
ty.super_visit_with(self);
430+
}
431+
_ => ty.super_visit_with(self),
420432
}
421-
ty.super_visit_with(self)
422433
}
423434
}
424435
let mut v = UsedParamsNeedInstantiationVisitor {
@@ -428,10 +439,10 @@ fn extend_type_not_partial_eq<'tcx>(
428439
adts_without_partialeq: FxHashSet::default(),
429440
manual: FxHashSet::default(),
430441
without: FxHashSet::default(),
431-
has_escaping_bound_vars: false,
442+
should_note: true,
432443
};
433444
v.visit_ty(ty);
434-
if v.has_escaping_bound_vars {
445+
if !v.should_note {
435446
return;
436447
}
437448
#[allow(rustc::potential_query_instability)] // Span labels will be sorted by the rendering
@@ -445,31 +456,38 @@ fn extend_type_not_partial_eq<'tcx>(
445456
"must be annotated with `#[derive(PartialEq)]` to be usable in patterns",
446457
);
447458
}
448-
#[allow(rustc::potential_query_instability)] // Span labels will be sorted by the rendering
449-
for ty in v.manual {
459+
#[allow(rustc::potential_query_instability)]
460+
let mut manual: Vec<_> = v.manual.into_iter().map(|t| t.to_string()).collect();
461+
manual.sort();
462+
for ty in manual {
450463
err.note(format!(
451464
"`{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"
452465
));
453466
}
454-
#[allow(rustc::potential_query_instability)] // Span labels will be sorted by the rendering
455-
for ty in v.without {
467+
#[allow(rustc::potential_query_instability)]
468+
let mut without: Vec<_> = v.without.into_iter().map(|t| t.to_string()).collect();
469+
without.sort();
470+
for ty in without {
456471
err.note(format!(
457472
"`{ty}` must be annotated with `#[derive(PartialEq)]` to be usable in patterns"
458473
));
459474
}
460475
}
461476

477+
#[derive(Debug)]
478+
struct PartialEqImplStatus {
479+
has_impl: bool,
480+
is_derived: bool,
481+
structural_partial_eq: bool,
482+
non_blanket_impl: Option<DefId>,
483+
}
484+
462485
#[instrument(level = "trace", skip(tcx), ret)]
463486
fn type_has_partial_eq_impl<'tcx>(
464487
tcx: TyCtxt<'tcx>,
465488
typing_env: ty::TypingEnv<'tcx>,
466489
ty: Ty<'tcx>,
467-
) -> (
468-
/* has impl */ bool,
469-
/* is derived */ bool,
470-
/* structural partial eq */ bool,
471-
/* non-blanket impl */ Option<DefId>,
472-
) {
490+
) -> PartialEqImplStatus {
473491
let (infcx, param_env) = tcx.infer_ctxt().build_with_typing_env(typing_env);
474492
// double-check there even *is* a semantic `PartialEq` to dispatch to.
475493
//
@@ -479,10 +497,6 @@ fn type_has_partial_eq_impl<'tcx>(
479497
let partial_eq_trait_id = tcx.require_lang_item(hir::LangItem::PartialEq, None);
480498
let structural_partial_eq_trait_id = tcx.require_lang_item(hir::LangItem::StructuralPeq, None);
481499

482-
if ty.has_escaping_bound_vars() {
483-
return (false, false, false, None);
484-
}
485-
486500
let partial_eq_obligation = Obligation::new(
487501
tcx,
488502
ObligationCause::dummy(),
@@ -510,10 +524,10 @@ fn type_has_partial_eq_impl<'tcx>(
510524
// that patterns can only do things that the code could also do without patterns, but it is
511525
// needed for backwards compatibility. The actual pattern matching compares primitive values,
512526
// `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-
)
527+
PartialEqImplStatus {
528+
has_impl: infcx.predicate_must_hold_modulo_regions(&partial_eq_obligation),
529+
is_derived: automatically_derived,
530+
structural_partial_eq: structural_peq,
531+
non_blanket_impl: impl_def_id,
532+
}
519533
}

0 commit comments

Comments
 (0)