44use std:: fmt:: { self , Display } ;
55use std:: iter;
66
7+ use rustc_data_structures:: fx:: IndexEntry ;
78use rustc_errors:: Diagnostic ;
89use rustc_hir as hir;
910use rustc_hir:: def:: { DefKind , Res } ;
@@ -17,7 +18,7 @@ use crate::{universal_regions::DefiningTy, MirBorrowckCtxt};
1718
1819/// A name for a particular region used in emitting diagnostics. This name could be a generated
1920/// 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 ) ]
2122pub ( crate ) struct RegionName {
2223 /// The name of the region (interned).
2324 pub ( crate ) name : Symbol ,
@@ -28,7 +29,7 @@ pub(crate) struct RegionName {
2829/// Denotes the source of a region that is named by a `RegionName`. For example, a free region that
2930/// was named by the user would get `NamedLateParamRegion` and `'static` lifetime would get `Static`.
3031/// This helps to print the right kinds of diagnostics.
31- #[ derive( Debug , Clone ) ]
32+ #[ derive( Debug , Clone , Copy ) ]
3233pub ( crate ) enum RegionNameSource {
3334 /// A bound (not free) region that was instantiated at the def site (not an HRTB).
3435 NamedEarlyParamRegion ( Span ) ,
@@ -45,7 +46,7 @@ pub(crate) enum RegionNameSource {
4546 /// The region corresponding to the return type of a closure.
4647 AnonRegionFromOutput ( RegionNameHighlight , & ' static str ) ,
4748 /// The region from a type yielded by a coroutine.
48- AnonRegionFromYieldTy ( Span , String ) ,
49+ AnonRegionFromYieldTy ( Span , Symbol ) ,
4950 /// An anonymous region from an async fn.
5051 AnonRegionFromAsyncFn ( Span ) ,
5152 /// An anonymous region from an impl self type or trait
@@ -54,19 +55,19 @@ pub(crate) enum RegionNameSource {
5455
5556/// Describes what to highlight to explain to the user that we're giving an anonymous region a
5657/// synthesized name, and how to highlight it.
57- #[ derive( Debug , Clone ) ]
58+ #[ derive( Debug , Clone , Copy ) ]
5859pub ( crate ) enum RegionNameHighlight {
5960 /// The anonymous region corresponds to a reference that was found by traversing the type in the HIR.
6061 MatchedHirTy ( Span ) ,
6162 /// The anonymous region corresponds to a `'_` in the generics list of a struct/enum/union.
6263 MatchedAdtAndSegment ( Span ) ,
6364 /// The anonymous region corresponds to a region where the type annotation is completely missing
6465 /// from the code, e.g. in a closure arguments `|x| { ... }`, where `x` is a reference.
65- CannotMatchHirTy ( Span , String ) ,
66+ CannotMatchHirTy ( Span , Symbol ) ,
6667 /// The anonymous region corresponds to a region where the type annotation is completely missing
6768 /// from the code, and *even if* we print out the full name of the type, the region name won't
6869 /// be included. This currently occurs for opaque types like `impl Future`.
69- Occluded ( Span , String ) ,
70+ Occluded ( Span , Symbol ) ,
7071}
7172
7273impl RegionName {
@@ -250,25 +251,28 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
250251
251252 assert ! ( self . regioncx. universal_regions( ) . is_universal_region( fr) ) ;
252253
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) ;
256272
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+ }
268275 }
269-
270- debug ! ( "give_region_a_name: gave name {:?}" , value) ;
271- value
272276 }
273277
274278 /// Checks for the case where `fr` maps to something that the
@@ -460,9 +464,9 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
460464 ) ;
461465 if type_name. contains ( & format ! ( "'{counter}" ) ) {
462466 // 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) )
464468 } else {
465- RegionNameHighlight :: Occluded ( span, type_name)
469+ RegionNameHighlight :: Occluded ( span, Symbol :: intern ( & type_name) )
466470 }
467471 }
468472
@@ -891,7 +895,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
891895
892896 Some ( RegionName {
893897 name : self . synthesize_region_name ( ) ,
894- source : RegionNameSource :: AnonRegionFromYieldTy ( yield_span, type_name) ,
898+ source : RegionNameSource :: AnonRegionFromYieldTy ( yield_span, Symbol :: intern ( & type_name) ) ,
895899 } )
896900 }
897901
@@ -983,7 +987,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
983987 Some ( RegionName {
984988 name : region_name,
985989 source : RegionNameSource :: AnonRegionFromArgument (
986- RegionNameHighlight :: CannotMatchHirTy ( arg_span, arg_name?. to_string ( ) ) ,
990+ RegionNameHighlight :: CannotMatchHirTy ( arg_span, arg_name?) ,
987991 ) ,
988992 } )
989993 } else {
0 commit comments