@@ -109,10 +109,9 @@ pub fn is_vtable_safe_method(tcx: TyCtxt<'_>, trait_def_id: DefId, method: ty::A
109109        return  false ; 
110110    } 
111111
112-     match  virtual_call_violation_for_method ( tcx,  trait_def_id,  method)  { 
113-         None  | Some ( MethodViolationCode :: WhereClauseReferencesSelf )  => true , 
114-         Some ( _)  => false , 
115-     } 
112+     virtual_call_violation_for_method ( tcx,  trait_def_id,  method) 
113+         . iter ( ) 
114+         . all ( |v| matches ! ( v,  MethodViolationCode :: WhereClauseReferencesSelf ) ) 
116115} 
117116
118117fn  object_safety_violations_for_trait ( 
@@ -123,7 +122,7 @@ fn object_safety_violations_for_trait(
123122    let  mut  violations:  Vec < _ >  = tcx
124123        . associated_items ( trait_def_id) 
125124        . in_definition_order ( ) 
126-         . filter_map ( |& item| object_safety_violation_for_assoc_item ( tcx,  trait_def_id,  item) ) 
125+         . flat_map ( |& item| object_safety_violation_for_assoc_item ( tcx,  trait_def_id,  item) ) 
127126        . collect ( ) ; 
128127
129128    // Check the trait itself. 
@@ -365,45 +364,48 @@ fn object_safety_violation_for_assoc_item(
365364    tcx :  TyCtxt < ' _ > , 
366365    trait_def_id :  DefId , 
367366    item :  ty:: AssocItem , 
368- )  -> Option < ObjectSafetyViolation >  { 
367+ )  -> Vec < ObjectSafetyViolation >  { 
369368    // Any item that has a `Self : Sized` requisite is otherwise 
370369    // exempt from the regulations. 
371370    if  tcx. generics_require_sized_self ( item. def_id )  { 
372-         return  None ; 
371+         return  Vec :: new ( ) ; 
373372    } 
374373
375374    match  item. kind  { 
376375        // Associated consts are never object safe, as they can't have `where` bounds yet at all, 
377376        // and associated const bounds in trait objects aren't a thing yet either. 
378377        ty:: AssocKind :: Const  => { 
379-             Some ( ObjectSafetyViolation :: AssocConst ( item. name ,  item. ident ( tcx) . span ) ) 
378+             vec ! [ ObjectSafetyViolation :: AssocConst ( item. name,  item. ident( tcx) . span) ] 
380379        } 
381-         ty:: AssocKind :: Fn  => virtual_call_violation_for_method ( tcx,  trait_def_id,  item) . map ( |v| { 
382-             let  node = tcx. hir ( ) . get_if_local ( item. def_id ) ; 
383-             // Get an accurate span depending on the violation. 
384-             let  span = match  ( & v,  node)  { 
385-                 ( MethodViolationCode :: ReferencesSelfInput ( Some ( span) ) ,  _)  => * span, 
386-                 ( MethodViolationCode :: UndispatchableReceiver ( Some ( span) ) ,  _)  => * span, 
387-                 ( MethodViolationCode :: ReferencesImplTraitInTrait ( span) ,  _)  => * span, 
388-                 ( MethodViolationCode :: ReferencesSelfOutput ,  Some ( node) )  => { 
389-                     node. fn_decl ( ) . map_or ( item. ident ( tcx) . span ,  |decl| decl. output . span ( ) ) 
390-                 } 
391-                 _ => item. ident ( tcx) . span , 
392-             } ; 
380+         ty:: AssocKind :: Fn  => virtual_call_violation_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+                 } ; 
393394
394-             ObjectSafetyViolation :: Method ( item. name ,  v,  span) 
395-         } ) , 
395+                 ObjectSafetyViolation :: Method ( item. name ,  v,  span) 
396+             } ) 
397+             . collect ( ) , 
396398        // Associated types can only be object safe if they have `Self: Sized` bounds. 
397399        ty:: AssocKind :: Type  => { 
398400            if  !tcx. features ( ) . generic_associated_types_extended 
399401                && !tcx. generics_of ( item. def_id ) . params . is_empty ( ) 
400402                && !item. is_impl_trait_in_trait ( ) 
401403            { 
402-                 Some ( ObjectSafetyViolation :: GAT ( item. name ,  item. ident ( tcx) . span ) ) 
404+                 vec ! [ ObjectSafetyViolation :: GAT ( item. name,  item. ident( tcx) . span) ] 
403405            }  else  { 
404406                // We will permit associated types if they are explicitly mentioned in the trait object. 
405407                // We can't check this here, as here we only check if it is guaranteed to not be possible. 
406-                 None 
408+                 Vec :: new ( ) 
407409            } 
408410        } 
409411    } 
@@ -417,7 +419,7 @@ fn virtual_call_violation_for_method<'tcx>(
417419    tcx :  TyCtxt < ' tcx > , 
418420    trait_def_id :  DefId , 
419421    method :  ty:: AssocItem , 
420- )  -> Option < MethodViolationCode >  { 
422+ )  -> Vec < MethodViolationCode >  { 
421423    let  sig = tcx. fn_sig ( method. def_id ) . instantiate_identity ( ) ; 
422424
423425    // The method's first parameter must be named `self` 
@@ -442,9 +444,14 @@ fn virtual_call_violation_for_method<'tcx>(
442444        }  else  { 
443445            None 
444446        } ; 
445-         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) ] ; 
446451    } 
447452
453+     let  mut  errors = Vec :: new ( ) ; 
454+ 
448455    for  ( i,  & input_ty)  in  sig. skip_binder ( ) . inputs ( ) . iter ( ) . enumerate ( ) . skip ( 1 )  { 
449456        if  contains_illegal_self_type_reference ( tcx,  trait_def_id,  sig. rebind ( input_ty) )  { 
450457            let  span = if  let  Some ( hir:: Node :: TraitItem ( hir:: TraitItem  { 
@@ -456,20 +463,20 @@ fn virtual_call_violation_for_method<'tcx>(
456463            }  else  { 
457464                None 
458465            } ; 
459-             return   Some ( MethodViolationCode :: ReferencesSelfInput ( span) ) ; 
466+             errors . push ( MethodViolationCode :: ReferencesSelfInput ( span) ) ; 
460467        } 
461468    } 
462469    if  contains_illegal_self_type_reference ( tcx,  trait_def_id,  sig. output ( ) )  { 
463-         return   Some ( MethodViolationCode :: ReferencesSelfOutput ) ; 
470+         errors . push ( MethodViolationCode :: ReferencesSelfOutput ) ; 
464471    } 
465472    if  let  Some ( code)  = contains_illegal_impl_trait_in_trait ( tcx,  method. def_id ,  sig. output ( ) )  { 
466-         return   Some ( code) ; 
473+         errors . push ( code) ; 
467474    } 
468475
469476    // We can't monomorphize things like `fn foo<A>(...)`. 
470477    let  own_counts = tcx. generics_of ( method. def_id ) . own_counts ( ) ; 
471478    if  own_counts. types  > 0  || own_counts. consts  > 0  { 
472-         return   Some ( MethodViolationCode :: Generic ) ; 
479+         errors . push ( MethodViolationCode :: Generic ) ; 
473480    } 
474481
475482    let  receiver_ty = tcx. liberate_late_bound_regions ( method. def_id ,  sig. input ( 0 ) ) ; 
@@ -489,7 +496,7 @@ fn virtual_call_violation_for_method<'tcx>(
489496            }  else  { 
490497                None 
491498            } ; 
492-             return   Some ( MethodViolationCode :: UndispatchableReceiver ( span) ) ; 
499+             errors . push ( MethodViolationCode :: UndispatchableReceiver ( span) ) ; 
493500        }  else  { 
494501            // Do sanity check to make sure the receiver actually has the layout of a pointer. 
495502
@@ -598,10 +605,10 @@ fn virtual_call_violation_for_method<'tcx>(
598605
599606        contains_illegal_self_type_reference ( tcx,  trait_def_id,  pred) 
600607    } )  { 
601-         return   Some ( MethodViolationCode :: WhereClauseReferencesSelf ) ; 
608+         errors . push ( MethodViolationCode :: WhereClauseReferencesSelf ) ; 
602609    } 
603610
604-     None 
611+     errors 
605612} 
606613
607614/// Performs a type substitution to produce the version of `receiver_ty` when `Self = self_ty`. 
0 commit comments