@@ -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,24 +46,33 @@ 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 ) =>
49
+ ObjectSafetyViolation :: Method ( name, MethodViolationCode :: StaticMethod , _ ) =>
50
50
format ! ( "associated function `{}` has no `self` parameter" , name) . into ( ) ,
51
- ObjectSafetyViolation :: Method ( name, MethodViolationCode :: ReferencesSelf ) => format ! (
51
+ ObjectSafetyViolation :: Method ( name, MethodViolationCode :: ReferencesSelf , _ ) => format ! (
52
52
"method `{}` references the `Self` type in its arguments or return type" ,
53
53
name,
54
54
) . into ( ) ,
55
55
ObjectSafetyViolation :: Method (
56
56
name,
57
- MethodViolationCode :: WhereClauseReferencesSelf ( _) ,
57
+ MethodViolationCode :: WhereClauseReferencesSelf ,
58
+ _,
58
59
) => format ! ( "method `{}` references the `Self` type in where clauses" , name) . into ( ) ,
59
- ObjectSafetyViolation :: Method ( name, MethodViolationCode :: Generic ) =>
60
+ ObjectSafetyViolation :: Method ( name, MethodViolationCode :: Generic , _ ) =>
60
61
format ! ( "method `{}` has generic type parameters" , name) . into ( ) ,
61
- ObjectSafetyViolation :: Method ( name, MethodViolationCode :: UndispatchableReceiver ) =>
62
+ ObjectSafetyViolation :: Method ( name, MethodViolationCode :: UndispatchableReceiver , _ ) =>
62
63
format ! ( "method `{}`'s receiver cannot be dispatched on" , name) . into ( ) ,
63
- ObjectSafetyViolation :: AssocConst ( name) =>
64
+ ObjectSafetyViolation :: AssocConst ( name, _ ) =>
64
65
format ! ( "the trait cannot contain associated consts like `{}`" , name) . into ( ) ,
65
66
}
66
67
}
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
+ }
67
76
}
68
77
69
78
/// Reasons a method might not be object-safe.
@@ -76,7 +85,7 @@ pub enum MethodViolationCode {
76
85
ReferencesSelf ,
77
86
78
87
/// e.g., `fn foo(&self) where Self: Clone`
79
- WhereClauseReferencesSelf ( Span ) ,
88
+ WhereClauseReferencesSelf ,
80
89
81
90
/// e.g., `fn foo<A>()`
82
91
Generic ,
@@ -90,9 +99,10 @@ impl<'tcx> TyCtxt<'tcx> {
90
99
/// astconv -- currently, `Self` in supertraits. This is needed
91
100
/// because `object_safety_violations` can't be used during
92
101
/// 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 > {
96
106
debug_assert ! ( self . generics_of( trait_def_id) . has_self) ;
97
107
let violations = traits:: supertrait_def_ids ( self , trait_def_id)
98
108
. filter ( |& def_id| self . predicates_reference_self ( def_id, true ) )
@@ -130,7 +140,7 @@ impl<'tcx> TyCtxt<'tcx> {
130
140
}
131
141
132
142
match self . virtual_call_violation_for_method ( trait_def_id, method) {
133
- None | Some ( MethodViolationCode :: WhereClauseReferencesSelf ( _ ) ) => true ,
143
+ None | Some ( MethodViolationCode :: WhereClauseReferencesSelf ) => true ,
134
144
Some ( _) => false ,
135
145
}
136
146
}
@@ -140,12 +150,15 @@ impl<'tcx> TyCtxt<'tcx> {
140
150
let mut violations: Vec < _ > = self . associated_items ( trait_def_id)
141
151
. filter ( |item| item. kind == ty:: AssocKind :: Method )
142
152
. 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
+ } )
145
156
) . 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 {
149
162
// Using `CRATE_NODE_ID` is wrong, but it's hard to get a more precise id.
150
163
// It's also hard to get a use site span, so we use the method definition span.
151
164
self . lint_node_note (
@@ -171,7 +184,7 @@ impl<'tcx> TyCtxt<'tcx> {
171
184
172
185
violations. extend ( self . associated_items ( trait_def_id)
173
186
. 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 ) ) ) ;
175
188
176
189
debug ! ( "object_safety_violations_for_trait(trait_def_id={:?}) = {:?}" ,
177
190
trait_def_id,
@@ -327,8 +340,7 @@ impl<'tcx> TyCtxt<'tcx> {
327
340
. visit_tys_shallow ( |t| {
328
341
self . contains_illegal_self_type_reference ( trait_def_id, t)
329
342
} ) {
330
- let span = self . def_span ( method. def_id ) ;
331
- return Some ( MethodViolationCode :: WhereClauseReferencesSelf ( span) ) ;
343
+ return Some ( MethodViolationCode :: WhereClauseReferencesSelf ) ;
332
344
}
333
345
334
346
let receiver_ty = self . liberate_late_bound_regions (
0 commit comments