88// option. This file may not be copied, modified, or distributed
99// except according to those terms.
1010
11- use borrow_check:: nll:: constraints:: { OutlivesConstraint , ConstraintCategory } ;
11+ use borrow_check:: nll:: constraints:: { OutlivesConstraint } ;
1212use borrow_check:: nll:: region_infer:: RegionInferenceContext ;
13+ use borrow_check:: nll:: type_check:: Locations ;
1314use rustc:: hir:: def_id:: DefId ;
1415use rustc:: infer:: error_reporting:: nice_region_error:: NiceRegionError ;
1516use rustc:: infer:: InferCtxt ;
16- use rustc:: mir:: { Location , Mir } ;
17+ use rustc:: mir:: { ConstraintCategory , Location , Mir } ;
1718use rustc:: ty:: { self , RegionVid } ;
1819use rustc_data_structures:: indexed_vec:: IndexVec ;
1920use rustc_errors:: { Diagnostic , DiagnosticBuilder } ;
2021use std:: collections:: VecDeque ;
21- use std:: fmt;
2222use syntax:: symbol:: keywords;
2323use syntax_pos:: Span ;
2424use syntax:: errors:: Applicability ;
@@ -28,22 +28,26 @@ mod var_name;
2828
2929use self :: region_name:: RegionName ;
3030
31- impl fmt:: Display for ConstraintCategory {
32- fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
31+ trait ConstraintDescription {
32+ fn description ( & self ) -> & ' static str ;
33+ }
34+
35+ impl ConstraintDescription for ConstraintCategory {
36+ fn description ( & self ) -> & ' static str {
3337 // Must end with a space. Allows for empty names to be provided.
3438 match self {
35- ConstraintCategory :: Assignment => write ! ( f , "assignment " ) ,
36- ConstraintCategory :: Return => write ! ( f , "returning this value " ) ,
37- ConstraintCategory :: Cast => write ! ( f , "cast " ) ,
38- ConstraintCategory :: CallArgument => write ! ( f , "argument " ) ,
39- ConstraintCategory :: TypeAnnotation => write ! ( f , "type annotation " ) ,
40- ConstraintCategory :: ClosureBounds => write ! ( f , "closure body " ) ,
41- ConstraintCategory :: SizedBound => write ! ( f , "proving this value is `Sized` " ) ,
42- ConstraintCategory :: CopyBound => write ! ( f , "copying this value " ) ,
43- ConstraintCategory :: OpaqueType => write ! ( f , "opaque type " ) ,
39+ ConstraintCategory :: Assignment => "assignment " ,
40+ ConstraintCategory :: Return => "returning this value " ,
41+ ConstraintCategory :: Cast => "cast " ,
42+ ConstraintCategory :: CallArgument => "argument " ,
43+ ConstraintCategory :: TypeAnnotation => "type annotation " ,
44+ ConstraintCategory :: ClosureBounds => "closure body " ,
45+ ConstraintCategory :: SizedBound => "proving this value is `Sized` " ,
46+ ConstraintCategory :: CopyBound => "copying this value " ,
47+ ConstraintCategory :: OpaqueType => "opaque type " ,
4448 ConstraintCategory :: Boring
4549 | ConstraintCategory :: BoringNoLocation
46- | ConstraintCategory :: Internal => write ! ( f , "" ) ,
50+ | ConstraintCategory :: Internal => "" ,
4751 }
4852 }
4953}
@@ -89,7 +93,13 @@ impl<'tcx> RegionInferenceContext<'tcx> {
8993 // Classify each of the constraints along the path.
9094 let mut categorized_path: Vec < ( ConstraintCategory , Span ) > = path
9195 . iter ( )
92- . map ( |constraint| ( constraint. category , constraint. locations . span ( mir) ) )
96+ . map ( |constraint| {
97+ if constraint. category == ConstraintCategory :: ClosureBounds {
98+ self . retrieve_closure_constraint_info ( mir, & constraint)
99+ } else {
100+ ( constraint. category , constraint. locations . span ( mir) )
101+ }
102+ } )
93103 . collect ( ) ;
94104 debug ! (
95105 "best_blame_constraint: categorized_path={:#?}" ,
@@ -358,7 +368,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
358368 _ => {
359369 diag. span_label ( span, format ! (
360370 "{}requires that `{}` must outlive `{}`" ,
361- category, fr_name, outlived_fr_name,
371+ category. description ( ) , fr_name, outlived_fr_name,
362372 ) ) ;
363373 } ,
364374 }
@@ -470,8 +480,24 @@ impl<'tcx> RegionInferenceContext<'tcx> {
470480 mir : & Mir < ' tcx > ,
471481 fr1 : RegionVid ,
472482 fr2 : RegionVid ,
473- ) -> Span {
474- let ( _, span, _) = self . best_blame_constraint ( mir, fr1, |r| r == fr2) ;
475- span
483+ ) -> ( ConstraintCategory , Span ) {
484+ let ( category, span, _) = self . best_blame_constraint ( mir, fr1, |r| r == fr2) ;
485+ ( category, span)
486+ }
487+
488+ fn retrieve_closure_constraint_info (
489+ & self ,
490+ mir : & Mir < ' tcx > ,
491+ constraint : & OutlivesConstraint
492+ ) -> ( ConstraintCategory , Span ) {
493+ let loc = match constraint. locations {
494+ Locations :: All ( span) => return ( constraint. category , span) ,
495+ Locations :: Single ( loc) => loc,
496+ } ;
497+
498+ let opt_span_category = self
499+ . closure_bounds_mapping [ & loc]
500+ . get ( & ( constraint. sup , constraint. sub ) ) ;
501+ * opt_span_category. unwrap_or ( & ( constraint. category , mir. source_info ( loc) . span ) )
476502 }
477503}
0 commit comments