@@ -91,6 +91,7 @@ impl<'tcx> TyCtxt<'tcx> {
9191 pub fn astconv_object_safety_violations ( self , trait_def_id : DefId )
9292 -> Vec < ObjectSafetyViolation >
9393 {
94+ debug_assert ! ( self . generics_of( trait_def_id) . has_self) ;
9495 let violations = traits:: supertrait_def_ids ( self , trait_def_id)
9596 . filter ( |& def_id| self . predicates_reference_self ( def_id, true ) )
9697 . map ( |_| ObjectSafetyViolation :: SupertraitSelf )
@@ -106,16 +107,33 @@ impl<'tcx> TyCtxt<'tcx> {
106107 pub fn object_safety_violations ( self , trait_def_id : DefId )
107108 -> Vec < ObjectSafetyViolation >
108109 {
110+ debug_assert ! ( self . generics_of( trait_def_id) . has_self) ;
109111 debug ! ( "object_safety_violations: {:?}" , trait_def_id) ;
110112
111113 traits:: supertrait_def_ids ( self , trait_def_id)
112114 . flat_map ( |def_id| self . object_safety_violations_for_trait ( def_id) )
113115 . collect ( )
114116 }
115117
116- fn object_safety_violations_for_trait ( self , trait_def_id : DefId )
117- -> Vec < ObjectSafetyViolation >
118- {
118+ /// We say a method is *vtable safe* if it can be invoked on a trait
119+ /// object. Note that object-safe traits can have some
120+ /// non-vtable-safe methods, so long as they require `Self:Sized` or
121+ /// otherwise ensure that they cannot be used when `Self=Trait`.
122+ pub fn is_vtable_safe_method ( self , trait_def_id : DefId , method : & ty:: AssocItem ) -> bool {
123+ debug_assert ! ( self . generics_of( trait_def_id) . has_self) ;
124+ debug ! ( "is_vtable_safe_method({:?}, {:?})" , trait_def_id, method) ;
125+ // Any method that has a `Self : Sized` requisite can't be called.
126+ if self . generics_require_sized_self ( method. def_id ) {
127+ return false ;
128+ }
129+
130+ match self . virtual_call_violation_for_method ( trait_def_id, method) {
131+ None | Some ( MethodViolationCode :: WhereClauseReferencesSelf ( _) ) => true ,
132+ Some ( _) => false ,
133+ }
134+ }
135+
136+ fn object_safety_violations_for_trait ( self , trait_def_id : DefId ) -> Vec < ObjectSafetyViolation > {
119137 // Check methods for violations.
120138 let mut violations: Vec < _ > = self . associated_items ( trait_def_id)
121139 . filter ( |item| item. kind == ty:: AssocKind :: Method )
@@ -163,14 +181,16 @@ impl<'tcx> TyCtxt<'tcx> {
163181 fn predicates_reference_self (
164182 self ,
165183 trait_def_id : DefId ,
166- supertraits_only : bool ) -> bool
167- {
184+ supertraits_only : bool ,
185+ ) -> bool {
168186 let trait_ref = ty:: Binder :: dummy ( ty:: TraitRef :: identity ( self , trait_def_id) ) ;
169187 let predicates = if supertraits_only {
170188 self . super_predicates_of ( trait_def_id)
171189 } else {
172190 self . predicates_of ( trait_def_id)
173191 } ;
192+ let self_ty = self . types . self_param ;
193+ let has_self_ty = |t : Ty < ' tcx > | t. walk ( ) . any ( |t| t == self_ty) ;
174194 predicates
175195 . predicates
176196 . iter ( )
@@ -179,7 +199,7 @@ impl<'tcx> TyCtxt<'tcx> {
179199 match predicate {
180200 ty:: Predicate :: Trait ( ref data) => {
181201 // In the case of a trait predicate, we can skip the "self" type.
182- data. skip_binder ( ) . input_types ( ) . skip ( 1 ) . any ( |t| t . has_self_ty ( ) )
202+ data. skip_binder ( ) . input_types ( ) . skip ( 1 ) . any ( has_self_ty)
183203 }
184204 ty:: Predicate :: Projection ( ref data) => {
185205 // And similarly for projections. This should be redundant with
@@ -199,7 +219,7 @@ impl<'tcx> TyCtxt<'tcx> {
199219 . trait_ref ( self )
200220 . input_types ( )
201221 . skip ( 1 )
202- . any ( |t| t . has_self_ty ( ) )
222+ . any ( has_self_ty)
203223 }
204224 ty:: Predicate :: WellFormed ( ..) |
205225 ty:: Predicate :: ObjectSafe ( ..) |
@@ -229,11 +249,11 @@ impl<'tcx> TyCtxt<'tcx> {
229249 let predicates = predicates. instantiate_identity ( self ) . predicates ;
230250 elaborate_predicates ( self , predicates)
231251 . any ( |predicate| match predicate {
232- ty:: Predicate :: Trait ( ref trait_pred) if trait_pred. def_id ( ) == sized_def_id => {
233- trait_pred. skip_binder ( ) . self_ty ( ) . is_self ( )
252+ ty:: Predicate :: Trait ( ref trait_pred) => {
253+ trait_pred. def_id ( ) == sized_def_id
254+ && trait_pred. skip_binder ( ) . self_ty ( ) . is_param ( 0 )
234255 }
235256 ty:: Predicate :: Projection ( ..) |
236- ty:: Predicate :: Trait ( ..) |
237257 ty:: Predicate :: Subtype ( ..) |
238258 ty:: Predicate :: RegionOutlives ( ..) |
239259 ty:: Predicate :: WellFormed ( ..) |
@@ -248,11 +268,11 @@ impl<'tcx> TyCtxt<'tcx> {
248268 }
249269
250270 /// Returns `Some(_)` if this method makes the containing trait not object safe.
251- fn object_safety_violation_for_method ( self ,
252- trait_def_id : DefId ,
253- method : & ty :: AssocItem )
254- -> Option < MethodViolationCode >
255- {
271+ fn object_safety_violation_for_method (
272+ self ,
273+ trait_def_id : DefId ,
274+ method : & ty :: AssocItem ,
275+ ) -> Option < MethodViolationCode > {
256276 debug ! ( "object_safety_violation_for_method({:?}, {:?})" , trait_def_id, method) ;
257277 // Any method that has a `Self : Sized` requisite is otherwise
258278 // exempt from the regulations.
@@ -263,36 +283,15 @@ impl<'tcx> TyCtxt<'tcx> {
263283 self . virtual_call_violation_for_method ( trait_def_id, method)
264284 }
265285
266- /// We say a method is *vtable safe* if it can be invoked on a trait
267- /// object. Note that object-safe traits can have some
268- /// non-vtable-safe methods, so long as they require `Self:Sized` or
269- /// otherwise ensure that they cannot be used when `Self=Trait`.
270- pub fn is_vtable_safe_method ( self ,
271- trait_def_id : DefId ,
272- method : & ty:: AssocItem )
273- -> bool
274- {
275- debug ! ( "is_vtable_safe_method({:?}, {:?})" , trait_def_id, method) ;
276- // Any method that has a `Self : Sized` requisite can't be called.
277- if self . generics_require_sized_self ( method. def_id ) {
278- return false ;
279- }
280-
281- match self . virtual_call_violation_for_method ( trait_def_id, method) {
282- None | Some ( MethodViolationCode :: WhereClauseReferencesSelf ( _) ) => true ,
283- Some ( _) => false ,
284- }
285- }
286-
287286 /// Returns `Some(_)` if this method cannot be called on a trait
288287 /// object; this does not necessarily imply that the enclosing trait
289288 /// is not object safe, because the method might have a where clause
290289 /// `Self:Sized`.
291- fn virtual_call_violation_for_method ( self ,
292- trait_def_id : DefId ,
293- method : & ty :: AssocItem )
294- -> Option < MethodViolationCode >
295- {
290+ fn virtual_call_violation_for_method (
291+ self ,
292+ trait_def_id : DefId ,
293+ method : & ty :: AssocItem ,
294+ ) -> Option < MethodViolationCode > {
296295 // The method's first parameter must be named `self`
297296 if !method. method_has_self_argument {
298297 return Some ( MethodViolationCode :: StaticMethod ) ;
@@ -323,7 +322,9 @@ impl<'tcx> TyCtxt<'tcx> {
323322 . collect :: < Vec < _ > > ( )
324323 // Do a shallow visit so that `contains_illegal_self_type_reference`
325324 // may apply it's custom visiting.
326- . visit_tys_shallow ( |t| self . contains_illegal_self_type_reference ( trait_def_id, t) ) {
325+ . visit_tys_shallow ( |t| {
326+ self . contains_illegal_self_type_reference ( trait_def_id, t)
327+ } ) {
327328 let span = self . def_span ( method. def_id ) ;
328329 return Some ( MethodViolationCode :: WhereClauseReferencesSelf ( span) ) ;
329330 }
@@ -337,7 +338,7 @@ impl<'tcx> TyCtxt<'tcx> {
337338 // However, this is already considered object-safe. We allow it as a special case here.
338339 // FIXME(mikeyhew) get rid of this `if` statement once `receiver_is_dispatchable` allows
339340 // `Receiver: Unsize<Receiver[Self => dyn Trait]>`
340- if receiver_ty != self . mk_self_type ( ) {
341+ if receiver_ty != self . types . self_param {
341342 if !self . receiver_is_dispatchable ( method, receiver_ty) {
342343 return Some ( MethodViolationCode :: UndispatchableReceiver ) ;
343344 } else {
@@ -404,7 +405,10 @@ impl<'tcx> TyCtxt<'tcx> {
404405 /// Performs a type substitution to produce the version of receiver_ty when `Self = self_ty`
405406 /// e.g., for receiver_ty = `Rc<Self>` and self_ty = `Foo`, returns `Rc<Foo>`.
406407 fn receiver_for_self_ty (
407- self , receiver_ty : Ty < ' tcx > , self_ty : Ty < ' tcx > , method_def_id : DefId
408+ self ,
409+ receiver_ty : Ty < ' tcx > ,
410+ self_ty : Ty < ' tcx > ,
411+ method_def_id : DefId ,
408412 ) -> Ty < ' tcx > {
409413 debug ! ( "receiver_for_self_ty({:?}, {:?}, {:?})" , receiver_ty, self_ty, method_def_id) ;
410414 let substs = InternalSubsts :: for_item ( self , method_def_id, |param, _| {
@@ -555,7 +559,7 @@ impl<'tcx> TyCtxt<'tcx> {
555559 // Self: Unsize<U>
556560 let unsize_predicate = ty:: TraitRef {
557561 def_id : unsize_did,
558- substs : self . mk_substs_trait ( self . mk_self_type ( ) , & [ unsized_self_ty. into ( ) ] ) ,
562+ substs : self . mk_substs_trait ( self . types . self_param , & [ unsized_self_ty. into ( ) ] ) ,
559563 } . to_predicate ( ) ;
560564
561565 // U: Trait<Arg1, ..., ArgN>
@@ -608,11 +612,11 @@ impl<'tcx> TyCtxt<'tcx> {
608612 } )
609613 }
610614
611- fn contains_illegal_self_type_reference ( self ,
612- trait_def_id : DefId ,
613- ty : Ty < ' tcx > )
614- -> bool
615- {
615+ fn contains_illegal_self_type_reference (
616+ self ,
617+ trait_def_id : DefId ,
618+ ty : Ty < ' tcx > ,
619+ ) -> bool {
616620 // This is somewhat subtle. In general, we want to forbid
617621 // references to `Self` in the argument and return types,
618622 // since the value of `Self` is erased. However, there is one
@@ -654,10 +658,11 @@ impl<'tcx> TyCtxt<'tcx> {
654658
655659 let mut supertraits: Option < Vec < ty:: PolyTraitRef < ' tcx > > > = None ;
656660 let mut error = false ;
661+ let self_ty = self . types . self_param ;
657662 ty. maybe_walk ( |ty| {
658663 match ty. sty {
659- ty:: Param ( ref param_ty ) => {
660- if param_ty . is_self ( ) {
664+ ty:: Param ( _ ) => {
665+ if ty == self_ty {
661666 error = true ;
662667 }
663668
0 commit comments