@@ -20,7 +20,9 @@ use rustc_span::def_id::DefId;
20
20
use rustc_span:: Span ;
21
21
use rustc_span:: DUMMY_SP ;
22
22
use rustc_target:: abi:: call:: { ArgAbi , ArgAttributes , FnAbi , PassMode } ;
23
- use rustc_target:: abi:: { Abi , Align , FieldsShape , Primitive , Scalar , Size , VariantIdx , Variants } ;
23
+ use rustc_target:: abi:: {
24
+ Abi , Align , FieldsShape , Layout , Primitive , Scalar , Size , TagEncoding , VariantIdx , Variants ,
25
+ } ;
24
26
use rustc_target:: spec:: abi:: Abi as SpecAbi ;
25
27
use std:: cell:: RefCell ;
26
28
use std:: collections:: hash_map:: Entry ;
@@ -89,6 +91,80 @@ pub(crate) fn provide(providers: &mut Providers) {
89
91
let result = ( rustc_interface:: DEFAULT_QUERY_PROVIDERS . fn_abi_of_instance ) ( tcx, key) ;
90
92
Ok ( readjust_fn_abi ( tcx, result?) )
91
93
} ;
94
+
95
+ // FIXME(eddyb) remove this by deriving `Clone` for `Layout` upstream.
96
+ fn clone_layout ( layout : & Layout ) -> Layout {
97
+ let Layout {
98
+ ref fields,
99
+ ref variants,
100
+ abi,
101
+ largest_niche,
102
+ align,
103
+ size,
104
+ } = * layout;
105
+ Layout {
106
+ fields : match * fields {
107
+ FieldsShape :: Primitive => FieldsShape :: Primitive ,
108
+ FieldsShape :: Union ( count) => FieldsShape :: Union ( count) ,
109
+ FieldsShape :: Array { stride, count } => FieldsShape :: Array { stride, count } ,
110
+ FieldsShape :: Arbitrary {
111
+ ref offsets,
112
+ ref memory_index,
113
+ } => FieldsShape :: Arbitrary {
114
+ offsets : offsets. clone ( ) ,
115
+ memory_index : memory_index. clone ( ) ,
116
+ } ,
117
+ } ,
118
+ variants : match * variants {
119
+ Variants :: Single { index } => Variants :: Single { index } ,
120
+ Variants :: Multiple {
121
+ tag,
122
+ ref tag_encoding,
123
+ tag_field,
124
+ ref variants,
125
+ } => Variants :: Multiple {
126
+ tag,
127
+ tag_encoding : match * tag_encoding {
128
+ TagEncoding :: Direct => TagEncoding :: Direct ,
129
+ TagEncoding :: Niche {
130
+ dataful_variant,
131
+ ref niche_variants,
132
+ niche_start,
133
+ } => TagEncoding :: Niche {
134
+ dataful_variant,
135
+ niche_variants : niche_variants. clone ( ) ,
136
+ niche_start,
137
+ } ,
138
+ } ,
139
+ tag_field,
140
+ variants : variants. iter ( ) . map ( clone_layout) . collect ( ) ,
141
+ } ,
142
+ } ,
143
+ abi,
144
+ largest_niche,
145
+ align,
146
+ size,
147
+ }
148
+ }
149
+ providers. layout_of = |tcx, key| {
150
+ let TyAndLayout { ty, mut layout } =
151
+ ( rustc_interface:: DEFAULT_QUERY_PROVIDERS . layout_of ) ( tcx, key) ?;
152
+
153
+ // FIXME(eddyb) make use of this - at this point, it's just a placeholder.
154
+ #[ allow( clippy:: match_single_binding) ]
155
+ let hide_niche = match ty. kind ( ) {
156
+ _ => false ,
157
+ } ;
158
+
159
+ if hide_niche {
160
+ layout = tcx. arena . alloc ( Layout {
161
+ largest_niche : None ,
162
+ ..clone_layout ( layout)
163
+ } ) ;
164
+ }
165
+
166
+ Ok ( TyAndLayout { ty, layout } )
167
+ } ;
92
168
}
93
169
94
170
pub ( crate ) fn provide_extern ( providers : & mut Providers ) {
0 commit comments