@@ -157,7 +157,42 @@ impl<'tcx> RegionInferenceContext<'tcx> {
157157 let target_scc = self . constraint_sccs . scc ( target_region) ;
158158 let mut range = 0 ..path. len ( ) ;
159159
160- let should_reverse = match from_region_origin {
160+ // As noted above, when reporting an error, there is typically a chain of constraints
161+ // leading from some "source" region which must outlive some "target" region.
162+ // In most cases, we prefer to "blame" the constraints closer to the target --
163+ // but there is one exception. When constraints arise from higher-ranked subtyping,
164+ // we generally prefer to blame the source value,
165+ // as the "target" in this case tends to be some type annotation that the user gave.
166+ // Therefore, if we find that the region origin is some instantiation
167+ // of a higher-ranked region, we start our search from the "source" point
168+ // rather than the "target", and we also tweak a few other things.
169+ //
170+ // An example might be this bit of Rust code:
171+ //
172+ // ```rust
173+ // let x: fn(&'static ()) = |_| {};
174+ // let y: for<'a> fn(&'a ()) = x;
175+ // ```
176+ //
177+ // In MIR, this will be converted into a combination of assignments and type ascriptions.
178+ // In particular, the 'static is imposed through a type ascription:
179+ //
180+ // ```rust
181+ // x = ...;
182+ // AscribeUserType(x, fn(&'static ())
183+ // y = x;
184+ // ```
185+ //
186+ // We wind up ultimately with constraints like
187+ //
188+ // ```rust
189+ // !a: 'temp1 // from the `y = x` statement
190+ // 'temp1: 'temp2
191+ // 'temp2: 'static // from the AscribeUserType
192+ // ```
193+ //
194+ // and here we prefer to blame the source (the y = x statement).
195+ let blame_source = match from_region_origin {
161196 NLLRegionVariableOrigin :: FreeRegion
162197 | NLLRegionVariableOrigin :: Existential { from_forall : false } => {
163198 true
@@ -173,7 +208,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
173208
174209 let constraint_sup_scc = self . constraint_sccs . scc ( constraint. sup ) ;
175210
176- if should_reverse {
211+ if blame_source {
177212 match categorized_path[ * i] . 0 {
178213 ConstraintCategory :: OpaqueType | ConstraintCategory :: Boring |
179214 ConstraintCategory :: BoringNoLocation | ConstraintCategory :: Internal => false ,
@@ -190,14 +225,14 @@ impl<'tcx> RegionInferenceContext<'tcx> {
190225 }
191226 } ;
192227
193- let best_choice = if should_reverse {
228+ let best_choice = if blame_source {
194229 range. rev ( ) . find ( find_region)
195230 } else {
196231 range. find ( find_region)
197232 } ;
198233
199- debug ! ( "best_blame_constraint: best_choice={:?} should_reverse ={}" ,
200- best_choice, should_reverse ) ;
234+ debug ! ( "best_blame_constraint: best_choice={:?} blame_source ={}" ,
235+ best_choice, blame_source ) ;
201236
202237 if let Some ( i) = best_choice {
203238 if let Some ( next) = categorized_path. get ( i + 1 ) {
0 commit comments