@@ -32,7 +32,7 @@ pub enum ObjectSafetyViolation {
3232
3333    /// Supertrait reference references `Self` an in illegal location 
3434/// (e.g., `trait Foo : Bar<Self>`). 
35- SupertraitSelf , 
35+ SupertraitSelf ( SmallVec < [ Span ;   1 ] > ) , 
3636
3737    /// Method has something illegal. 
3838Method ( ast:: Name ,  MethodViolationCode ,  Span ) , 
@@ -45,9 +45,13 @@ impl ObjectSafetyViolation {
4545    pub  fn  error_msg ( & self )  -> Cow < ' static ,  str >  { 
4646        match  * self  { 
4747            ObjectSafetyViolation :: SizedSelf ( _)  => "it requires `Self: Sized`" . into ( ) , 
48-             ObjectSafetyViolation :: SupertraitSelf  => { 
49-                 "it cannot use `Self` as a type parameter in the supertraits or `where`-clauses" 
50-                     . into ( ) 
48+             ObjectSafetyViolation :: SupertraitSelf ( ref  spans)  => { 
49+                 if  spans. iter ( ) . any ( |sp| * sp != DUMMY_SP )  { 
50+                     "it uses `Self` as a type parameter in this" . into ( ) 
51+                 }  else  { 
52+                     "it cannot use `Self` as a type parameter in a supertrait or `where`-clause" 
53+                         . into ( ) 
54+                 } 
5155            } 
5256            ObjectSafetyViolation :: Method ( name,  MethodViolationCode :: StaticMethod ( _) ,  _)  => { 
5357                format ! ( "associated function `{}` has no `self` parameter" ,  name) . into ( ) 
@@ -87,7 +91,7 @@ impl ObjectSafetyViolation {
8791
8892    pub  fn  solution ( & self )  -> Option < ( String ,  Option < ( String ,  Span ) > ) >  { 
8993        Some ( match  * self  { 
90-             ObjectSafetyViolation :: SizedSelf ( _)  | ObjectSafetyViolation :: SupertraitSelf  => { 
94+             ObjectSafetyViolation :: SizedSelf ( _)  | ObjectSafetyViolation :: SupertraitSelf ( _ )  => { 
9195                return  None ; 
9296            } 
9397            ObjectSafetyViolation :: Method ( name,  MethodViolationCode :: StaticMethod ( sugg) ,  _)  => ( 
@@ -118,7 +122,8 @@ impl ObjectSafetyViolation {
118122        // When `span` comes from a separate crate, it'll be `DUMMY_SP`. Treat it as `None` so 
119123        // diagnostics use a `note` instead of a `span_label`. 
120124        match  self  { 
121-             ObjectSafetyViolation :: SizedSelf ( spans)  => spans. clone ( ) , 
125+             ObjectSafetyViolation :: SupertraitSelf ( spans) 
126+             | ObjectSafetyViolation :: SizedSelf ( spans)  => spans. clone ( ) , 
122127            ObjectSafetyViolation :: AssocConst ( _,  span) 
123128            | ObjectSafetyViolation :: Method ( _,  _,  span) 
124129                if  * span != DUMMY_SP  =>
@@ -162,8 +167,9 @@ pub fn astconv_object_safety_violations(
162167)  -> Vec < ObjectSafetyViolation >  { 
163168    debug_assert ! ( tcx. generics_of( trait_def_id) . has_self) ; 
164169    let  violations = traits:: supertrait_def_ids ( tcx,  trait_def_id) 
165-         . filter ( |& def_id| predicates_reference_self ( tcx,  def_id,  true ) ) 
166-         . map ( |_| ObjectSafetyViolation :: SupertraitSelf ) 
170+         . map ( |def_id| predicates_reference_self ( tcx,  def_id,  true ) ) 
171+         . filter ( |spans| !spans. is_empty ( ) ) 
172+         . map ( |spans| ObjectSafetyViolation :: SupertraitSelf ( spans) ) 
167173        . collect ( ) ; 
168174
169175    debug ! ( "astconv_object_safety_violations(trait_def_id={:?}) = {:?}" ,  trait_def_id,  violations) ; 
@@ -266,8 +272,9 @@ fn object_safety_violations_for_trait(
266272        let  spans = get_sized_bounds ( tcx,  trait_def_id) ; 
267273        violations. push ( ObjectSafetyViolation :: SizedSelf ( spans) ) ; 
268274    } 
269-     if  predicates_reference_self ( tcx,  trait_def_id,  false )  { 
270-         violations. push ( ObjectSafetyViolation :: SupertraitSelf ) ; 
275+     let  spans = predicates_reference_self ( tcx,  trait_def_id,  false ) ; 
276+     if  !spans. is_empty ( )  { 
277+         violations. push ( ObjectSafetyViolation :: SupertraitSelf ( spans) ) ; 
271278    } 
272279
273280    violations. extend ( 
@@ -337,7 +344,11 @@ fn get_sized_bounds(tcx: TyCtxt<'_>, trait_def_id: DefId) -> SmallVec<[Span; 1]>
337344        . unwrap_or_else ( SmallVec :: new) 
338345} 
339346
340- fn  predicates_reference_self ( tcx :  TyCtxt < ' _ > ,  trait_def_id :  DefId ,  supertraits_only :  bool )  -> bool  { 
347+ fn  predicates_reference_self ( 
348+     tcx :  TyCtxt < ' _ > , 
349+     trait_def_id :  DefId , 
350+     supertraits_only :  bool , 
351+ )  -> SmallVec < [ Span ;  1 ] >  { 
341352    let  trait_ref = ty:: Binder :: dummy ( ty:: TraitRef :: identity ( tcx,  trait_def_id) ) ; 
342353    let  predicates = if  supertraits_only { 
343354        tcx. super_predicates_of ( trait_def_id) 
@@ -349,12 +360,16 @@ fn predicates_reference_self(tcx: TyCtxt<'_>, trait_def_id: DefId, supertraits_o
349360    predicates
350361        . predicates 
351362        . iter ( ) 
352-         . map ( |( predicate,  _ ) | predicate. subst_supertrait ( tcx,  & trait_ref) ) 
353-         . any ( | predicate| { 
363+         . map ( |( predicate,  sp ) | ( predicate. subst_supertrait ( tcx,  & trait_ref) ,  sp ) ) 
364+         . filter_map ( | ( predicate,   & sp ) | { 
354365            match  predicate { 
355366                ty:: Predicate :: Trait ( ref  data,  _)  => { 
356367                    // In the case of a trait predicate, we can skip the "self" type. 
357-                     data. skip_binder ( ) . input_types ( ) . skip ( 1 ) . any ( has_self_ty) 
368+                     if  data. skip_binder ( ) . input_types ( ) . skip ( 1 ) . any ( has_self_ty)  { 
369+                         Some ( sp) 
370+                     }  else  { 
371+                         None 
372+                     } 
358373                } 
359374                ty:: Predicate :: Projection ( ref  data)  => { 
360375                    // And similarly for projections. This should be redundant with 
@@ -369,22 +384,29 @@ fn predicates_reference_self(tcx: TyCtxt<'_>, trait_def_id: DefId, supertraits_o
369384                    // 
370385                    // This is ALT2 in issue #56288, see that for discussion of the 
371386                    // possible alternatives. 
372-                     data. skip_binder ( ) 
387+                     if  data
388+                         . skip_binder ( ) 
373389                        . projection_ty 
374390                        . trait_ref ( tcx) 
375391                        . input_types ( ) 
376392                        . skip ( 1 ) 
377393                        . any ( has_self_ty) 
394+                     { 
395+                         Some ( sp) 
396+                     }  else  { 
397+                         None 
398+                     } 
378399                } 
379400                ty:: Predicate :: WellFormed ( ..) 
380401                | ty:: Predicate :: ObjectSafe ( ..) 
381402                | ty:: Predicate :: TypeOutlives ( ..) 
382403                | ty:: Predicate :: RegionOutlives ( ..) 
383404                | ty:: Predicate :: ClosureKind ( ..) 
384405                | ty:: Predicate :: Subtype ( ..) 
385-                 | ty:: Predicate :: ConstEvaluatable ( ..)  => false , 
406+                 | ty:: Predicate :: ConstEvaluatable ( ..)  => None , 
386407            } 
387408        } ) 
409+         . collect ( ) 
388410} 
389411
390412fn  trait_has_sized_self ( tcx :  TyCtxt < ' _ > ,  trait_def_id :  DefId )  -> bool  { 
0 commit comments