@@ -4,6 +4,7 @@ use crate::infer::error_reporting::nice_region_error::NiceRegionError;
44use crate :: infer:: lexical_region_resolve:: RegionResolutionError ;
55use crate :: infer:: { SubregionOrigin , TypeTrace } ;
66use crate :: traits:: { ObligationCauseCode , UnifyReceiverContext } ;
7+ use rustc_data_structures:: stable_set:: FxHashSet ;
78use rustc_errors:: { struct_span_err, Applicability , DiagnosticBuilder , ErrorReported } ;
89use rustc_hir:: def_id:: DefId ;
910use rustc_hir:: intravisit:: { walk_ty, ErasedMap , NestedVisitorMap , Visitor } ;
@@ -185,17 +186,20 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
185186 }
186187 }
187188 if let SubregionOrigin :: Subtype ( box TypeTrace { cause, .. } ) = & sub_origin {
188- if let ObligationCauseCode :: ItemObligation ( item_def_id) = cause. code {
189+ let code = match & cause. code {
190+ ObligationCauseCode :: MatchImpl ( parent, ..) => & * * parent,
191+ _ => & cause. code ,
192+ } ;
193+ if let ObligationCauseCode :: ItemObligation ( item_def_id) = * code {
189194 // Same case of `impl Foo for dyn Bar { fn qux(&self) {} }` introducing a `'static`
190195 // lifetime as above, but called using a fully-qualified path to the method:
191196 // `Foo::qux(bar)`.
192- let mut v = TraitObjectVisitor ( vec ! [ ] ) ;
197+ let mut v = TraitObjectVisitor ( FxHashSet :: default ( ) ) ;
193198 v. visit_ty ( param. param_ty ) ;
194199 if let Some ( ( ident, self_ty) ) =
195- 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 )
196201 {
197- if self . suggest_constrain_dyn_trait_in_impl ( & mut err, & v. 0 [ ..] , ident, self_ty)
198- {
202+ if self . suggest_constrain_dyn_trait_in_impl ( & mut err, & v. 0 , ident, self_ty) {
199203 override_error_code = Some ( ident) ;
200204 }
201205 }
@@ -336,7 +340,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
336340 fn get_impl_ident_and_self_ty_from_trait (
337341 & self ,
338342 def_id : DefId ,
339- trait_objects : & [ DefId ] ,
343+ trait_objects : & FxHashSet < DefId > ,
340344 ) -> Option < ( Ident , & ' tcx hir:: Ty < ' tcx > ) > {
341345 let tcx = self . tcx ( ) ;
342346 match tcx. hir ( ) . get_if_local ( def_id) {
@@ -373,9 +377,10 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
373377 // multiple `impl`s for the same trait like
374378 // `impl Foo for Box<dyn Bar>` and `impl Foo for dyn Bar`.
375379 // In that case, only the first one will get suggestions.
376- let mut hir_v = HirTraitObjectVisitor ( vec ! [ ] , * did) ;
380+ let mut traits = vec ! [ ] ;
381+ let mut hir_v = HirTraitObjectVisitor ( & mut traits, * did) ;
377382 hir_v. visit_ty ( self_ty) ;
378- !hir_v . 0 . is_empty ( )
383+ !traits . is_empty ( )
379384 } ) =>
380385 {
381386 Some ( self_ty)
@@ -417,33 +422,34 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
417422 _ => return false ,
418423 } ;
419424
420- let mut v = TraitObjectVisitor ( vec ! [ ] ) ;
425+ let mut v = TraitObjectVisitor ( FxHashSet :: default ( ) ) ;
421426 v. visit_ty ( ty) ;
422427
423428 // Get the `Ident` of the method being called and the corresponding `impl` (to point at
424429 // `Bar` in `impl Foo for dyn Bar {}` and the definition of the method being called).
425430 let ( ident, self_ty) =
426- 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 ) {
427432 Some ( ( ident, self_ty) ) => ( ident, self_ty) ,
428433 None => return false ,
429434 } ;
430435
431436 // Find the trait object types in the argument, so we point at *only* the trait object.
432- 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)
433438 }
434439
435440 fn suggest_constrain_dyn_trait_in_impl (
436441 & self ,
437442 err : & mut DiagnosticBuilder < ' _ > ,
438- found_dids : & [ DefId ] ,
443+ found_dids : & FxHashSet < DefId > ,
439444 ident : Ident ,
440445 self_ty : & hir:: Ty < ' _ > ,
441446 ) -> bool {
442447 let mut suggested = false ;
443448 for found_did in found_dids {
444- let mut hir_v = HirTraitObjectVisitor ( vec ! [ ] , * found_did) ;
449+ let mut traits = vec ! [ ] ;
450+ let mut hir_v = HirTraitObjectVisitor ( & mut traits, * found_did) ;
445451 hir_v. visit_ty ( & self_ty) ;
446- for span in & hir_v . 0 {
452+ for span in & traits {
447453 let mut multi_span: MultiSpan = vec ! [ * span] . into ( ) ;
448454 multi_span. push_span_label (
449455 * span,
@@ -468,14 +474,14 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
468474}
469475
470476/// Collect all the trait objects in a type that could have received an implicit `'static` lifetime.
471- struct TraitObjectVisitor ( Vec < DefId > ) ;
477+ pub ( super ) struct TraitObjectVisitor ( pub ( super ) FxHashSet < DefId > ) ;
472478
473479impl TypeVisitor < ' _ > for TraitObjectVisitor {
474480 fn visit_ty ( & mut self , t : Ty < ' _ > ) -> ControlFlow < Self :: BreakTy > {
475481 match t. kind ( ) {
476482 ty:: Dynamic ( preds, RegionKind :: ReStatic ) => {
477483 if let Some ( def_id) = preds. principal_def_id ( ) {
478- self . 0 . push ( def_id) ;
484+ self . 0 . insert ( def_id) ;
479485 }
480486 ControlFlow :: CONTINUE
481487 }
@@ -485,9 +491,9 @@ impl TypeVisitor<'_> for TraitObjectVisitor {
485491}
486492
487493/// Collect all `hir::Ty<'_>` `Span`s for trait objects with an implicit lifetime.
488- struct HirTraitObjectVisitor ( Vec < Span > , DefId ) ;
494+ pub ( super ) struct HirTraitObjectVisitor < ' a > ( pub ( super ) & ' a mut Vec < Span > , pub ( super ) DefId ) ;
489495
490- impl < ' tcx > Visitor < ' tcx > for HirTraitObjectVisitor {
496+ impl < ' a , ' tcx > Visitor < ' tcx > for HirTraitObjectVisitor < ' a > {
491497 type Map = ErasedMap < ' tcx > ;
492498
493499 fn nested_visit_map ( & mut self ) -> NestedVisitorMap < Self :: Map > {
0 commit comments