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