@@ -15,10 +15,10 @@ use rustc::hir::def_id::DefId;
15
15
use rustc:: infer:: InferCtxt ;
16
16
use rustc:: mir:: Mir ;
17
17
use rustc:: ty:: subst:: { Substs , UnpackedKind } ;
18
- use rustc:: ty:: { self , RegionVid , Ty , TyCtxt } ;
18
+ use rustc:: ty:: { self , RegionKind , RegionVid , Ty , TyCtxt } ;
19
19
use rustc:: util:: ppaux:: with_highlight_region;
20
20
use rustc_errors:: DiagnosticBuilder ;
21
- use syntax:: ast:: Name ;
21
+ use syntax:: ast:: { Name , DUMMY_NODE_ID } ;
22
22
use syntax:: symbol:: keywords;
23
23
use syntax_pos:: symbol:: InternedString ;
24
24
@@ -90,14 +90,21 @@ impl<'tcx> RegionInferenceContext<'tcx> {
90
90
diag : & mut DiagnosticBuilder < ' _ > ,
91
91
) -> Option < InternedString > {
92
92
let error_region = self . to_error_region ( fr) ?;
93
+
93
94
debug ! ( "give_region_a_name: error_region = {:?}" , error_region) ;
94
95
match error_region {
95
- ty:: ReEarlyBound ( ebr) => Some ( ebr. name ) ,
96
+ ty:: ReEarlyBound ( ebr) => {
97
+ self . highlight_named_span ( tcx, error_region, & ebr. name , diag) ;
98
+ Some ( ebr. name )
99
+ } ,
96
100
97
101
ty:: ReStatic => Some ( keywords:: StaticLifetime . name ( ) . as_interned_str ( ) ) ,
98
102
99
103
ty:: ReFree ( free_region) => match free_region. bound_region {
100
- ty:: BoundRegion :: BrNamed ( _, name) => Some ( name) ,
104
+ ty:: BoundRegion :: BrNamed ( _, name) => {
105
+ self . highlight_named_span ( tcx, error_region, & name, diag) ;
106
+ Some ( name)
107
+ } ,
101
108
102
109
ty:: BoundRegion :: BrEnv => {
103
110
let closure_span = tcx. hir . span_if_local ( mir_def_id) . unwrap ( ) ;
@@ -123,6 +130,45 @@ impl<'tcx> RegionInferenceContext<'tcx> {
123
130
}
124
131
}
125
132
133
+ /// Highlight a named span to provide context for error messages that
134
+ /// mention that span, for example:
135
+ ///
136
+ /// ```
137
+ /// |
138
+ /// | fn two_regions<'a, 'b, T>(cell: Cell<&'a ()>, t: T)
139
+ /// | -- -- lifetime `'b` defined here
140
+ /// | |
141
+ /// | lifetime `'a` defined here
142
+ /// |
143
+ /// | with_signature(cell, t, |cell, t| require(cell, t));
144
+ /// | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'b` must
145
+ /// | outlive `'a`
146
+ /// ```
147
+ fn highlight_named_span (
148
+ & self ,
149
+ tcx : TyCtxt < ' _ , ' _ , ' tcx > ,
150
+ error_region : & RegionKind ,
151
+ name : & InternedString ,
152
+ diag : & mut DiagnosticBuilder < ' _ > ,
153
+ ) {
154
+ let cm = tcx. sess . codemap ( ) ;
155
+
156
+ let scope = error_region. free_region_binding_scope ( tcx) ;
157
+ let node = tcx. hir . as_local_node_id ( scope) . unwrap_or ( DUMMY_NODE_ID ) ;
158
+
159
+ let mut sp = cm. def_span ( tcx. hir . span ( node) ) ;
160
+ if let Some ( param) = tcx. hir . get_generics ( scope) . and_then ( |generics| {
161
+ generics. get_named ( name)
162
+ } ) {
163
+ sp = param. span ;
164
+ }
165
+
166
+ diag. span_label (
167
+ sp,
168
+ format ! ( "lifetime `{}` defined here" , name) ,
169
+ ) ;
170
+ }
171
+
126
172
/// Find an argument that contains `fr` and label it with a fully
127
173
/// elaborated type, returning something like `'1`. Result looks
128
174
/// like:
0 commit comments