4
4
use std:: fmt:: { self , Display } ;
5
5
use std:: iter;
6
6
7
+ use rustc_data_structures:: fx:: IndexEntry ;
7
8
use rustc_errors:: Diagnostic ;
8
9
use rustc_hir as hir;
9
10
use rustc_hir:: def:: { DefKind , Res } ;
@@ -17,7 +18,7 @@ use crate::{universal_regions::DefiningTy, MirBorrowckCtxt};
17
18
18
19
/// A name for a particular region used in emitting diagnostics. This name could be a generated
19
20
/// name like `'1`, a name used by the user like `'a`, or a name like `'static`.
20
- #[ derive( Debug , Clone ) ]
21
+ #[ derive( Debug , Clone , Copy ) ]
21
22
pub ( crate ) struct RegionName {
22
23
/// The name of the region (interned).
23
24
pub ( crate ) name : Symbol ,
@@ -28,7 +29,7 @@ pub(crate) struct RegionName {
28
29
/// Denotes the source of a region that is named by a `RegionName`. For example, a free region that
29
30
/// was named by the user would get `NamedLateParamRegion` and `'static` lifetime would get `Static`.
30
31
/// This helps to print the right kinds of diagnostics.
31
- #[ derive( Debug , Clone ) ]
32
+ #[ derive( Debug , Clone , Copy ) ]
32
33
pub ( crate ) enum RegionNameSource {
33
34
/// A bound (not free) region that was instantiated at the def site (not an HRTB).
34
35
NamedEarlyParamRegion ( Span ) ,
@@ -45,7 +46,7 @@ pub(crate) enum RegionNameSource {
45
46
/// The region corresponding to the return type of a closure.
46
47
AnonRegionFromOutput ( RegionNameHighlight , & ' static str ) ,
47
48
/// The region from a type yielded by a coroutine.
48
- AnonRegionFromYieldTy ( Span , String ) ,
49
+ AnonRegionFromYieldTy ( Span , Symbol ) ,
49
50
/// An anonymous region from an async fn.
50
51
AnonRegionFromAsyncFn ( Span ) ,
51
52
/// An anonymous region from an impl self type or trait
@@ -54,19 +55,19 @@ pub(crate) enum RegionNameSource {
54
55
55
56
/// Describes what to highlight to explain to the user that we're giving an anonymous region a
56
57
/// synthesized name, and how to highlight it.
57
- #[ derive( Debug , Clone ) ]
58
+ #[ derive( Debug , Clone , Copy ) ]
58
59
pub ( crate ) enum RegionNameHighlight {
59
60
/// The anonymous region corresponds to a reference that was found by traversing the type in the HIR.
60
61
MatchedHirTy ( Span ) ,
61
62
/// The anonymous region corresponds to a `'_` in the generics list of a struct/enum/union.
62
63
MatchedAdtAndSegment ( Span ) ,
63
64
/// The anonymous region corresponds to a region where the type annotation is completely missing
64
65
/// from the code, e.g. in a closure arguments `|x| { ... }`, where `x` is a reference.
65
- CannotMatchHirTy ( Span , String ) ,
66
+ CannotMatchHirTy ( Span , Symbol ) ,
66
67
/// The anonymous region corresponds to a region where the type annotation is completely missing
67
68
/// from the code, and *even if* we print out the full name of the type, the region name won't
68
69
/// be included. This currently occurs for opaque types like `impl Future`.
69
- Occluded ( Span , String ) ,
70
+ Occluded ( Span , Symbol ) ,
70
71
}
71
72
72
73
impl RegionName {
@@ -250,25 +251,28 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
250
251
251
252
assert ! ( self . regioncx. universal_regions( ) . is_universal_region( fr) ) ;
252
253
253
- if let Some ( value) = self . region_names . try_borrow_mut ( ) . unwrap ( ) . get ( & fr) {
254
- return Some ( value. clone ( ) ) ;
255
- }
254
+ match self . region_names . borrow_mut ( ) . entry ( fr) {
255
+ IndexEntry :: Occupied ( precomputed_name) => Some ( * precomputed_name. get ( ) ) ,
256
+ IndexEntry :: Vacant ( slot) => {
257
+ let new_name = self
258
+ . give_name_from_error_region ( fr)
259
+ . or_else ( || self . give_name_if_anonymous_region_appears_in_arguments ( fr) )
260
+ . or_else ( || self . give_name_if_anonymous_region_appears_in_upvars ( fr) )
261
+ . or_else ( || self . give_name_if_anonymous_region_appears_in_output ( fr) )
262
+ . or_else ( || self . give_name_if_anonymous_region_appears_in_yield_ty ( fr) )
263
+ . or_else ( || self . give_name_if_anonymous_region_appears_in_impl_signature ( fr) )
264
+ . or_else ( || {
265
+ self . give_name_if_anonymous_region_appears_in_arg_position_impl_trait ( fr)
266
+ } ) ;
267
+
268
+ if let Some ( new_name) = new_name {
269
+ slot. insert ( new_name) ;
270
+ }
271
+ debug ! ( "give_region_a_name: gave name {:?}" , new_name) ;
256
272
257
- let value = self
258
- . give_name_from_error_region ( fr)
259
- . or_else ( || self . give_name_if_anonymous_region_appears_in_arguments ( fr) )
260
- . or_else ( || self . give_name_if_anonymous_region_appears_in_upvars ( fr) )
261
- . or_else ( || self . give_name_if_anonymous_region_appears_in_output ( fr) )
262
- . or_else ( || self . give_name_if_anonymous_region_appears_in_yield_ty ( fr) )
263
- . or_else ( || self . give_name_if_anonymous_region_appears_in_impl_signature ( fr) )
264
- . or_else ( || self . give_name_if_anonymous_region_appears_in_arg_position_impl_trait ( fr) ) ;
265
-
266
- if let Some ( value) = & value {
267
- self . region_names . try_borrow_mut ( ) . unwrap ( ) . insert ( fr, value. clone ( ) ) ;
273
+ new_name
274
+ }
268
275
}
269
-
270
- debug ! ( "give_region_a_name: gave name {:?}" , value) ;
271
- value
272
276
}
273
277
274
278
/// Checks for the case where `fr` maps to something that the
@@ -460,9 +464,9 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
460
464
) ;
461
465
if type_name. contains ( & format ! ( "'{counter}" ) ) {
462
466
// Only add a label if we can confirm that a region was labelled.
463
- RegionNameHighlight :: CannotMatchHirTy ( span, type_name)
467
+ RegionNameHighlight :: CannotMatchHirTy ( span, Symbol :: intern ( & type_name) )
464
468
} else {
465
- RegionNameHighlight :: Occluded ( span, type_name)
469
+ RegionNameHighlight :: Occluded ( span, Symbol :: intern ( & type_name) )
466
470
}
467
471
}
468
472
@@ -891,7 +895,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
891
895
892
896
Some ( RegionName {
893
897
name : self . synthesize_region_name ( ) ,
894
- source : RegionNameSource :: AnonRegionFromYieldTy ( yield_span, type_name) ,
898
+ source : RegionNameSource :: AnonRegionFromYieldTy ( yield_span, Symbol :: intern ( & type_name) ) ,
895
899
} )
896
900
}
897
901
@@ -983,7 +987,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
983
987
Some ( RegionName {
984
988
name : region_name,
985
989
source : RegionNameSource :: AnonRegionFromArgument (
986
- RegionNameHighlight :: CannotMatchHirTy ( arg_span, arg_name?. to_string ( ) ) ,
990
+ RegionNameHighlight :: CannotMatchHirTy ( arg_span, arg_name?) ,
987
991
) ,
988
992
} )
989
993
} else {
0 commit comments