@@ -22,11 +22,10 @@ use super::elaborate_predicates;
22
22
use hir:: def_id:: DefId ;
23
23
use traits;
24
24
use ty:: { self , ToPolyTraitRef , Ty , TyCtxt , TypeFoldable } ;
25
- use std:: rc:: Rc ;
26
25
use syntax:: ast;
27
26
28
27
#[ derive( Clone , Debug , PartialEq , Eq , Hash ) ]
29
- pub enum ObjectSafetyViolation < ' tcx > {
28
+ pub enum ObjectSafetyViolation {
30
29
/// Self : Sized declared on the trait
31
30
SizedSelf ,
32
31
@@ -35,7 +34,7 @@ pub enum ObjectSafetyViolation<'tcx> {
35
34
SupertraitSelf ,
36
35
37
36
/// Method has something illegal
38
- Method ( Rc < ty :: Method < ' tcx > > , MethodViolationCode ) ,
37
+ Method ( ast :: Name , MethodViolationCode ) ,
39
38
}
40
39
41
40
/// Reasons a method might not be object-safe.
@@ -77,7 +76,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
77
76
/// because `object_safety_violations` can't be used during
78
77
/// type collection.
79
78
pub fn astconv_object_safety_violations ( self , trait_def_id : DefId )
80
- -> Vec < ObjectSafetyViolation < ' tcx > >
79
+ -> Vec < ObjectSafetyViolation >
81
80
{
82
81
let mut violations = vec ! [ ] ;
83
82
@@ -93,29 +92,23 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
93
92
}
94
93
95
94
pub fn object_safety_violations ( self , trait_def_id : DefId )
96
- -> Vec < ObjectSafetyViolation < ' tcx > >
95
+ -> Vec < ObjectSafetyViolation >
97
96
{
98
97
traits:: supertrait_def_ids ( self , trait_def_id)
99
98
. flat_map ( |def_id| self . object_safety_violations_for_trait ( def_id) )
100
99
. collect ( )
101
100
}
102
101
103
102
fn object_safety_violations_for_trait ( self , trait_def_id : DefId )
104
- -> Vec < ObjectSafetyViolation < ' tcx > >
103
+ -> Vec < ObjectSafetyViolation >
105
104
{
106
105
// Check methods for violations.
107
- let mut violations: Vec < _ > =
108
- self . trait_items ( trait_def_id ) . iter ( )
106
+ let mut violations: Vec < _ > = self . associated_items ( trait_def_id )
107
+ . filter ( |item| item . kind == ty :: AssociatedKind :: Method )
109
108
. filter_map ( |item| {
110
- match * item {
111
- ty:: MethodTraitItem ( ref m) => {
112
- self . object_safety_violation_for_method ( trait_def_id, & m)
113
- . map ( |code| ObjectSafetyViolation :: Method ( m. clone ( ) , code) )
114
- }
115
- _ => None ,
116
- }
117
- } )
118
- . collect ( ) ;
109
+ self . object_safety_violation_for_method ( trait_def_id, & item)
110
+ . map ( |code| ObjectSafetyViolation :: Method ( item. name , code) )
111
+ } ) . collect ( ) ;
119
112
120
113
// Check the trait itself.
121
114
if self . trait_has_sized_self ( trait_def_id) {
@@ -198,7 +191,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
198
191
/// Returns `Some(_)` if this method makes the containing trait not object safe.
199
192
fn object_safety_violation_for_method ( self ,
200
193
trait_def_id : DefId ,
201
- method : & ty:: Method < ' gcx > )
194
+ method : & ty:: AssociatedItem )
202
195
-> Option < MethodViolationCode >
203
196
{
204
197
// Any method that has a `Self : Sized` requisite is otherwise
@@ -216,7 +209,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
216
209
/// otherwise ensure that they cannot be used when `Self=Trait`.
217
210
pub fn is_vtable_safe_method ( self ,
218
211
trait_def_id : DefId ,
219
- method : & ty:: Method < ' gcx > )
212
+ method : & ty:: AssociatedItem )
220
213
-> bool
221
214
{
222
215
// Any method that has a `Self : Sized` requisite can't be called.
@@ -233,26 +226,19 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
233
226
/// `Self:Sized`.
234
227
fn virtual_call_violation_for_method ( self ,
235
228
trait_def_id : DefId ,
236
- method : & ty:: Method < ' tcx > )
229
+ method : & ty:: AssociatedItem )
237
230
-> Option < MethodViolationCode >
238
231
{
239
232
// The method's first parameter must be something that derefs (or
240
233
// autorefs) to `&self`. For now, we only accept `self`, `&self`
241
234
// and `Box<Self>`.
242
- match method. explicit_self {
243
- ty:: ExplicitSelfCategory :: Static => {
244
- return Some ( MethodViolationCode :: StaticMethod ) ;
245
- }
246
-
247
- ty:: ExplicitSelfCategory :: ByValue |
248
- ty:: ExplicitSelfCategory :: ByReference ( ..) |
249
- ty:: ExplicitSelfCategory :: ByBox => {
250
- }
235
+ if !method. method_has_self_argument {
236
+ return Some ( MethodViolationCode :: StaticMethod ) ;
251
237
}
252
238
253
239
// The `Self` type is erased, so it should not appear in list of
254
240
// arguments or return type apart from the receiver.
255
- let ref sig = method. fty . sig ;
241
+ let ref sig = self . lookup_item_type ( method. def_id ) . ty . fn_sig ( ) ;
256
242
for & input_ty in & sig. 0 . inputs [ 1 ..] {
257
243
if self . contains_illegal_self_type_reference ( trait_def_id, input_ty) {
258
244
return Some ( MethodViolationCode :: ReferencesSelf ) ;
@@ -263,7 +249,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
263
249
}
264
250
265
251
// We can't monomorphize things like `fn foo<A>(...)`.
266
- if !method. generics . types . is_empty ( ) {
252
+ if !self . lookup_generics ( method. def_id ) . types . is_empty ( ) {
267
253
return Some ( MethodViolationCode :: Generic ) ;
268
254
}
269
255
0 commit comments