@@ -42,9 +42,6 @@ pub enum ObjectSafetyViolation<'tcx> {
42
42
/// Reasons a method might not be object-safe.
43
43
#[ derive( Copy , Clone , Debug ) ]
44
44
pub enum MethodViolationCode {
45
- /// e.g., `fn(self)`
46
- ByValueSelf ,
47
-
48
45
/// e.g., `fn foo()`
49
46
StaticMethod ,
50
47
@@ -157,19 +154,25 @@ fn supertraits_reference_self<'tcx>(tcx: &ty::ctxt<'tcx>,
157
154
fn trait_has_sized_self < ' tcx > ( tcx : & ty:: ctxt < ' tcx > ,
158
155
trait_def_id : ast:: DefId )
159
156
-> bool
157
+ {
158
+ let trait_def = ty:: lookup_trait_def ( tcx, trait_def_id) ;
159
+ let trait_predicates = ty:: lookup_predicates ( tcx, trait_def_id) ;
160
+ generics_require_sized_self ( tcx, & trait_def. generics , & trait_predicates)
161
+ }
162
+
163
+ fn generics_require_sized_self < ' tcx > ( tcx : & ty:: ctxt < ' tcx > ,
164
+ generics : & ty:: Generics < ' tcx > ,
165
+ predicates : & ty:: GenericPredicates < ' tcx > )
166
+ -> bool
160
167
{
161
168
let sized_def_id = match tcx. lang_items . sized_trait ( ) {
162
169
Some ( def_id) => def_id,
163
170
None => { return false ; /* No Sized trait, can't require it! */ }
164
171
} ;
165
172
166
173
// Search for a predicate like `Self : Sized` amongst the trait bounds.
167
- let trait_def = ty:: lookup_trait_def ( tcx, trait_def_id) ;
168
- let free_substs = ty:: construct_free_substs ( tcx, & trait_def. generics , ast:: DUMMY_NODE_ID ) ;
169
-
170
- let trait_predicates = ty:: lookup_predicates ( tcx, trait_def_id) ;
171
- let predicates = trait_predicates. instantiate ( tcx, & free_substs) . predicates . into_vec ( ) ;
172
-
174
+ let free_substs = ty:: construct_free_substs ( tcx, generics, ast:: DUMMY_NODE_ID ) ;
175
+ let predicates = predicates. instantiate ( tcx, & free_substs) . predicates . into_vec ( ) ;
173
176
elaborate_predicates ( tcx, predicates)
174
177
. any ( |predicate| {
175
178
match predicate {
@@ -192,17 +195,21 @@ fn object_safety_violations_for_method<'tcx>(tcx: &ty::ctxt<'tcx>,
192
195
method : & ty:: Method < ' tcx > )
193
196
-> Option < MethodViolationCode >
194
197
{
195
- // The method's first parameter must be something that derefs to
196
- // `&self`. For now, we only accept `&self` and `Box<Self>`.
197
- match method. explicit_self {
198
- ty:: ByValueExplicitSelfCategory => {
199
- return Some ( MethodViolationCode :: ByValueSelf ) ;
200
- }
198
+ // Any method that has a `Self : Sized` requisite is otherwise
199
+ // exempt from the regulations.
200
+ if generics_require_sized_self ( tcx, & method. generics , & method. predicates ) {
201
+ return None ;
202
+ }
201
203
204
+ // The method's first parameter must be something that derefs (or
205
+ // autorefs) to `&self`. For now, we only accept `self`, `&self`
206
+ // and `Box<Self>`.
207
+ match method. explicit_self {
202
208
ty:: StaticExplicitSelfCategory => {
203
209
return Some ( MethodViolationCode :: StaticMethod ) ;
204
210
}
205
211
212
+ ty:: ByValueExplicitSelfCategory |
206
213
ty:: ByReferenceExplicitSelfCategory ( ..) |
207
214
ty:: ByBoxExplicitSelfCategory => {
208
215
}
0 commit comments