1313
1414use super :: { CombinedSnapshot ,
1515 InferCtxt ,
16+ LateBoundRegion ,
1617 HigherRankedType ,
18+ RegionVariableOrigin ,
1719 SubregionOrigin ,
1820 SkolemizationMap } ;
1921use super :: combine:: CombineFields ;
@@ -27,6 +29,15 @@ use util::nodemap::{FxHashMap, FxHashSet};
2729
2830pub struct HrMatchResult < U > {
2931 pub value : U ,
32+
33+ /// Normally, when we do a higher-ranked match operation, we
34+ /// expect all higher-ranked regions to be constrained as part of
35+ /// the match operation. However, in the transition period for
36+ /// #32330, it can happen that we sometimes have unconstrained
37+ /// regions that get instantiated with fresh variables. In that
38+ /// case, we collect the set of unconstrained bound regions here
39+ /// and replace them with fresh variables.
40+ pub unconstrained_regions : Vec < ty:: BoundRegion > ,
3041}
3142
3243impl < ' a , ' gcx , ' tcx > CombineFields < ' a , ' gcx , ' tcx > {
@@ -97,6 +108,7 @@ impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> {
97108 /// that do not appear in `T`. If that happens, those regions are
98109 /// unconstrained, and this routine replaces them with `'static`.
99110 pub fn higher_ranked_match < T , U > ( & mut self ,
111+ span : Span ,
100112 a_pair : & Binder < ( T , U ) > ,
101113 b_match : & T ,
102114 a_is_expected : bool )
@@ -146,16 +158,28 @@ impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> {
146158 // be any region from the sets above, except for other members of
147159 // `skol_map`. There should always be a representative if things
148160 // are properly well-formed.
161+ let mut unconstrained_regions = vec ! [ ] ;
149162 let skol_representatives: FxHashMap < _ , _ > =
150163 skol_resolution_map
151164 . iter ( )
152- . map ( |( & skol, & ( _ , ref regions) ) | {
165+ . map ( |( & skol, & ( br , ref regions) ) | {
153166 let representative =
154167 regions. iter ( )
155168 . filter ( |& & r| !skol_resolution_map. contains_key ( r) )
156169 . cloned ( )
157170 . next ( )
158- . expect ( "no representative region" ) ;
171+ . unwrap_or_else ( || { // [1]
172+ unconstrained_regions. push ( br) ;
173+ self . infcx . next_region_var (
174+ LateBoundRegion ( span, br, HigherRankedType ) )
175+ } ) ;
176+
177+ // [1] There should always be a representative,
178+ // unless the higher-ranked region did not appear
179+ // in the values being matched. We should reject
180+ // as ill-formed cases that can lead to this, but
181+ // right now we sometimes issue warnings (see
182+ // #32330).
159183
160184 ( skol, representative)
161185 } )
@@ -192,7 +216,10 @@ impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> {
192216 // We are now done with these skolemized variables.
193217 self . infcx . pop_skolemized ( skol_map, snapshot) ;
194218
195- Ok ( HrMatchResult { value : a_value } )
219+ Ok ( HrMatchResult {
220+ value : a_value,
221+ unconstrained_regions,
222+ } )
196223 } ) ;
197224 }
198225
@@ -630,13 +657,28 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
630657 skol_br,
631658 tainted_region) ;
632659
633- return Err ( if overly_polymorphic {
660+ let issue_32330 = if let & ty:: ReVar ( vid) = tainted_region {
661+ match self . region_vars . var_origin ( vid) {
662+ RegionVariableOrigin :: EarlyBoundRegion ( _, _, issue_32330) => {
663+ issue_32330. map ( Box :: new)
664+ }
665+ _ => None
666+ }
667+ } else {
668+ None
669+ } ;
670+
671+ if overly_polymorphic {
634672 debug ! ( "Overly polymorphic!" ) ;
635- TypeError :: RegionsOverlyPolymorphic ( skol_br, tainted_region)
673+ return Err ( TypeError :: RegionsOverlyPolymorphic ( skol_br,
674+ tainted_region,
675+ issue_32330) ) ;
636676 } else {
637677 debug ! ( "Not as polymorphic!" ) ;
638- TypeError :: RegionsInsufficientlyPolymorphic ( skol_br, tainted_region)
639- } )
678+ return Err ( TypeError :: RegionsInsufficientlyPolymorphic ( skol_br,
679+ tainted_region,
680+ issue_32330) ) ;
681+ }
640682 }
641683 }
642684
0 commit comments