@@ -217,128 +217,159 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
217
217
) ) ;
218
218
}
219
219
220
- debug ! ( "try_report_static_impl_trait: fn_return={:?}" , fn_returns) ;
221
- // FIXME: account for the need of parens in `&(dyn Trait + '_)`
222
- let consider = "consider changing the" ;
223
- let declare = "to declare that the" ;
224
220
let arg = match param. param . pat . simple_ident ( ) {
225
221
Some ( simple_ident) => format ! ( "argument `{}`" , simple_ident) ,
226
222
None => "the argument" . to_string ( ) ,
227
223
} ;
228
- let explicit = format ! ( "you can add an explicit `{}` lifetime bound" , lifetime_name) ;
229
- let explicit_static = format ! ( "explicit `'static` bound to the lifetime of {}" , arg) ;
230
224
let captures = format ! ( "captures data from {}" , arg) ;
231
- let add_static_bound = "alternatively, add an explicit `'static` bound to this reference" ;
232
- let plus_lt = format ! ( " + {}" , lifetime_name) ;
233
- for fn_return in fn_returns {
234
- if fn_return. span . desugaring_kind ( ) . is_some ( ) {
235
- // Skip `async` desugaring `impl Future`.
236
- continue ;
237
- }
238
- match fn_return. kind {
239
- TyKind :: OpaqueDef ( item_id, _) => {
240
- let item = tcx. hir ( ) . item ( item_id) ;
241
- let opaque = if let ItemKind :: OpaqueTy ( opaque) = & item. kind {
242
- opaque
243
- } else {
244
- err. emit ( ) ;
245
- return Some ( ErrorReported ) ;
246
- } ;
225
+ suggest_new_region_bound (
226
+ tcx,
227
+ & mut err,
228
+ fn_returns,
229
+ lifetime_name,
230
+ Some ( arg) ,
231
+ captures,
232
+ Some ( ( param. param_ty_span , param. param_ty . to_string ( ) ) ) ,
233
+ ) ;
247
234
248
- if let Some ( span) = opaque
249
- . bounds
250
- . iter ( )
251
- . filter_map ( |arg| match arg {
252
- GenericBound :: Outlives ( Lifetime {
253
- name : LifetimeName :: Static ,
254
- span,
255
- ..
256
- } ) => Some ( * span) ,
257
- _ => None ,
258
- } )
259
- . next ( )
260
- {
235
+ err. emit ( ) ;
236
+ Some ( ErrorReported )
237
+ }
238
+ }
239
+
240
+ pub fn suggest_new_region_bound (
241
+ tcx : TyCtxt < ' tcx > ,
242
+ err : & mut DiagnosticBuilder < ' _ > ,
243
+ fn_returns : Vec < & rustc_hir:: Ty < ' _ > > ,
244
+ lifetime_name : String ,
245
+ arg : Option < String > ,
246
+ captures : String ,
247
+ param : Option < ( Span , String ) > ,
248
+ ) {
249
+ debug ! ( "try_report_static_impl_trait: fn_return={:?}" , fn_returns) ;
250
+ // FIXME: account for the need of parens in `&(dyn Trait + '_)`
251
+ let consider = "consider changing the" ;
252
+ let declare = "to declare that the" ;
253
+ let explicit = format ! ( "you can add an explicit `{}` lifetime bound" , lifetime_name) ;
254
+ let explicit_static =
255
+ arg. map ( |arg| format ! ( "explicit `'static` bound to the lifetime of {}" , arg) ) ;
256
+ let add_static_bound = "alternatively, add an explicit `'static` bound to this reference" ;
257
+ let plus_lt = format ! ( " + {}" , lifetime_name) ;
258
+ for fn_return in fn_returns {
259
+ if fn_return. span . desugaring_kind ( ) . is_some ( ) {
260
+ // Skip `async` desugaring `impl Future`.
261
+ continue ;
262
+ }
263
+ match fn_return. kind {
264
+ TyKind :: OpaqueDef ( item_id, _) => {
265
+ let item = tcx. hir ( ) . item ( item_id) ;
266
+ let opaque = if let ItemKind :: OpaqueTy ( opaque) = & item. kind {
267
+ opaque
268
+ } else {
269
+ return ;
270
+ } ;
271
+
272
+ if let Some ( span) = opaque
273
+ . bounds
274
+ . iter ( )
275
+ . filter_map ( |arg| match arg {
276
+ GenericBound :: Outlives ( Lifetime {
277
+ name : LifetimeName :: Static ,
278
+ span,
279
+ ..
280
+ } ) => Some ( * span) ,
281
+ _ => None ,
282
+ } )
283
+ . next ( )
284
+ {
285
+ if let Some ( explicit_static) = & explicit_static {
261
286
err. span_suggestion_verbose (
262
287
span,
263
288
& format ! ( "{} `impl Trait`'s {}" , consider, explicit_static) ,
264
289
lifetime_name. clone ( ) ,
265
290
Applicability :: MaybeIncorrect ,
266
291
) ;
292
+ }
293
+ if let Some ( ( param_span, param_ty) ) = param. clone ( ) {
267
294
err. span_suggestion_verbose (
268
- param . param_ty_span ,
295
+ param_span ,
269
296
add_static_bound,
270
- param. param_ty . to_string ( ) ,
271
- Applicability :: MaybeIncorrect ,
272
- ) ;
273
- } else if opaque
274
- . bounds
275
- . iter ( )
276
- . filter_map ( |arg| match arg {
277
- GenericBound :: Outlives ( Lifetime { name, span, .. } )
278
- if name. ident ( ) . to_string ( ) == lifetime_name =>
279
- {
280
- Some ( * span)
281
- }
282
- _ => None ,
283
- } )
284
- . next ( )
285
- . is_some ( )
286
- {
287
- } else {
288
- err. span_suggestion_verbose (
289
- fn_return. span . shrink_to_hi ( ) ,
290
- & format ! (
291
- "{declare} `impl Trait` {captures}, {explicit}" ,
292
- declare = declare,
293
- captures = captures,
294
- explicit = explicit,
295
- ) ,
296
- plus_lt. clone ( ) ,
297
+ param_ty,
297
298
Applicability :: MaybeIncorrect ,
298
299
) ;
299
300
}
301
+ } else if opaque
302
+ . bounds
303
+ . iter ( )
304
+ . filter_map ( |arg| match arg {
305
+ GenericBound :: Outlives ( Lifetime { name, span, .. } )
306
+ if name. ident ( ) . to_string ( ) == lifetime_name =>
307
+ {
308
+ Some ( * span)
309
+ }
310
+ _ => None ,
311
+ } )
312
+ . next ( )
313
+ . is_some ( )
314
+ {
315
+ } else {
316
+ err. span_suggestion_verbose (
317
+ fn_return. span . shrink_to_hi ( ) ,
318
+ & format ! (
319
+ "{declare} `impl Trait` {captures}, {explicit}" ,
320
+ declare = declare,
321
+ captures = captures,
322
+ explicit = explicit,
323
+ ) ,
324
+ plus_lt. clone ( ) ,
325
+ Applicability :: MaybeIncorrect ,
326
+ ) ;
300
327
}
301
- TyKind :: TraitObject ( _, lt, _) => match lt. name {
302
- LifetimeName :: ImplicitObjectLifetimeDefault => {
303
- err. span_suggestion_verbose (
304
- fn_return. span . shrink_to_hi ( ) ,
305
- & format ! (
306
- "{declare} trait object {captures}, {explicit}" ,
307
- declare = declare,
308
- captures = captures,
309
- explicit = explicit,
310
- ) ,
311
- plus_lt. clone ( ) ,
312
- Applicability :: MaybeIncorrect ,
313
- ) ;
314
- }
315
- name if name. ident ( ) . to_string ( ) != lifetime_name => {
316
- // With this check we avoid suggesting redundant bounds. This
317
- // would happen if there are nested impl/dyn traits and only
318
- // one of them has the bound we'd suggest already there, like
319
- // in `impl Foo<X = dyn Bar> + '_`.
328
+ }
329
+ TyKind :: TraitObject ( _, lt, _) => match lt. name {
330
+ LifetimeName :: ImplicitObjectLifetimeDefault => {
331
+ err. span_suggestion_verbose (
332
+ fn_return. span . shrink_to_hi ( ) ,
333
+ & format ! (
334
+ "{declare} trait object {captures}, {explicit}" ,
335
+ declare = declare,
336
+ captures = captures,
337
+ explicit = explicit,
338
+ ) ,
339
+ plus_lt. clone ( ) ,
340
+ Applicability :: MaybeIncorrect ,
341
+ ) ;
342
+ }
343
+ name if name. ident ( ) . to_string ( ) != lifetime_name => {
344
+ // With this check we avoid suggesting redundant bounds. This
345
+ // would happen if there are nested impl/dyn traits and only
346
+ // one of them has the bound we'd suggest already there, like
347
+ // in `impl Foo<X = dyn Bar> + '_`.
348
+ if let Some ( explicit_static) = & explicit_static {
320
349
err. span_suggestion_verbose (
321
350
lt. span ,
322
351
& format ! ( "{} trait object's {}" , consider, explicit_static) ,
323
352
lifetime_name. clone ( ) ,
324
353
Applicability :: MaybeIncorrect ,
325
354
) ;
355
+ }
356
+ if let Some ( ( param_span, param_ty) ) = param. clone ( ) {
326
357
err. span_suggestion_verbose (
327
- param . param_ty_span ,
358
+ param_span ,
328
359
add_static_bound,
329
- param . param_ty . to_string ( ) ,
360
+ param_ty,
330
361
Applicability :: MaybeIncorrect ,
331
362
) ;
332
363
}
333
- _ => { }
334
- } ,
364
+ }
335
365
_ => { }
336
- }
366
+ } ,
367
+ _ => { }
337
368
}
338
- err. emit ( ) ;
339
- Some ( ErrorReported )
340
369
}
370
+ }
341
371
372
+ impl < ' a , ' tcx > NiceRegionError < ' a , ' tcx > {
342
373
fn get_impl_ident_and_self_ty_from_trait (
343
374
& self ,
344
375
def_id : DefId ,
0 commit comments