@@ -4,6 +4,7 @@ use crate::infer::error_reporting::nice_region_error::NiceRegionError;
4
4
use crate :: infer:: lexical_region_resolve:: RegionResolutionError ;
5
5
use crate :: infer:: { SubregionOrigin , TypeTrace } ;
6
6
use crate :: traits:: { ObligationCauseCode , UnifyReceiverContext } ;
7
+ use rustc_data_structures:: stable_set:: FxHashSet ;
7
8
use rustc_errors:: { struct_span_err, Applicability , DiagnosticBuilder , ErrorReported } ;
8
9
use rustc_hir:: def_id:: DefId ;
9
10
use rustc_hir:: intravisit:: { walk_ty, ErasedMap , NestedVisitorMap , Visitor } ;
@@ -193,13 +194,12 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
193
194
// Same case of `impl Foo for dyn Bar { fn qux(&self) {} }` introducing a `'static`
194
195
// lifetime as above, but called using a fully-qualified path to the method:
195
196
// `Foo::qux(bar)`.
196
- let mut v = TraitObjectVisitor ( vec ! [ ] ) ;
197
+ let mut v = TraitObjectVisitor ( FxHashSet :: default ( ) ) ;
197
198
v. visit_ty ( param. param_ty ) ;
198
199
if let Some ( ( ident, self_ty) ) =
199
- self . get_impl_ident_and_self_ty_from_trait ( item_def_id, & v. 0 [ .. ] )
200
+ self . get_impl_ident_and_self_ty_from_trait ( item_def_id, & v. 0 )
200
201
{
201
- if self . suggest_constrain_dyn_trait_in_impl ( & mut err, & v. 0 [ ..] , ident, self_ty)
202
- {
202
+ if self . suggest_constrain_dyn_trait_in_impl ( & mut err, & v. 0 , ident, self_ty) {
203
203
override_error_code = Some ( ident) ;
204
204
}
205
205
}
@@ -340,7 +340,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
340
340
fn get_impl_ident_and_self_ty_from_trait (
341
341
& self ,
342
342
def_id : DefId ,
343
- trait_objects : & [ DefId ] ,
343
+ trait_objects : & FxHashSet < DefId > ,
344
344
) -> Option < ( Ident , & ' tcx hir:: Ty < ' tcx > ) > {
345
345
let tcx = self . tcx ( ) ;
346
346
match tcx. hir ( ) . get_if_local ( def_id) {
@@ -377,9 +377,10 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
377
377
// multiple `impl`s for the same trait like
378
378
// `impl Foo for Box<dyn Bar>` and `impl Foo for dyn Bar`.
379
379
// In that case, only the first one will get suggestions.
380
- let mut hir_v = HirTraitObjectVisitor ( vec ! [ ] , * did) ;
380
+ let mut traits = vec ! [ ] ;
381
+ let mut hir_v = HirTraitObjectVisitor ( & mut traits, * did) ;
381
382
hir_v. visit_ty ( self_ty) ;
382
- !hir_v . 0 . is_empty ( )
383
+ !traits . is_empty ( )
383
384
} ) =>
384
385
{
385
386
Some ( self_ty)
@@ -421,33 +422,34 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
421
422
_ => return false ,
422
423
} ;
423
424
424
- let mut v = TraitObjectVisitor ( vec ! [ ] ) ;
425
+ let mut v = TraitObjectVisitor ( FxHashSet :: default ( ) ) ;
425
426
v. visit_ty ( ty) ;
426
427
427
428
// Get the `Ident` of the method being called and the corresponding `impl` (to point at
428
429
// `Bar` in `impl Foo for dyn Bar {}` and the definition of the method being called).
429
430
let ( ident, self_ty) =
430
- match self . get_impl_ident_and_self_ty_from_trait ( instance. def_id ( ) , & v. 0 [ .. ] ) {
431
+ match self . get_impl_ident_and_self_ty_from_trait ( instance. def_id ( ) , & v. 0 ) {
431
432
Some ( ( ident, self_ty) ) => ( ident, self_ty) ,
432
433
None => return false ,
433
434
} ;
434
435
435
436
// Find the trait object types in the argument, so we point at *only* the trait object.
436
- self . suggest_constrain_dyn_trait_in_impl ( err, & v. 0 [ .. ] , ident, self_ty)
437
+ self . suggest_constrain_dyn_trait_in_impl ( err, & v. 0 , ident, self_ty)
437
438
}
438
439
439
440
fn suggest_constrain_dyn_trait_in_impl (
440
441
& self ,
441
442
err : & mut DiagnosticBuilder < ' _ > ,
442
- found_dids : & [ DefId ] ,
443
+ found_dids : & FxHashSet < DefId > ,
443
444
ident : Ident ,
444
445
self_ty : & hir:: Ty < ' _ > ,
445
446
) -> bool {
446
447
let mut suggested = false ;
447
448
for found_did in found_dids {
448
- let mut hir_v = HirTraitObjectVisitor ( vec ! [ ] , * found_did) ;
449
+ let mut traits = vec ! [ ] ;
450
+ let mut hir_v = HirTraitObjectVisitor ( & mut traits, * found_did) ;
449
451
hir_v. visit_ty ( & self_ty) ;
450
- for span in & hir_v . 0 {
452
+ for span in & traits {
451
453
let mut multi_span: MultiSpan = vec ! [ * span] . into ( ) ;
452
454
multi_span. push_span_label (
453
455
* span,
@@ -472,14 +474,14 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
472
474
}
473
475
474
476
/// Collect all the trait objects in a type that could have received an implicit `'static` lifetime.
475
- pub ( super ) struct TraitObjectVisitor ( pub ( super ) Vec < DefId > ) ;
477
+ pub ( super ) struct TraitObjectVisitor ( pub ( super ) FxHashSet < DefId > ) ;
476
478
477
479
impl TypeVisitor < ' _ > for TraitObjectVisitor {
478
480
fn visit_ty ( & mut self , t : Ty < ' _ > ) -> ControlFlow < Self :: BreakTy > {
479
481
match t. kind ( ) {
480
482
ty:: Dynamic ( preds, RegionKind :: ReStatic ) => {
481
483
if let Some ( def_id) = preds. principal_def_id ( ) {
482
- self . 0 . push ( def_id) ;
484
+ self . 0 . insert ( def_id) ;
483
485
}
484
486
ControlFlow :: CONTINUE
485
487
}
@@ -489,9 +491,9 @@ impl TypeVisitor<'_> for TraitObjectVisitor {
489
491
}
490
492
491
493
/// Collect all `hir::Ty<'_>` `Span`s for trait objects with an implicit lifetime.
492
- pub ( super ) struct HirTraitObjectVisitor ( pub ( super ) Vec < Span > , pub ( super ) DefId ) ;
494
+ pub ( super ) struct HirTraitObjectVisitor < ' a > ( pub ( super ) & ' a mut Vec < Span > , pub ( super ) DefId ) ;
493
495
494
- impl < ' tcx > Visitor < ' tcx > for HirTraitObjectVisitor {
496
+ impl < ' a , ' tcx > Visitor < ' tcx > for HirTraitObjectVisitor < ' a > {
495
497
type Map = ErasedMap < ' tcx > ;
496
498
497
499
fn nested_visit_map ( & mut self ) -> NestedVisitorMap < Self :: Map > {
0 commit comments