@@ -20,7 +20,9 @@ use rustc_span::def_id::DefId;
2020use rustc_span:: Span ;
2121use rustc_span:: DUMMY_SP ;
2222use 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+ } ;
2426use rustc_target:: spec:: abi:: Abi as SpecAbi ;
2527use std:: cell:: RefCell ;
2628use std:: collections:: hash_map:: Entry ;
@@ -89,6 +91,80 @@ pub(crate) fn provide(providers: &mut Providers) {
8991 let result = ( rustc_interface:: DEFAULT_QUERY_PROVIDERS . fn_abi_of_instance ) ( tcx, key) ;
9092 Ok ( readjust_fn_abi ( tcx, result?) )
9193 } ;
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+ } ;
92168}
93169
94170pub ( crate ) fn provide_extern ( providers : & mut Providers ) {
0 commit comments