@@ -97,6 +97,10 @@ fn check_is_object_safe(tcx: TyCtxt<'_>, trait_def_id: DefId) -> bool {
9797/// object. Note that object-safe traits can have some 
9898/// non-vtable-safe methods, so long as they require `Self: Sized` or 
9999/// otherwise ensure that they cannot be used when `Self = Trait`. 
100+ /// 
101+ /// [`MethodViolationCode::WhereClauseReferencesSelf`] is considered object safe due to backwards 
102+ /// compatibility, see <https://github.com/rust-lang/rust/issues/51443> and 
103+ /// [`WHERE_CLAUSES_OBJECT_SAFETY`]. 
100104pub  fn  is_vtable_safe_method ( tcx :  TyCtxt < ' _ > ,  trait_def_id :  DefId ,  method :  ty:: AssocItem )  -> bool  { 
101105    debug_assert ! ( tcx. generics_of( trait_def_id) . has_self) ; 
102106    debug ! ( "is_vtable_safe_method({:?}, {:?})" ,  trait_def_id,  method) ; 
@@ -105,10 +109,9 @@ pub fn is_vtable_safe_method(tcx: TyCtxt<'_>, trait_def_id: DefId, method: ty::A
105109        return  false ; 
106110    } 
107111
108-     match  virtual_call_violation_for_method ( tcx,  trait_def_id,  method)  { 
109-         None  | Some ( MethodViolationCode :: WhereClauseReferencesSelf )  => true , 
110-         Some ( _)  => false , 
111-     } 
112+     virtual_call_violations_for_method ( tcx,  trait_def_id,  method) 
113+         . iter ( ) 
114+         . all ( |v| matches ! ( v,  MethodViolationCode :: WhereClauseReferencesSelf ) ) 
112115} 
113116
114117fn  object_safety_violations_for_trait ( 
@@ -119,7 +122,7 @@ fn object_safety_violations_for_trait(
119122    let  mut  violations:  Vec < _ >  = tcx
120123        . associated_items ( trait_def_id) 
121124        . in_definition_order ( ) 
122-         . filter_map ( |& item| object_safety_violation_for_assoc_item ( tcx,  trait_def_id,  item) ) 
125+         . flat_map ( |& item| object_safety_violations_for_assoc_item ( tcx,  trait_def_id,  item) ) 
123126        . collect ( ) ; 
124127
125128    // Check the trait itself. 
@@ -357,49 +360,52 @@ fn generics_require_sized_self(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
357360
358361/// Returns `Some(_)` if this item makes the containing trait not object safe. 
359362#[ instrument( level = "debug" ,  skip( tcx) ,  ret) ]  
360- fn  object_safety_violation_for_assoc_item ( 
363+ fn  object_safety_violations_for_assoc_item ( 
361364    tcx :  TyCtxt < ' _ > , 
362365    trait_def_id :  DefId , 
363366    item :  ty:: AssocItem , 
364- )  -> Option < ObjectSafetyViolation >  { 
367+ )  -> Vec < ObjectSafetyViolation >  { 
365368    // Any item that has a `Self : Sized` requisite is otherwise 
366369    // exempt from the regulations. 
367370    if  tcx. generics_require_sized_self ( item. def_id )  { 
368-         return  None ; 
371+         return  Vec :: new ( ) ; 
369372    } 
370373
371374    match  item. kind  { 
372375        // Associated consts are never object safe, as they can't have `where` bounds yet at all, 
373376        // and associated const bounds in trait objects aren't a thing yet either. 
374377        ty:: AssocKind :: Const  => { 
375-             Some ( ObjectSafetyViolation :: AssocConst ( item. name ,  item. ident ( tcx) . span ) ) 
378+             vec ! [ ObjectSafetyViolation :: AssocConst ( item. name,  item. ident( tcx) . span) ] 
376379        } 
377-         ty:: AssocKind :: Fn  => virtual_call_violation_for_method ( tcx,  trait_def_id,  item) . map ( |v| { 
378-             let  node = tcx. hir ( ) . get_if_local ( item. def_id ) ; 
379-             // Get an accurate span depending on the violation. 
380-             let  span = match  ( & v,  node)  { 
381-                 ( MethodViolationCode :: ReferencesSelfInput ( Some ( span) ) ,  _)  => * span, 
382-                 ( MethodViolationCode :: UndispatchableReceiver ( Some ( span) ) ,  _)  => * span, 
383-                 ( MethodViolationCode :: ReferencesImplTraitInTrait ( span) ,  _)  => * span, 
384-                 ( MethodViolationCode :: ReferencesSelfOutput ,  Some ( node) )  => { 
385-                     node. fn_decl ( ) . map_or ( item. ident ( tcx) . span ,  |decl| decl. output . span ( ) ) 
386-                 } 
387-                 _ => item. ident ( tcx) . span , 
388-             } ; 
380+         ty:: AssocKind :: Fn  => virtual_call_violations_for_method ( tcx,  trait_def_id,  item) 
381+             . into_iter ( ) 
382+             . map ( |v| { 
383+                 let  node = tcx. hir ( ) . get_if_local ( item. def_id ) ; 
384+                 // Get an accurate span depending on the violation. 
385+                 let  span = match  ( & v,  node)  { 
386+                     ( MethodViolationCode :: ReferencesSelfInput ( Some ( span) ) ,  _)  => * span, 
387+                     ( MethodViolationCode :: UndispatchableReceiver ( Some ( span) ) ,  _)  => * span, 
388+                     ( MethodViolationCode :: ReferencesImplTraitInTrait ( span) ,  _)  => * span, 
389+                     ( MethodViolationCode :: ReferencesSelfOutput ,  Some ( node) )  => { 
390+                         node. fn_decl ( ) . map_or ( item. ident ( tcx) . span ,  |decl| decl. output . span ( ) ) 
391+                     } 
392+                     _ => item. ident ( tcx) . span , 
393+                 } ; 
389394
390-             ObjectSafetyViolation :: Method ( item. name ,  v,  span) 
391-         } ) , 
395+                 ObjectSafetyViolation :: Method ( item. name ,  v,  span) 
396+             } ) 
397+             . collect ( ) , 
392398        // Associated types can only be object safe if they have `Self: Sized` bounds. 
393399        ty:: AssocKind :: Type  => { 
394400            if  !tcx. features ( ) . generic_associated_types_extended 
395401                && !tcx. generics_of ( item. def_id ) . params . is_empty ( ) 
396402                && !item. is_impl_trait_in_trait ( ) 
397403            { 
398-                 Some ( ObjectSafetyViolation :: GAT ( item. name ,  item. ident ( tcx) . span ) ) 
404+                 vec ! [ ObjectSafetyViolation :: GAT ( item. name,  item. ident( tcx) . span) ] 
399405            }  else  { 
400406                // We will permit associated types if they are explicitly mentioned in the trait object. 
401407                // We can't check this here, as here we only check if it is guaranteed to not be possible. 
402-                 None 
408+                 Vec :: new ( ) 
403409            } 
404410        } 
405411    } 
@@ -409,11 +415,11 @@ fn object_safety_violation_for_assoc_item(
409415/// object; this does not necessarily imply that the enclosing trait 
410416/// is not object safe, because the method might have a where clause 
411417/// `Self:Sized`. 
412- fn  virtual_call_violation_for_method < ' tcx > ( 
418+ fn  virtual_call_violations_for_method < ' tcx > ( 
413419    tcx :  TyCtxt < ' tcx > , 
414420    trait_def_id :  DefId , 
415421    method :  ty:: AssocItem , 
416- )  -> Option < MethodViolationCode >  { 
422+ )  -> Vec < MethodViolationCode >  { 
417423    let  sig = tcx. fn_sig ( method. def_id ) . instantiate_identity ( ) ; 
418424
419425    // The method's first parameter must be named `self` 
@@ -438,9 +444,14 @@ fn virtual_call_violation_for_method<'tcx>(
438444        }  else  { 
439445            None 
440446        } ; 
441-         return  Some ( MethodViolationCode :: StaticMethod ( sugg) ) ; 
447+ 
448+         // Not having `self` parameter messes up the later checks, 
449+         // so we need to return instead of pushing 
450+         return  vec ! [ MethodViolationCode :: StaticMethod ( sugg) ] ; 
442451    } 
443452
453+     let  mut  errors = Vec :: new ( ) ; 
454+ 
444455    for  ( i,  & input_ty)  in  sig. skip_binder ( ) . inputs ( ) . iter ( ) . enumerate ( ) . skip ( 1 )  { 
445456        if  contains_illegal_self_type_reference ( tcx,  trait_def_id,  sig. rebind ( input_ty) )  { 
446457            let  span = if  let  Some ( hir:: Node :: TraitItem ( hir:: TraitItem  { 
@@ -452,20 +463,20 @@ fn virtual_call_violation_for_method<'tcx>(
452463            }  else  { 
453464                None 
454465            } ; 
455-             return   Some ( MethodViolationCode :: ReferencesSelfInput ( span) ) ; 
466+             errors . push ( MethodViolationCode :: ReferencesSelfInput ( span) ) ; 
456467        } 
457468    } 
458469    if  contains_illegal_self_type_reference ( tcx,  trait_def_id,  sig. output ( ) )  { 
459-         return   Some ( MethodViolationCode :: ReferencesSelfOutput ) ; 
470+         errors . push ( MethodViolationCode :: ReferencesSelfOutput ) ; 
460471    } 
461472    if  let  Some ( code)  = contains_illegal_impl_trait_in_trait ( tcx,  method. def_id ,  sig. output ( ) )  { 
462-         return   Some ( code) ; 
473+         errors . push ( code) ; 
463474    } 
464475
465476    // We can't monomorphize things like `fn foo<A>(...)`. 
466477    let  own_counts = tcx. generics_of ( method. def_id ) . own_counts ( ) ; 
467-     if  own_counts. types  +  own_counts. consts  !=  0  { 
468-         return   Some ( MethodViolationCode :: Generic ) ; 
478+     if  own_counts. types  >  0  ||  own_counts. consts  >  0  { 
479+         errors . push ( MethodViolationCode :: Generic ) ; 
469480    } 
470481
471482    let  receiver_ty = tcx. liberate_late_bound_regions ( method. def_id ,  sig. input ( 0 ) ) ; 
@@ -485,7 +496,7 @@ fn virtual_call_violation_for_method<'tcx>(
485496            }  else  { 
486497                None 
487498            } ; 
488-             return   Some ( MethodViolationCode :: UndispatchableReceiver ( span) ) ; 
499+             errors . push ( MethodViolationCode :: UndispatchableReceiver ( span) ) ; 
489500        }  else  { 
490501            // Do sanity check to make sure the receiver actually has the layout of a pointer. 
491502
@@ -593,10 +604,10 @@ fn virtual_call_violation_for_method<'tcx>(
593604
594605        contains_illegal_self_type_reference ( tcx,  trait_def_id,  pred) 
595606    } )  { 
596-         return   Some ( MethodViolationCode :: WhereClauseReferencesSelf ) ; 
607+         errors . push ( MethodViolationCode :: WhereClauseReferencesSelf ) ; 
597608    } 
598609
599-     None 
610+     errors 
600611} 
601612
602613/// Performs a type substitution to produce the version of `receiver_ty` when `Self = self_ty`. 
@@ -709,7 +720,6 @@ fn object_ty_for_trait<'tcx>(
709720// FIXME(mikeyhew) when unsized receivers are implemented as part of unsized rvalues, add this 
710721// fallback query: `Receiver: Unsize<Receiver[Self => U]>` to support receivers like 
711722// `self: Wrapper<Self>`. 
712- #[ allow( dead_code) ]  
713723fn  receiver_is_dispatchable < ' tcx > ( 
714724    tcx :  TyCtxt < ' tcx > , 
715725    method :  ty:: AssocItem , 
0 commit comments