Skip to content

Commit 6232d95

Browse files
authored
abi: demonstrate overriding the behavior of the layout_of query. (#808)
1 parent d789b58 commit 6232d95

File tree

1 file changed

+77
-1
lines changed
  • crates/rustc_codegen_spirv/src

1 file changed

+77
-1
lines changed

crates/rustc_codegen_spirv/src/abi.rs

Lines changed: 77 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@ use rustc_span::def_id::DefId;
2020
use rustc_span::Span;
2121
use rustc_span::DUMMY_SP;
2222
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+
};
2426
use rustc_target::spec::abi::Abi as SpecAbi;
2527
use std::cell::RefCell;
2628
use 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

94170
pub(crate) fn provide_extern(providers: &mut Providers) {

0 commit comments

Comments
 (0)