@@ -965,6 +965,30 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
965965 ty:: ExistentialTraitRef :: erase_self_ty ( self . tcx ( ) , trait_ref)
966966 }
967967
968+ fn expand_trait_refs ( & self ,
969+ trait_refs : impl IntoIterator < Item = ( ty:: PolyTraitRef < ' tcx > , Span ) >
970+ ) -> Vec < DefId > {
971+ let tcx = self . tcx ( ) ;
972+
973+ // Expand trait aliases recursively and check that only one regular (non-auto) trait
974+ // is used.
975+ let expanded_traits = traits:: expand_trait_refs ( tcx, trait_refs) ;
976+ let ( auto_traits, regular_traits) : ( Vec < _ > , Vec < _ > ) =
977+ expanded_traits. partition ( |i| tcx. trait_is_auto ( i. trait_ref . def_id ( ) ) ) ;
978+ if regular_traits. len ( ) > 1 {
979+ let extra_trait = & regular_traits[ 1 ] ;
980+ let mut err = struct_span_err ! ( tcx. sess, extra_trait. top_level_span, E0225 ,
981+ "only auto traits can be used as additional traits in a trait object" ) ;
982+ err. span_label ( extra_trait. span , "non-auto additional trait" ) ;
983+ if extra_trait. span != extra_trait. top_level_span {
984+ err. span_label ( extra_trait. top_level_span , "expanded from this trait alias" ) ;
985+ }
986+ err. emit ( ) ;
987+ }
988+
989+ auto_traits. into_iter ( ) . map ( |i| i. trait_ref . def_id ( ) ) . collect ( )
990+ }
991+
968992 fn conv_object_ty_poly_trait_ref ( & self ,
969993 span : Span ,
970994 trait_bounds : & [ hir:: PolyTraitRef ] ,
@@ -1000,19 +1024,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
10001024 }
10011025 bound_trait_refs. push ( ( principal, trait_bounds[ 0 ] . span ) ) ;
10021026
1003- let expanded_traits = traits:: expand_trait_refs ( tcx, bound_trait_refs) ;
1004- let ( auto_traits, regular_traits) : ( Vec < _ > , Vec < _ > ) =
1005- expanded_traits. partition ( |i| tcx. trait_is_auto ( i. trait_ref . def_id ( ) ) ) ;
1006- if regular_traits. len ( ) > 1 {
1007- let extra_trait = & regular_traits[ 1 ] ;
1008- let mut err = struct_span_err ! ( tcx. sess, extra_trait. top_level_span, E0225 ,
1009- "only auto traits can be used as additional traits in a trait object" ) ;
1010- err. span_label ( extra_trait. span , "non-auto additional trait" ) ;
1011- if extra_trait. span != extra_trait. top_level_span {
1012- err. span_label ( extra_trait. top_level_span , "expanded from this trait alias" ) ;
1013- }
1014- err. emit ( ) ;
1015- }
1027+ let mut auto_traits = self . expand_trait_refs ( bound_trait_refs) ;
10161028
10171029 // Check that there are no gross object safety violations;
10181030 // most importantly, that the supertraits don't contain `Self`,
@@ -1156,8 +1168,6 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
11561168
11571169 // De-duplicate auto traits so that, e.g., `dyn Trait + Send + Send` is the same as
11581170 // `dyn Trait + Send`.
1159- let mut auto_traits: Vec < _ > =
1160- auto_traits. into_iter ( ) . map ( |i| i. trait_ref . def_id ( ) ) . collect ( ) ;
11611171 auto_traits. sort ( ) ;
11621172 auto_traits. dedup ( ) ;
11631173 debug ! ( "auto_traits: {:?}" , auto_traits) ;
0 commit comments