@@ -13,13 +13,13 @@ use rustc::hir::def_id::DefId;
13
13
use rustc:: infer:: InferCtxt ;
14
14
use rustc:: mir:: { Local , Body } ;
15
15
use rustc:: ty:: subst:: { SubstsRef , GenericArgKind } ;
16
- use rustc:: ty:: { self , RegionKind , RegionVid , Ty , TyCtxt } ;
16
+ use rustc:: ty:: { self , RegionVid , Ty , TyCtxt } ;
17
17
use rustc:: ty:: print:: RegionHighlightMode ;
18
18
use rustc_index:: vec:: IndexVec ;
19
19
use rustc_errors:: DiagnosticBuilder ;
20
20
use syntax:: symbol:: kw;
21
21
use rustc_data_structures:: fx:: FxHashMap ;
22
- use syntax_pos:: { Span , symbol:: Symbol } ;
22
+ use syntax_pos:: { Span , symbol:: Symbol , DUMMY_SP } ;
23
23
24
24
/// A name for a particular region used in emitting diagnostics. This name could be a generated
25
25
/// name like `'1`, a name used by the user like `'a`, or a name like `'static`.
@@ -55,7 +55,10 @@ crate enum RegionNameSource {
55
55
AnonRegionFromUpvar ( Span , String ) ,
56
56
/// The region corresponding to the return type of a closure.
57
57
AnonRegionFromOutput ( Span , String , String ) ,
58
+ /// The region from a type yielded by a generator.
58
59
AnonRegionFromYieldTy ( Span , String ) ,
60
+ /// An anonymous region from an async fn.
61
+ AnonRegionFromAsyncFn ( Span ) ,
59
62
}
60
63
61
64
/// Records region names that have been assigned before so that we can use the same ones in later
@@ -113,14 +116,11 @@ impl RegionName {
113
116
RegionNameSource :: MatchedAdtAndSegment ( ..) |
114
117
RegionNameSource :: AnonRegionFromUpvar ( ..) |
115
118
RegionNameSource :: AnonRegionFromOutput ( ..) |
116
- RegionNameSource :: AnonRegionFromYieldTy ( ..) => false ,
119
+ RegionNameSource :: AnonRegionFromYieldTy ( ..) |
120
+ RegionNameSource :: AnonRegionFromAsyncFn ( ..) => false ,
117
121
}
118
122
}
119
123
120
- crate fn name ( & self ) -> Symbol {
121
- self . name
122
- }
123
-
124
124
crate fn highlight_region_name ( & self , diag : & mut DiagnosticBuilder < ' _ > ) {
125
125
match & self . source {
126
126
RegionNameSource :: NamedFreeRegion ( span)
@@ -137,7 +137,8 @@ impl RegionName {
137
137
RegionNameSource :: CannotMatchHirTy ( span, type_name) => {
138
138
diag. span_label ( * span, format ! ( "has type `{}`" , type_name) ) ;
139
139
}
140
- RegionNameSource :: MatchedHirTy ( span) => {
140
+ RegionNameSource :: MatchedHirTy ( span) |
141
+ RegionNameSource :: AnonRegionFromAsyncFn ( span) => {
141
142
diag. span_label (
142
143
* span,
143
144
format ! ( "let's call the lifetime of this reference `{}`" , self ) ,
@@ -270,7 +271,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
270
271
match error_region {
271
272
ty:: ReEarlyBound ( ebr) => {
272
273
if ebr. has_name ( ) {
273
- let span = self . get_named_span ( tcx , error_region , ebr. name ) ;
274
+ let span = tcx . hir ( ) . span_if_local ( ebr. def_id ) . unwrap_or ( DUMMY_SP ) ;
274
275
Some ( RegionName {
275
276
name : ebr. name ,
276
277
source : RegionNameSource :: NamedEarlyBoundRegion ( span) ,
@@ -286,12 +287,30 @@ impl<'tcx> RegionInferenceContext<'tcx> {
286
287
} ) ,
287
288
288
289
ty:: ReFree ( free_region) => match free_region. bound_region {
289
- ty:: BoundRegion :: BrNamed ( _, name) => {
290
- let span = self . get_named_span ( tcx, error_region, name) ;
291
- Some ( RegionName {
292
- name,
293
- source : RegionNameSource :: NamedFreeRegion ( span) ,
294
- } )
290
+ ty:: BoundRegion :: BrNamed ( region_def_id, name) => {
291
+ // Get the span to point to, even if we don't use the name.
292
+ let span = tcx. hir ( ) . span_if_local ( region_def_id) . unwrap_or ( DUMMY_SP ) ;
293
+ debug ! ( "bound region named: {:?}, is_named: {:?}" ,
294
+ name, free_region. bound_region. is_named( ) ) ;
295
+
296
+ if free_region. bound_region . is_named ( ) {
297
+ // A named region that is actually named.
298
+ Some ( RegionName {
299
+ name,
300
+ source : RegionNameSource :: NamedFreeRegion ( span) ,
301
+ } )
302
+ } else {
303
+ // If we spuriously thought that the region is named, we should let the
304
+ // system generate a true name for error messages. Currently this can
305
+ // happen if we have an elided name in an async fn for example: the
306
+ // compiler will generate a region named `'_`, but reporting such a name is
307
+ // not actually useful, so we synthesize a name for it instead.
308
+ let name = renctx. synthesize_region_name ( ) ;
309
+ Some ( RegionName {
310
+ name,
311
+ source : RegionNameSource :: AnonRegionFromAsyncFn ( span) ,
312
+ } )
313
+ }
295
314
}
296
315
297
316
ty:: BoundRegion :: BrEnv => {
@@ -350,40 +369,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
350
369
}
351
370
}
352
371
353
- /// Gets a span of a named region to provide context for error messages that
354
- /// mention that span, for example:
355
- ///
356
- /// ```
357
- /// |
358
- /// | fn two_regions<'a, 'b, T>(cell: Cell<&'a ()>, t: T)
359
- /// | -- -- lifetime `'b` defined here
360
- /// | |
361
- /// | lifetime `'a` defined here
362
- /// |
363
- /// | with_signature(cell, t, |cell, t| require(cell, t));
364
- /// | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'b` must
365
- /// | outlive `'a`
366
- /// ```
367
- fn get_named_span (
368
- & self ,
369
- tcx : TyCtxt < ' tcx > ,
370
- error_region : & RegionKind ,
371
- name : Symbol ,
372
- ) -> Span {
373
- let scope = error_region. free_region_binding_scope ( tcx) ;
374
- let node = tcx. hir ( ) . as_local_hir_id ( scope) . unwrap_or ( hir:: DUMMY_HIR_ID ) ;
375
-
376
- let span = tcx. sess . source_map ( ) . def_span ( tcx. hir ( ) . span ( node) ) ;
377
- if let Some ( param) = tcx. hir ( )
378
- . get_generics ( scope)
379
- . and_then ( |generics| generics. get_named ( name) )
380
- {
381
- param. span
382
- } else {
383
- span
384
- }
385
- }
386
-
387
372
/// Finds an argument that contains `fr` and label it with a fully
388
373
/// elaborated type, returning something like `'1`. Result looks
389
374
/// like:
0 commit comments