@@ -42,9 +42,6 @@ pub enum ObjectSafetyViolation<'tcx> {
4242/// Reasons a method might not be object-safe.
4343#[ derive( Copy , Clone , Debug ) ]
4444pub enum MethodViolationCode {
45- /// e.g., `fn(self)`
46- ByValueSelf ,
47-
4845 /// e.g., `fn foo()`
4946 StaticMethod ,
5047
@@ -157,19 +154,25 @@ fn supertraits_reference_self<'tcx>(tcx: &ty::ctxt<'tcx>,
157154fn trait_has_sized_self < ' tcx > ( tcx : & ty:: ctxt < ' tcx > ,
158155 trait_def_id : ast:: DefId )
159156 -> 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
160167{
161168 let sized_def_id = match tcx. lang_items . sized_trait ( ) {
162169 Some ( def_id) => def_id,
163170 None => { return false ; /* No Sized trait, can't require it! */ }
164171 } ;
165172
166173 // 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 ( ) ;
173176 elaborate_predicates ( tcx, predicates)
174177 . any ( |predicate| {
175178 match predicate {
@@ -192,17 +195,21 @@ fn object_safety_violations_for_method<'tcx>(tcx: &ty::ctxt<'tcx>,
192195 method : & ty:: Method < ' tcx > )
193196 -> Option < MethodViolationCode >
194197{
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+ }
201203
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 {
202208 ty:: StaticExplicitSelfCategory => {
203209 return Some ( MethodViolationCode :: StaticMethod ) ;
204210 }
205211
212+ ty:: ByValueExplicitSelfCategory |
206213 ty:: ByReferenceExplicitSelfCategory ( ..) |
207214 ty:: ByBoxExplicitSelfCategory => {
208215 }
0 commit comments