@@ -33,37 +33,48 @@ pub(crate) fn expand_deriving_clone(
33
33
let substructure;
34
34
let is_simple;
35
35
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 ) ) ] ;
47
70
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 )
50
73
} ) ) ;
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) ) ) ;
56
74
}
75
+ _ => cx. dcx ( ) . span_bug ( span, "`#[derive(Clone)]` on wrong item kind" ) ,
57
76
}
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
+ }
67
78
68
79
_ => cx. dcx ( ) . span_bug ( span, "`#[derive(Clone)]` on trait item or impl item" ) ,
69
80
}
@@ -98,6 +109,7 @@ fn cs_clone_simple(
98
109
trait_span : Span ,
99
110
substr : & Substructure < ' _ > ,
100
111
is_union : bool ,
112
+ has_repr_scalable : bool ,
101
113
) -> BlockOrExpr {
102
114
let mut stmts = ThinVec :: new ( ) ;
103
115
let mut seen_type_names = FxHashSet :: default ( ) ;
@@ -112,6 +124,9 @@ fn cs_clone_simple(
112
124
// Already produced an assertion for this type.
113
125
// Anonymous structs or unions must be eliminated as they cannot be
114
126
// 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`
115
130
} else {
116
131
// let _: AssertParamIsClone<FieldTy>;
117
132
super :: assert_ty_bounds (
0 commit comments