@@ -564,6 +564,11 @@ fn find_opaque_ty_constraints_for_tait(tcx: TyCtxt<'_>, def_id: LocalDefId) -> T
564
564
/// checked against it (we also carry the span of that first
565
565
/// type).
566
566
found : Option < ty:: OpaqueHiddenType < ' tcx > > ,
567
+
568
+ /// In the presence of dead code, typeck may figure out a hidden type
569
+ /// while borrowck will now. We collect these cases here and check at
570
+ /// the end that we actually found a type that matches (modulo regions).
571
+ typeck_types : Vec < ty:: OpaqueHiddenType < ' tcx > > ,
567
572
}
568
573
569
574
impl ConstraintLocator < ' _ > {
@@ -590,18 +595,23 @@ fn find_opaque_ty_constraints_for_tait(tcx: TyCtxt<'_>, def_id: LocalDefId) -> T
590
595
self . found = Some ( ty:: OpaqueHiddenType { span : DUMMY_SP , ty : self . tcx . ty_error ( ) } ) ;
591
596
return ;
592
597
}
593
- if ! tables. concrete_opaque_types . contains_key ( & self . def_id ) {
598
+ let Some ( & typeck_hidden_ty ) = tables. concrete_opaque_types . get ( & self . def_id ) else {
594
599
debug ! ( "no constraints in typeck results" ) ;
595
600
return ;
601
+ } ;
602
+ if self . typeck_types . iter ( ) . all ( |prev| prev. ty != typeck_hidden_ty. ty ) {
603
+ self . typeck_types . push ( typeck_hidden_ty) ;
596
604
}
605
+
597
606
// Use borrowck to get the type with unerased regions.
598
607
let concrete_opaque_types = & self . tcx . mir_borrowck ( item_def_id) . concrete_opaque_types ;
599
608
debug ! ( ?concrete_opaque_types) ;
600
609
if let Some ( & concrete_type) = concrete_opaque_types. get ( & self . def_id ) {
601
610
debug ! ( ?concrete_type, "found constraint" ) ;
602
- if let Some ( prev) = self . found {
603
- if concrete_type. ty != prev. ty && !( concrete_type, prev) . references_error ( ) {
611
+ if let Some ( prev) = & mut self . found {
612
+ if concrete_type. ty != prev. ty && !( concrete_type, prev. ty ) . references_error ( ) {
604
613
prev. report_mismatch ( & concrete_type, self . tcx ) ;
614
+ prev. ty = self . tcx . ty_error ( ) ;
605
615
}
606
616
} else {
607
617
self . found = Some ( concrete_type) ;
@@ -648,7 +658,7 @@ fn find_opaque_ty_constraints_for_tait(tcx: TyCtxt<'_>, def_id: LocalDefId) -> T
648
658
649
659
let hir_id = tcx. hir ( ) . local_def_id_to_hir_id ( def_id) ;
650
660
let scope = tcx. hir ( ) . get_defining_scope ( hir_id) ;
651
- let mut locator = ConstraintLocator { def_id : def_id, tcx, found : None } ;
661
+ let mut locator = ConstraintLocator { def_id : def_id, tcx, found : None , typeck_types : vec ! [ ] } ;
652
662
653
663
debug ! ( ?scope) ;
654
664
@@ -678,16 +688,26 @@ fn find_opaque_ty_constraints_for_tait(tcx: TyCtxt<'_>, def_id: LocalDefId) -> T
678
688
}
679
689
}
680
690
681
- match locator. found {
682
- Some ( hidden) => hidden. ty ,
683
- None => {
684
- tcx. sess . emit_err ( UnconstrainedOpaqueType {
685
- span : tcx. def_span ( def_id) ,
686
- name : tcx. item_name ( tcx. local_parent ( def_id) . to_def_id ( ) ) ,
687
- } ) ;
688
- tcx. ty_error ( )
691
+ let Some ( hidden) = locator. found else {
692
+ tcx. sess . emit_err ( UnconstrainedOpaqueType {
693
+ span : tcx. def_span ( def_id) ,
694
+ name : tcx. item_name ( tcx. local_parent ( def_id) . to_def_id ( ) ) ,
695
+ } ) ;
696
+ return tcx. ty_error ( ) ;
697
+ } ;
698
+
699
+ // Only check against typeck if we didn't already error
700
+ if !hidden. ty . references_error ( ) {
701
+ for concrete_type in locator. typeck_types {
702
+ if tcx. erase_regions ( concrete_type. ty ) != tcx. erase_regions ( hidden. ty )
703
+ && !( concrete_type, hidden) . references_error ( )
704
+ {
705
+ hidden. report_mismatch ( & concrete_type, tcx) ;
706
+ }
689
707
}
690
708
}
709
+
710
+ hidden. ty
691
711
}
692
712
693
713
fn find_opaque_ty_constraints_for_rpit (
@@ -788,7 +808,7 @@ fn find_opaque_ty_constraints_for_rpit(
788
808
// the `concrete_opaque_types` table.
789
809
tcx. ty_error ( )
790
810
} else {
791
- table. concrete_opaque_types . get ( & def_id) . copied ( ) . unwrap_or_else ( || {
811
+ table. concrete_opaque_types . get ( & def_id) . map ( |ty| ty . ty ) . unwrap_or_else ( || {
792
812
// We failed to resolve the opaque type or it
793
813
// resolves to itself. We interpret this as the
794
814
// no values of the hidden type ever being constructed,
0 commit comments