Skip to content

Commit aa831d0

Browse files
committed
Remove some duplication
1 parent 7d50fac commit aa831d0

1 file changed

Lines changed: 41 additions & 60 deletions

File tree

  • compiler/rustc_hir_analysis/src/coherence

compiler/rustc_hir_analysis/src/coherence/builtin.rs

Lines changed: 41 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -503,14 +503,8 @@ pub(crate) fn reborrow_info<'tcx>(
503503

504504
let source = tcx.type_of(impl_did).instantiate_identity();
505505
let trait_ref = tcx.impl_trait_ref(impl_did).instantiate_identity();
506-
let lifetime_params_count = tcx
507-
.generics_of(impl_did)
508-
.own_params
509-
.iter()
510-
.filter(|p| matches!(p.kind, ty::GenericParamDefKind::Lifetime))
511-
.count();
512506

513-
if lifetime_params_count != 1 {
507+
if trait_impl_lifetime_params_count(tcx, impl_did) != 1 {
514508
return Err(tcx
515509
.dcx()
516510
.emit_err(errors::CoerceSharedNotSingleLifetimeParam { span, trait_name }));
@@ -528,20 +522,8 @@ pub(crate) fn reborrow_info<'tcx>(
528522
}
529523
};
530524

531-
let lifetimes_count = args.iter().filter(|arg| arg.as_region().is_some()).count();
532-
let data_fields = def
533-
.non_enum_variant()
534-
.fields
535-
.iter()
536-
.filter_map(|f| {
537-
// Ignore PhantomData fields
538-
let ty = f.ty(tcx, args);
539-
if ty.is_phantom_data() {
540-
return None;
541-
}
542-
Some((ty, tcx.def_span(f.did)))
543-
})
544-
.collect::<Vec<_>>();
525+
let lifetimes_count = generic_lifetime_params_count(args);
526+
let data_fields = collect_struct_data_fields(tcx, def, args);
545527

546528
if lifetimes_count != 1 {
547529
let item = tcx.hir_expect_item(impl_did);
@@ -618,14 +600,8 @@ pub(crate) fn coerce_shared_info<'tcx>(
618600

619601
let source = tcx.type_of(impl_did).instantiate_identity();
620602
let trait_ref = tcx.impl_trait_ref(impl_did).instantiate_identity();
621-
let lifetime_params_count = tcx
622-
.generics_of(impl_did)
623-
.own_params
624-
.iter()
625-
.filter(|p| matches!(p.kind, ty::GenericParamDefKind::Lifetime))
626-
.count();
627603

628-
if lifetime_params_count != 1 {
604+
if trait_impl_lifetime_params_count(tcx, impl_did) != 1 {
629605
return Err(tcx
630606
.dcx()
631607
.emit_err(errors::CoerceSharedNotSingleLifetimeParam { span, trait_name }));
@@ -650,36 +626,10 @@ pub(crate) fn coerce_shared_info<'tcx>(
650626
// support multiple lifetime arguments (with the reborrowed lifetimes inferred from
651627
// usage one way or another) and multiple data fields with B allowed to leave out fields
652628
// from A. The current state is just the simplest choice.
653-
let a_lifetimes_count = args_a.iter().filter(|arg| arg.as_region().is_some()).count();
654-
let a_data_fields = def_a
655-
.non_enum_variant()
656-
.fields
657-
.iter_enumerated()
658-
.filter_map(|(i, f)| {
659-
let a = f.ty(tcx, args_b);
660-
661-
if a.is_phantom_data() {
662-
return None;
663-
}
664-
665-
Some((i, a, tcx.def_span(f.did)))
666-
})
667-
.collect::<Vec<_>>();
668-
let b_lifetimes_count = args_b.iter().filter(|arg| arg.as_region().is_some()).count();
669-
let b_data_fields = def_b
670-
.non_enum_variant()
671-
.fields
672-
.iter_enumerated()
673-
.filter_map(|(i, f)| {
674-
let b = f.ty(tcx, args_b);
675-
676-
if b.is_phantom_data() {
677-
return None;
678-
}
679-
680-
Some((i, b, tcx.def_span(f.did)))
681-
})
682-
.collect::<Vec<_>>();
629+
let a_lifetimes_count = generic_lifetime_params_count(args_a);
630+
let a_data_fields = collect_struct_data_fields(tcx, def_a, args_a);
631+
let b_lifetimes_count = generic_lifetime_params_count(args_b);
632+
let b_data_fields = collect_struct_data_fields(tcx, def_b, args_b);
683633

684634
if a_lifetimes_count != 1
685635
|| b_lifetimes_count != 1
@@ -702,8 +652,8 @@ pub(crate) fn coerce_shared_info<'tcx>(
702652
if a_data_fields.len() == 1 {
703653
// We found one data field for both: we'll attempt to perform CoerceShared between
704654
// them below.
705-
let (_a_i, a, span_a) = a_data_fields[0];
706-
let (_b_i, b, span_b) = b_data_fields[0];
655+
let (a, span_a) = a_data_fields[0];
656+
let (b, span_b) = b_data_fields[0];
707657

708658
Some((a, b, coerce_shared_trait, span_a, span_b))
709659
} else {
@@ -772,6 +722,37 @@ pub(crate) fn coerce_shared_info<'tcx>(
772722
Ok(())
773723
}
774724

725+
fn trait_impl_lifetime_params_count(tcx: TyCtxt<'_>, did: LocalDefId) -> usize {
726+
tcx.generics_of(did)
727+
.own_params
728+
.iter()
729+
.filter(|p| matches!(p.kind, ty::GenericParamDefKind::Lifetime))
730+
.count()
731+
}
732+
733+
fn generic_lifetime_params_count(args: &[ty::GenericArg<'_>]) -> usize {
734+
args.iter().filter(|arg| arg.as_region().is_some()).count()
735+
}
736+
737+
fn collect_struct_data_fields<'tcx>(
738+
tcx: TyCtxt<'tcx>,
739+
def: ty::AdtDef<'tcx>,
740+
args: ty::GenericArgsRef<'tcx>,
741+
) -> Vec<(Ty<'tcx>, Span)> {
742+
def.non_enum_variant()
743+
.fields
744+
.iter()
745+
.filter_map(|f| {
746+
// Ignore PhantomData fields
747+
let ty = f.ty(tcx, args);
748+
if ty.is_phantom_data() {
749+
return None;
750+
}
751+
Some((ty, tcx.def_span(f.did)))
752+
})
753+
.collect()
754+
}
755+
775756
fn assert_field_type_is_copy<'tcx>(
776757
tcx: TyCtxt<'tcx>,
777758
infcx: &InferCtxt<'tcx>,

0 commit comments

Comments
 (0)