@@ -872,35 +872,50 @@ impl<'tcx> RegionInferenceContext<'tcx> {
872
872
// be obvious to the user -- not to mention the naive notion
873
873
// of dependencies, which doesn't account for the locations of
874
874
// contraints at all. But it will do for now.
875
- for constraint in & self . constraints {
876
- if constraint. sub == fr2 && influenced_fr1[ constraint. sup ] {
877
- return constraint. span ;
878
- }
879
- }
880
-
881
- bug ! (
882
- "could not find any constraint to blame for {:?}: {:?}" ,
883
- fr1,
884
- fr2
885
- ) ;
875
+ let relevant_constraint = self . constraints
876
+ . iter ( )
877
+ . filter_map ( |constraint| {
878
+ if constraint. sub != fr2 {
879
+ None
880
+ } else {
881
+ influenced_fr1[ constraint. sup ]
882
+ . map ( |distance| ( distance, constraint. span ) )
883
+ }
884
+ } )
885
+ . min ( ) // constraining fr1 with fewer hops *ought* to be more obvious
886
+ . map ( |( _dist, span) | span) ;
887
+
888
+ relevant_constraint. unwrap_or_else ( || {
889
+ bug ! (
890
+ "could not find any constraint to blame for {:?}: {:?}" ,
891
+ fr1,
892
+ fr2
893
+ ) ;
894
+ } )
886
895
}
887
896
888
897
/// Finds all regions whose values `'a` may depend on in some way.
889
- /// Basically if there exists a constraint `'a: 'b @ P`, then `'b`
890
- /// and `dependencies('b)` will be in the final set.
898
+ /// For each region, returns either `None` (does not influence
899
+ /// `'a`) or `Some(d)` which indicates that it influences `'a`
900
+ /// with distinct `d` (minimum number of edges that must be
901
+ /// traversed).
891
902
///
892
903
/// Used during error reporting, extremely naive and inefficient.
893
- fn dependencies ( & self , r0 : RegionVid ) -> IndexVec < RegionVid , bool > {
894
- let mut result_set = IndexVec :: from_elem ( false , & self . definitions ) ;
904
+ fn dependencies ( & self , r0 : RegionVid ) -> IndexVec < RegionVid , Option < usize > > {
905
+ let mut result_set = IndexVec :: from_elem ( None , & self . definitions ) ;
895
906
let mut changed = true ;
896
- result_set[ r0] = true ;
907
+ result_set[ r0] = Some ( 0 ) ; // distance 0 from `r0`
897
908
898
909
while changed {
899
910
changed = false ;
900
911
for constraint in & self . constraints {
901
- if result_set[ constraint. sup ] {
902
- if !result_set[ constraint. sub ] {
903
- result_set[ constraint. sub ] = true ;
912
+ if let Some ( n) = result_set[ constraint. sup ] {
913
+ let m = n + 1 ;
914
+ if result_set[ constraint. sub ]
915
+ . map ( |distance| m < distance)
916
+ . unwrap_or ( true )
917
+ {
918
+ result_set[ constraint. sub ] = Some ( m) ;
904
919
changed = true ;
905
920
}
906
921
}
@@ -1049,13 +1064,16 @@ impl<'gcx, 'tcx> ClosureRegionRequirementsExt<'gcx, 'tcx> for ClosureRegionRequi
1049
1064
value : & T ,
1050
1065
) -> T
1051
1066
where
1052
- T : TypeFoldable < ' tcx >
1067
+ T : TypeFoldable < ' tcx > ,
1053
1068
{
1054
1069
infcx. tcx . fold_regions ( value, & mut false , |r, _depth| {
1055
1070
if let ty:: ReClosureBound ( vid) = r {
1056
1071
closure_mapping[ * vid]
1057
1072
} else {
1058
- bug ! ( "subst_closure_mapping: encountered non-closure bound free region {:?}" , r)
1073
+ bug ! (
1074
+ "subst_closure_mapping: encountered non-closure bound free region {:?}" ,
1075
+ r
1076
+ )
1059
1077
}
1060
1078
} )
1061
1079
}
0 commit comments