@@ -32,10 +32,10 @@ pub enum ObjectSafetyViolation {
3232 SupertraitSelf ,
3333
3434 /// Method has something illegal.
35- Method ( ast:: Name , MethodViolationCode ) ,
35+ Method ( ast:: Name , MethodViolationCode , Span ) ,
3636
3737 /// Associated const.
38- AssocConst ( ast:: Name ) ,
38+ AssocConst ( ast:: Name , Span ) ,
3939}
4040
4141impl ObjectSafetyViolation {
@@ -46,24 +46,33 @@ impl ObjectSafetyViolation {
4646 ObjectSafetyViolation :: SupertraitSelf =>
4747 "the trait cannot use `Self` as a type parameter \
4848 in the supertraits or where-clauses". into ( ) ,
49- ObjectSafetyViolation :: Method ( name, MethodViolationCode :: StaticMethod ) =>
49+ ObjectSafetyViolation :: Method ( name, MethodViolationCode :: StaticMethod , _ ) =>
5050 format ! ( "associated function `{}` has no `self` parameter" , name) . into ( ) ,
51- ObjectSafetyViolation :: Method ( name, MethodViolationCode :: ReferencesSelf ) => format ! (
51+ ObjectSafetyViolation :: Method ( name, MethodViolationCode :: ReferencesSelf , _ ) => format ! (
5252 "method `{}` references the `Self` type in its arguments or return type" ,
5353 name,
5454 ) . into ( ) ,
5555 ObjectSafetyViolation :: Method (
5656 name,
57- MethodViolationCode :: WhereClauseReferencesSelf ( _) ,
57+ MethodViolationCode :: WhereClauseReferencesSelf ,
58+ _,
5859 ) => format ! ( "method `{}` references the `Self` type in where clauses" , name) . into ( ) ,
59- ObjectSafetyViolation :: Method ( name, MethodViolationCode :: Generic ) =>
60+ ObjectSafetyViolation :: Method ( name, MethodViolationCode :: Generic , _ ) =>
6061 format ! ( "method `{}` has generic type parameters" , name) . into ( ) ,
61- ObjectSafetyViolation :: Method ( name, MethodViolationCode :: UndispatchableReceiver ) =>
62+ ObjectSafetyViolation :: Method ( name, MethodViolationCode :: UndispatchableReceiver , _ ) =>
6263 format ! ( "method `{}`'s receiver cannot be dispatched on" , name) . into ( ) ,
63- ObjectSafetyViolation :: AssocConst ( name) =>
64+ ObjectSafetyViolation :: AssocConst ( name, _ ) =>
6465 format ! ( "the trait cannot contain associated consts like `{}`" , name) . into ( ) ,
6566 }
6667 }
68+
69+ pub fn span ( & self ) -> Option < Span > {
70+ match self {
71+ ObjectSafetyViolation :: AssocConst ( _, span) |
72+ ObjectSafetyViolation :: Method ( _, _, span) => Some ( * span) ,
73+ _ => None ,
74+ }
75+ }
6776}
6877
6978/// Reasons a method might not be object-safe.
@@ -76,7 +85,7 @@ pub enum MethodViolationCode {
7685 ReferencesSelf ,
7786
7887 /// e.g., `fn foo(&self) where Self: Clone`
79- WhereClauseReferencesSelf ( Span ) ,
88+ WhereClauseReferencesSelf ,
8089
8190 /// e.g., `fn foo<A>()`
8291 Generic ,
@@ -90,9 +99,10 @@ impl<'tcx> TyCtxt<'tcx> {
9099 /// astconv -- currently, `Self` in supertraits. This is needed
91100 /// because `object_safety_violations` can't be used during
92101 /// type collection.
93- pub fn astconv_object_safety_violations ( self , trait_def_id : DefId )
94- -> Vec < ObjectSafetyViolation >
95- {
102+ pub fn astconv_object_safety_violations (
103+ self ,
104+ trait_def_id : DefId ,
105+ ) -> Vec < ObjectSafetyViolation > {
96106 debug_assert ! ( self . generics_of( trait_def_id) . has_self) ;
97107 let violations = traits:: supertrait_def_ids ( self , trait_def_id)
98108 . filter ( |& def_id| self . predicates_reference_self ( def_id, true ) )
@@ -130,7 +140,7 @@ impl<'tcx> TyCtxt<'tcx> {
130140 }
131141
132142 match self . virtual_call_violation_for_method ( trait_def_id, method) {
133- None | Some ( MethodViolationCode :: WhereClauseReferencesSelf ( _ ) ) => true ,
143+ None | Some ( MethodViolationCode :: WhereClauseReferencesSelf ) => true ,
134144 Some ( _) => false ,
135145 }
136146 }
@@ -140,12 +150,15 @@ impl<'tcx> TyCtxt<'tcx> {
140150 let mut violations: Vec < _ > = self . associated_items ( trait_def_id)
141151 . filter ( |item| item. kind == ty:: AssocKind :: Method )
142152 . filter_map ( |item|
143- self . object_safety_violation_for_method ( trait_def_id, & item)
144- . map ( |code| ObjectSafetyViolation :: Method ( item. ident . name , code) )
153+ self . object_safety_violation_for_method ( trait_def_id, & item) . map ( |code| {
154+ ObjectSafetyViolation :: Method ( item. ident . name , code, item. ident . span )
155+ } )
145156 ) . filter ( |violation| {
146- if let ObjectSafetyViolation :: Method ( _,
147- MethodViolationCode :: WhereClauseReferencesSelf ( span) ) = violation
148- {
157+ if let ObjectSafetyViolation :: Method (
158+ _,
159+ MethodViolationCode :: WhereClauseReferencesSelf ,
160+ span,
161+ ) = violation {
149162 // Using `CRATE_NODE_ID` is wrong, but it's hard to get a more precise id.
150163 // It's also hard to get a use site span, so we use the method definition span.
151164 self . lint_node_note (
@@ -171,7 +184,7 @@ impl<'tcx> TyCtxt<'tcx> {
171184
172185 violations. extend ( self . associated_items ( trait_def_id)
173186 . filter ( |item| item. kind == ty:: AssocKind :: Const )
174- . map ( |item| ObjectSafetyViolation :: AssocConst ( item. ident . name ) ) ) ;
187+ . map ( |item| ObjectSafetyViolation :: AssocConst ( item. ident . name , item . ident . span ) ) ) ;
175188
176189 debug ! ( "object_safety_violations_for_trait(trait_def_id={:?}) = {:?}" ,
177190 trait_def_id,
@@ -327,8 +340,7 @@ impl<'tcx> TyCtxt<'tcx> {
327340 . visit_tys_shallow ( |t| {
328341 self . contains_illegal_self_type_reference ( trait_def_id, t)
329342 } ) {
330- let span = self . def_span ( method. def_id ) ;
331- return Some ( MethodViolationCode :: WhereClauseReferencesSelf ( span) ) ;
343+ return Some ( MethodViolationCode :: WhereClauseReferencesSelf ) ;
332344 }
333345
334346 let receiver_ty = self . liberate_late_bound_regions (
0 commit comments