@@ -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+
775756fn assert_field_type_is_copy < ' tcx > (
776757 tcx : TyCtxt < ' tcx > ,
777758 infcx : & InferCtxt < ' tcx > ,
0 commit comments