@@ -33,37 +33,48 @@ pub(crate) fn expand_deriving_clone(
3333 let substructure;
3434 let is_simple;
3535 match item {
36- Annotatable :: Item ( annitem) => match & annitem. kind {
37- ItemKind :: Struct ( _, Generics { params, .. } , _)
38- | ItemKind :: Enum ( _, Generics { params, .. } , _) => {
39- let container_id = cx. current_expansion . id . expn_data ( ) . parent . expect_local ( ) ;
40- let has_derive_copy = cx. resolver . has_derive_copy ( container_id) ;
41- if has_derive_copy
42- && !params
43- . iter ( )
44- . any ( |param| matches ! ( param. kind, ast:: GenericParamKind :: Type { .. } ) )
45- {
46- bounds = vec ! [ ] ;
36+ Annotatable :: Item ( annitem) => {
37+ let has_repr_scalable = annitem. attrs . iter ( ) . any ( |attr| {
38+ attr. has_name ( sym:: repr)
39+ && attr
40+ . meta_item_list ( )
41+ . map ( |list| list. iter ( ) . any ( |inner| inner. has_name ( sym:: scalable) ) )
42+ . unwrap_or ( false )
43+ } ) ;
44+
45+ match & annitem. kind {
46+ ItemKind :: Struct ( _, Generics { params, .. } , _)
47+ | ItemKind :: Enum ( _, Generics { params, .. } , _) => {
48+ let container_id = cx. current_expansion . id . expn_data ( ) . parent . expect_local ( ) ;
49+ let has_derive_copy = cx. resolver . has_derive_copy ( container_id) ;
50+ if has_derive_copy
51+ && !params
52+ . iter ( )
53+ . any ( |param| matches ! ( param. kind, ast:: GenericParamKind :: Type { .. } ) )
54+ {
55+ bounds = vec ! [ ] ;
56+ is_simple = true ;
57+ substructure = combine_substructure ( Box :: new ( move |c, s, sub| {
58+ cs_clone_simple ( "Clone" , c, s, sub, false , has_repr_scalable)
59+ } ) ) ;
60+ } else {
61+ bounds = vec ! [ ] ;
62+ is_simple = false ;
63+ substructure = combine_substructure ( Box :: new ( |c, s, sub| {
64+ cs_clone ( "Clone" , c, s, sub)
65+ } ) ) ;
66+ }
67+ }
68+ ItemKind :: Union ( ..) => {
69+ bounds = vec ! [ Path ( path_std!( marker:: Copy ) ) ] ;
4770 is_simple = true ;
48- substructure = combine_substructure ( Box :: new ( |c, s, sub| {
49- cs_clone_simple ( "Clone" , c, s, sub, false )
71+ substructure = combine_substructure ( Box :: new ( move |c, s, sub| {
72+ cs_clone_simple ( "Clone" , c, s, sub, true , has_repr_scalable )
5073 } ) ) ;
51- } else {
52- bounds = vec ! [ ] ;
53- is_simple = false ;
54- substructure =
55- combine_substructure ( Box :: new ( |c, s, sub| cs_clone ( "Clone" , c, s, sub) ) ) ;
5674 }
75+ _ => cx. dcx ( ) . span_bug ( span, "`#[derive(Clone)]` on wrong item kind" ) ,
5776 }
58- ItemKind :: Union ( ..) => {
59- bounds = vec ! [ Path ( path_std!( marker:: Copy ) ) ] ;
60- is_simple = true ;
61- substructure = combine_substructure ( Box :: new ( |c, s, sub| {
62- cs_clone_simple ( "Clone" , c, s, sub, true )
63- } ) ) ;
64- }
65- _ => cx. dcx ( ) . span_bug ( span, "`#[derive(Clone)]` on wrong item kind" ) ,
66- } ,
77+ }
6778
6879 _ => cx. dcx ( ) . span_bug ( span, "`#[derive(Clone)]` on trait item or impl item" ) ,
6980 }
@@ -98,6 +109,7 @@ fn cs_clone_simple(
98109 trait_span : Span ,
99110 substr : & Substructure < ' _ > ,
100111 is_union : bool ,
112+ has_repr_scalable : bool ,
101113) -> BlockOrExpr {
102114 let mut stmts = ThinVec :: new ( ) ;
103115 let mut seen_type_names = FxHashSet :: default ( ) ;
@@ -112,6 +124,9 @@ fn cs_clone_simple(
112124 // Already produced an assertion for this type.
113125 // Anonymous structs or unions must be eliminated as they cannot be
114126 // type parameters.
127+ } else if has_repr_scalable {
128+ // Fields of scalable vector types are just markers for codegen, don't assert they
129+ // implement `Clone`
115130 } else {
116131 // let _: AssertParamIsClone<FieldTy>;
117132 super :: assert_ty_bounds (
0 commit comments