@@ -20,7 +20,7 @@ use std::borrow::Cow;
20
20
use std:: iter:: { self } ;
21
21
use syntax:: ast:: { self } ;
22
22
use syntax:: symbol:: InternedString ;
23
- use syntax_pos:: Span ;
23
+ use syntax_pos:: { Span , DUMMY_SP } ;
24
24
25
25
#[ derive( Copy , Clone , Debug , PartialEq , Eq , Hash ) ]
26
26
pub enum ObjectSafetyViolation {
@@ -32,10 +32,10 @@ pub enum ObjectSafetyViolation {
32
32
SupertraitSelf ,
33
33
34
34
/// Method has something illegal.
35
- Method ( ast:: Name , MethodViolationCode ) ,
35
+ Method ( ast:: Name , MethodViolationCode , Span ) ,
36
36
37
37
/// Associated const.
38
- AssocConst ( ast:: Name ) ,
38
+ AssocConst ( ast:: Name , Span ) ,
39
39
}
40
40
41
41
impl ObjectSafetyViolation {
@@ -46,22 +46,35 @@ impl ObjectSafetyViolation {
46
46
ObjectSafetyViolation :: SupertraitSelf =>
47
47
"the trait cannot use `Self` as a type parameter \
48
48
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 , _) =>
58
61
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, _ ) =>
62
65
format ! ( "the trait cannot contain associated consts like `{}`" , name) . into ( ) ,
63
66
}
64
67
}
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
+ }
65
78
}
66
79
67
80
/// Reasons a method might not be object-safe.
@@ -74,7 +87,7 @@ pub enum MethodViolationCode {
74
87
ReferencesSelf ,
75
88
76
89
/// e.g., `fn foo(&self) where Self: Clone`
77
- WhereClauseReferencesSelf ( Span ) ,
90
+ WhereClauseReferencesSelf ,
78
91
79
92
/// e.g., `fn foo<A>()`
80
93
Generic ,
@@ -88,9 +101,10 @@ impl<'tcx> TyCtxt<'tcx> {
88
101
/// astconv -- currently, `Self` in supertraits. This is needed
89
102
/// because `object_safety_violations` can't be used during
90
103
/// 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 > {
94
108
debug_assert ! ( self . generics_of( trait_def_id) . has_self) ;
95
109
let violations = traits:: supertrait_def_ids ( self , trait_def_id)
96
110
. filter ( |& def_id| self . predicates_reference_self ( def_id, true ) )
@@ -128,7 +142,7 @@ impl<'tcx> TyCtxt<'tcx> {
128
142
}
129
143
130
144
match self . virtual_call_violation_for_method ( trait_def_id, method) {
131
- None | Some ( MethodViolationCode :: WhereClauseReferencesSelf ( _ ) ) => true ,
145
+ None | Some ( MethodViolationCode :: WhereClauseReferencesSelf ) => true ,
132
146
Some ( _) => false ,
133
147
}
134
148
}
@@ -138,12 +152,15 @@ impl<'tcx> TyCtxt<'tcx> {
138
152
let mut violations: Vec < _ > = self . associated_items ( trait_def_id)
139
153
. filter ( |item| item. kind == ty:: AssocKind :: Method )
140
154
. 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
+ } )
143
158
) . 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 {
147
164
// Using `CRATE_NODE_ID` is wrong, but it's hard to get a more precise id.
148
165
// It's also hard to get a use site span, so we use the method definition span.
149
166
self . lint_node_note (
@@ -169,7 +186,7 @@ impl<'tcx> TyCtxt<'tcx> {
169
186
170
187
violations. extend ( self . associated_items ( trait_def_id)
171
188
. 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 ) ) ) ;
173
190
174
191
debug ! ( "object_safety_violations_for_trait(trait_def_id={:?}) = {:?}" ,
175
192
trait_def_id,
@@ -325,8 +342,7 @@ impl<'tcx> TyCtxt<'tcx> {
325
342
. visit_tys_shallow ( |t| {
326
343
self . contains_illegal_self_type_reference ( trait_def_id, t)
327
344
} ) {
328
- let span = self . def_span ( method. def_id ) ;
329
- return Some ( MethodViolationCode :: WhereClauseReferencesSelf ( span) ) ;
345
+ return Some ( MethodViolationCode :: WhereClauseReferencesSelf ) ;
330
346
}
331
347
332
348
let receiver_ty = self . liberate_late_bound_regions (
0 commit comments