@@ -116,7 +116,7 @@ pub(super) fn note_and_explain_region(
116
116
emit_msg_span ( err, prefix, description, span, suffix) ;
117
117
}
118
118
119
- pub ( super ) fn note_and_explain_free_region (
119
+ fn explain_free_region (
120
120
tcx : TyCtxt < ' tcx > ,
121
121
err : & mut DiagnosticBuilder < ' _ > ,
122
122
prefix : & str ,
@@ -125,7 +125,7 @@ pub(super) fn note_and_explain_free_region(
125
125
) {
126
126
let ( description, span) = msg_span_from_free_region ( tcx, region, None ) ;
127
127
128
- emit_msg_span ( err, prefix, description, span, suffix) ;
128
+ label_msg_span ( err, prefix, description, span, suffix) ;
129
129
}
130
130
131
131
fn msg_span_from_free_region (
@@ -135,7 +135,8 @@ fn msg_span_from_free_region(
135
135
) -> ( String , Option < Span > ) {
136
136
match * region {
137
137
ty:: ReEarlyBound ( _) | ty:: ReFree ( _) => {
138
- msg_span_from_early_bound_and_free_regions ( tcx, region)
138
+ let ( msg, span) = msg_span_from_early_bound_and_free_regions ( tcx, region) ;
139
+ ( msg, Some ( span) )
139
140
}
140
141
ty:: ReStatic => ( "the static lifetime" . to_owned ( ) , alt_span) ,
141
142
ty:: ReEmpty ( ty:: UniverseIndex :: ROOT ) => ( "an empty lifetime" . to_owned ( ) , alt_span) ,
@@ -147,28 +148,20 @@ fn msg_span_from_free_region(
147
148
fn msg_span_from_early_bound_and_free_regions (
148
149
tcx : TyCtxt < ' tcx > ,
149
150
region : ty:: Region < ' tcx > ,
150
- ) -> ( String , Option < Span > ) {
151
+ ) -> ( String , Span ) {
151
152
let sm = tcx. sess . source_map ( ) ;
152
153
153
154
let scope = region. free_region_binding_scope ( tcx) ;
154
155
let node = tcx. hir ( ) . local_def_id_to_hir_id ( scope. expect_local ( ) ) ;
155
- let tag = match tcx. hir ( ) . find ( node) {
156
- Some ( Node :: Block ( _) | Node :: Expr ( _) ) => "body" ,
157
- Some ( Node :: Item ( it) ) => item_scope_tag ( & it) ,
158
- Some ( Node :: TraitItem ( it) ) => trait_item_scope_tag ( & it) ,
159
- Some ( Node :: ImplItem ( it) ) => impl_item_scope_tag ( & it) ,
160
- Some ( Node :: ForeignItem ( it) ) => foreign_item_scope_tag ( & it) ,
161
- _ => unreachable ! ( ) ,
162
- } ;
163
- let ( prefix, span) = match * region {
156
+ match * region {
164
157
ty:: ReEarlyBound ( ref br) => {
165
158
let mut sp = sm. guess_head_span ( tcx. hir ( ) . span ( node) ) ;
166
159
if let Some ( param) =
167
160
tcx. hir ( ) . get_generics ( scope) . and_then ( |generics| generics. get_named ( br. name ) )
168
161
{
169
162
sp = param. span ;
170
163
}
171
- ( format ! ( "the lifetime `{}` as defined on " , br. name) , sp)
164
+ ( format ! ( "the lifetime `{}` as defined here " , br. name) , sp)
172
165
}
173
166
ty:: ReFree ( ty:: FreeRegion {
174
167
bound_region : ty:: BoundRegionKind :: BrNamed ( _, name) , ..
@@ -179,28 +172,26 @@ fn msg_span_from_early_bound_and_free_regions(
179
172
{
180
173
sp = param. span ;
181
174
}
182
- ( format ! ( "the lifetime `{}` as defined on " , name) , sp)
175
+ ( format ! ( "the lifetime `{}` as defined here " , name) , sp)
183
176
}
184
177
ty:: ReFree ( ref fr) => match fr. bound_region {
185
178
ty:: BrAnon ( idx) => {
186
179
if let Some ( ( ty, _) ) = find_anon_type ( tcx, region, & fr. bound_region ) {
187
- ( "the anonymous lifetime defined on " . to_string ( ) , ty. span )
180
+ ( "the anonymous lifetime defined here " . to_string ( ) , ty. span )
188
181
} else {
189
182
(
190
- format ! ( "the anonymous lifetime #{} defined on " , idx + 1 ) ,
183
+ format ! ( "the anonymous lifetime #{} defined here " , idx + 1 ) ,
191
184
tcx. hir ( ) . span ( node) ,
192
185
)
193
186
}
194
187
}
195
188
_ => (
196
- format ! ( "the lifetime `{}` as defined on " , region) ,
189
+ format ! ( "the lifetime `{}` as defined here " , region) ,
197
190
sm. guess_head_span ( tcx. hir ( ) . span ( node) ) ,
198
191
) ,
199
192
} ,
200
193
_ => bug ! ( ) ,
201
- } ;
202
- let ( msg, opt_span) = explain_span ( tcx, tag, span) ;
203
- ( format ! ( "{} {}" , prefix, msg) , opt_span)
194
+ }
204
195
}
205
196
206
197
fn emit_msg_span (
@@ -219,44 +210,22 @@ fn emit_msg_span(
219
210
}
220
211
}
221
212
222
- fn item_scope_tag ( item : & hir:: Item < ' _ > ) -> & ' static str {
223
- match item. kind {
224
- hir:: ItemKind :: Impl { .. } => "impl" ,
225
- hir:: ItemKind :: Struct ( ..) => "struct" ,
226
- hir:: ItemKind :: Union ( ..) => "union" ,
227
- hir:: ItemKind :: Enum ( ..) => "enum" ,
228
- hir:: ItemKind :: Trait ( ..) => "trait" ,
229
- hir:: ItemKind :: Fn ( ..) => "function body" ,
230
- _ => "item" ,
231
- }
232
- }
233
-
234
- fn trait_item_scope_tag ( item : & hir:: TraitItem < ' _ > ) -> & ' static str {
235
- match item. kind {
236
- hir:: TraitItemKind :: Fn ( ..) => "method body" ,
237
- hir:: TraitItemKind :: Const ( ..) | hir:: TraitItemKind :: Type ( ..) => "associated item" ,
238
- }
239
- }
240
-
241
- fn impl_item_scope_tag ( item : & hir:: ImplItem < ' _ > ) -> & ' static str {
242
- match item. kind {
243
- hir:: ImplItemKind :: Fn ( ..) => "method body" ,
244
- hir:: ImplItemKind :: Const ( ..) | hir:: ImplItemKind :: TyAlias ( ..) => "associated item" ,
245
- }
246
- }
213
+ fn label_msg_span (
214
+ err : & mut DiagnosticBuilder < ' _ > ,
215
+ prefix : & str ,
216
+ description : String ,
217
+ span : Option < Span > ,
218
+ suffix : & str ,
219
+ ) {
220
+ let message = format ! ( "{}{}{}" , prefix, description, suffix) ;
247
221
248
- fn foreign_item_scope_tag ( item : & hir :: ForeignItem < ' _ > ) -> & ' static str {
249
- match item . kind {
250
- hir :: ForeignItemKind :: Fn ( .. ) => "method body" ,
251
- hir :: ForeignItemKind :: Static ( .. ) | hir :: ForeignItemKind :: Type => "associated item" ,
222
+ if let Some ( span ) = span {
223
+ err . span_label ( span , & message ) ;
224
+ } else {
225
+ err . note ( & message ) ;
252
226
}
253
227
}
254
228
255
- fn explain_span ( tcx : TyCtxt < ' tcx > , heading : & str , span : Span ) -> ( String , Option < Span > ) {
256
- let lo = tcx. sess . source_map ( ) . lookup_char_pos ( span. lo ( ) ) ;
257
- ( format ! ( "the {} at {}:{}" , heading, lo. line, lo. col. to_usize( ) + 1 ) , Some ( span) )
258
- }
259
-
260
229
pub fn unexpected_hidden_region_diagnostic (
261
230
tcx : TyCtxt < ' tcx > ,
262
231
span : Span ,
@@ -291,13 +260,25 @@ pub fn unexpected_hidden_region_diagnostic(
291
260
//
292
261
// (*) if not, the `tainted_by_errors` field would be set to
293
262
// `Some(ErrorReported)` in any case, so we wouldn't be here at all.
294
- note_and_explain_free_region (
263
+ explain_free_region (
295
264
tcx,
296
265
& mut err,
297
266
& format ! ( "hidden type `{}` captures " , hidden_ty) ,
298
267
hidden_region,
299
268
"" ,
300
269
) ;
270
+ if let Some ( reg_info) = tcx. is_suitable_region ( hidden_region) {
271
+ let fn_returns = tcx. return_type_impl_or_dyn_traits ( reg_info. def_id ) ;
272
+ nice_region_error:: suggest_new_region_bound (
273
+ tcx,
274
+ & mut err,
275
+ fn_returns,
276
+ hidden_region. to_string ( ) ,
277
+ None ,
278
+ format ! ( "captures {}" , hidden_region) ,
279
+ None ,
280
+ )
281
+ }
301
282
}
302
283
_ => {
303
284
// Ugh. This is a painful case: the hidden region is not one
0 commit comments