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