@@ -20,7 +20,7 @@ use std::borrow::Cow;
2020use std:: iter:: { self } ;
2121use syntax:: ast:: { self } ;
2222use syntax:: symbol:: InternedString ;
23- use syntax_pos:: Span ;
23+ use syntax_pos:: { Span , DUMMY_SP } ;
2424
2525#[ derive( Copy , Clone , Debug , PartialEq , Eq , Hash ) ]
2626pub enum ObjectSafetyViolation {
@@ -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,22 +46,35 @@ 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 ) =>
50- format ! ( "method `{}` has no receiver" , name) . into ( ) ,
51- ObjectSafetyViolation :: Method ( name, MethodViolationCode :: ReferencesSelf ) =>
52- format ! ( "method `{}` references the `Self` type \
53- in its arguments or return type", name) . into ( ) ,
54- ObjectSafetyViolation :: Method ( name,
55- MethodViolationCode :: WhereClauseReferencesSelf ( _) ) =>
56- format ! ( "method `{}` references the `Self` type in where clauses" , name) . into ( ) ,
57- ObjectSafetyViolation :: Method ( name, MethodViolationCode :: Generic ) =>
49+ ObjectSafetyViolation :: Method ( name, MethodViolationCode :: StaticMethod , _) =>
50+ format ! ( "associated function `{}` has no `self` parameter" , name) . into ( ) ,
51+ ObjectSafetyViolation :: Method ( name, MethodViolationCode :: ReferencesSelf , _) => format ! (
52+ "method `{}` references the `Self` type in its parameters or return type" ,
53+ name,
54+ ) . into ( ) ,
55+ ObjectSafetyViolation :: Method (
56+ name,
57+ MethodViolationCode :: WhereClauseReferencesSelf ,
58+ _,
59+ ) => format ! ( "method `{}` references the `Self` type in where clauses" , name) . into ( ) ,
60+ ObjectSafetyViolation :: Method ( name, MethodViolationCode :: Generic , _) =>
5861 format ! ( "method `{}` has generic type parameters" , name) . into ( ) ,
59- ObjectSafetyViolation :: Method ( name, MethodViolationCode :: UndispatchableReceiver ) =>
60- format ! ( "method `{}`'s receiver cannot be dispatched on" , name) . into ( ) ,
61- ObjectSafetyViolation :: AssocConst ( name) =>
62+ ObjectSafetyViolation :: Method ( name, MethodViolationCode :: UndispatchableReceiver , _ ) =>
63+ format ! ( "method `{}`'s `self` parameter cannot be dispatched on" , name) . into ( ) ,
64+ ObjectSafetyViolation :: AssocConst ( name, _ ) =>
6265 format ! ( "the trait cannot contain associated consts like `{}`" , name) . into ( ) ,
6366 }
6467 }
68+
69+ pub fn span ( & self ) -> Option < Span > {
70+ // When `span` comes from a separate crate, it'll be `DUMMY_SP`. Treat it as `None` so
71+ // diagnostics use a `note` instead of a `span_label`.
72+ match * self {
73+ ObjectSafetyViolation :: AssocConst ( _, span) |
74+ ObjectSafetyViolation :: Method ( _, _, span) if span != DUMMY_SP => Some ( span) ,
75+ _ => None ,
76+ }
77+ }
6578}
6679
6780/// Reasons a method might not be object-safe.
@@ -74,7 +87,7 @@ pub enum MethodViolationCode {
7487 ReferencesSelf ,
7588
7689 /// e.g., `fn foo(&self) where Self: Clone`
77- WhereClauseReferencesSelf ( Span ) ,
90+ WhereClauseReferencesSelf ,
7891
7992 /// e.g., `fn foo<A>()`
8093 Generic ,
@@ -88,9 +101,10 @@ impl<'tcx> TyCtxt<'tcx> {
88101 /// astconv -- currently, `Self` in supertraits. This is needed
89102 /// because `object_safety_violations` can't be used during
90103 /// type collection.
91- pub fn astconv_object_safety_violations ( self , trait_def_id : DefId )
92- -> Vec < ObjectSafetyViolation >
93- {
104+ pub fn astconv_object_safety_violations (
105+ self ,
106+ trait_def_id : DefId ,
107+ ) -> Vec < ObjectSafetyViolation > {
94108 debug_assert ! ( self . generics_of( trait_def_id) . has_self) ;
95109 let violations = traits:: supertrait_def_ids ( self , trait_def_id)
96110 . filter ( |& def_id| self . predicates_reference_self ( def_id, true ) )
@@ -128,7 +142,7 @@ impl<'tcx> TyCtxt<'tcx> {
128142 }
129143
130144 match self . virtual_call_violation_for_method ( trait_def_id, method) {
131- None | Some ( MethodViolationCode :: WhereClauseReferencesSelf ( _ ) ) => true ,
145+ None | Some ( MethodViolationCode :: WhereClauseReferencesSelf ) => true ,
132146 Some ( _) => false ,
133147 }
134148 }
@@ -138,12 +152,15 @@ impl<'tcx> TyCtxt<'tcx> {
138152 let mut violations: Vec < _ > = self . associated_items ( trait_def_id)
139153 . filter ( |item| item. kind == ty:: AssocKind :: Method )
140154 . filter_map ( |item|
141- self . object_safety_violation_for_method ( trait_def_id, & item)
142- . map ( |code| ObjectSafetyViolation :: Method ( item. ident . name , code) )
155+ self . object_safety_violation_for_method ( trait_def_id, & item) . map ( |code| {
156+ ObjectSafetyViolation :: Method ( item. ident . name , code, item. ident . span )
157+ } )
143158 ) . filter ( |violation| {
144- if let ObjectSafetyViolation :: Method ( _,
145- MethodViolationCode :: WhereClauseReferencesSelf ( span) ) = violation
146- {
159+ if let ObjectSafetyViolation :: Method (
160+ _,
161+ MethodViolationCode :: WhereClauseReferencesSelf ,
162+ span,
163+ ) = violation {
147164 // Using `CRATE_NODE_ID` is wrong, but it's hard to get a more precise id.
148165 // It's also hard to get a use site span, so we use the method definition span.
149166 self . lint_node_note (
@@ -169,7 +186,7 @@ impl<'tcx> TyCtxt<'tcx> {
169186
170187 violations. extend ( self . associated_items ( trait_def_id)
171188 . filter ( |item| item. kind == ty:: AssocKind :: Const )
172- . map ( |item| ObjectSafetyViolation :: AssocConst ( item. ident . name ) ) ) ;
189+ . map ( |item| ObjectSafetyViolation :: AssocConst ( item. ident . name , item . ident . span ) ) ) ;
173190
174191 debug ! ( "object_safety_violations_for_trait(trait_def_id={:?}) = {:?}" ,
175192 trait_def_id,
@@ -325,8 +342,7 @@ impl<'tcx> TyCtxt<'tcx> {
325342 . visit_tys_shallow ( |t| {
326343 self . contains_illegal_self_type_reference ( trait_def_id, t)
327344 } ) {
328- let span = self . def_span ( method. def_id ) ;
329- return Some ( MethodViolationCode :: WhereClauseReferencesSelf ( span) ) ;
345+ return Some ( MethodViolationCode :: WhereClauseReferencesSelf ) ;
330346 }
331347
332348 let receiver_ty = self . liberate_late_bound_regions (
0 commit comments