Skip to content

Commit fd3f917

Browse files
authored
Rollup merge of #69901 - RalfJung:rustc_layout, r=eddyb
add #[rustc_layout(debug)] @eddyb recently told me about the `#[rustc_layout]` attribute, and I think it would be very useful if it could be used to print all the layout information Rust has about a type. When working with layouts (e.g. in Miri), it is often not clear how certain surface language features get represented internally. I have some awful hacks locally to be able to dump this debug information; with this attribute I could get it on the playground which is so much better. :)
2 parents a6596f2 + e548df7 commit fd3f917

File tree

4 files changed

+356
-8
lines changed

4 files changed

+356
-8
lines changed

src/librustc_passes/layout_test.rs

+21-8
Original file line numberDiff line numberDiff line change
@@ -17,32 +17,38 @@ use rustc_span::symbol::sym;
1717
pub fn test_layout(tcx: TyCtxt<'_>) {
1818
if tcx.features().rustc_attrs {
1919
// if the `rustc_attrs` feature is not enabled, don't bother testing layout
20-
tcx.hir().krate().visit_all_item_likes(&mut VarianceTest { tcx });
20+
tcx.hir().krate().visit_all_item_likes(&mut LayoutTest { tcx });
2121
}
2222
}
2323

24-
struct VarianceTest<'tcx> {
24+
struct LayoutTest<'tcx> {
2525
tcx: TyCtxt<'tcx>,
2626
}
2727

28-
impl ItemLikeVisitor<'tcx> for VarianceTest<'tcx> {
28+
impl ItemLikeVisitor<'tcx> for LayoutTest<'tcx> {
2929
fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
3030
let item_def_id = self.tcx.hir().local_def_id(item.hir_id);
3131

32-
if let ItemKind::TyAlias(..) = item.kind {
33-
for attr in self.tcx.get_attrs(item_def_id).iter() {
34-
if attr.check_name(sym::rustc_layout) {
35-
self.dump_layout_of(item_def_id, item, attr);
32+
match item.kind {
33+
ItemKind::TyAlias(..)
34+
| ItemKind::Enum(..)
35+
| ItemKind::Struct(..)
36+
| ItemKind::Union(..) => {
37+
for attr in self.tcx.get_attrs(item_def_id).iter() {
38+
if attr.check_name(sym::rustc_layout) {
39+
self.dump_layout_of(item_def_id, item, attr);
40+
}
3641
}
3742
}
43+
_ => {}
3844
}
3945
}
4046

4147
fn visit_trait_item(&mut self, _: &'tcx hir::TraitItem<'tcx>) {}
4248
fn visit_impl_item(&mut self, _: &'tcx hir::ImplItem<'tcx>) {}
4349
}
4450

45-
impl VarianceTest<'tcx> {
51+
impl LayoutTest<'tcx> {
4652
fn dump_layout_of(&self, item_def_id: DefId, item: &hir::Item<'tcx>, attr: &Attribute) {
4753
let tcx = self.tcx;
4854
let param_env = self.tcx.param_env(item_def_id);
@@ -81,6 +87,13 @@ impl VarianceTest<'tcx> {
8187
);
8288
}
8389

90+
sym::debug => {
91+
self.tcx.sess.span_err(
92+
item.span,
93+
&format!("layout debugging: {:#?}", *ty_layout),
94+
);
95+
}
96+
8497
name => {
8598
self.tcx.sess.span_err(
8699
meta_item.span(),

src/librustc_span/symbol.rs

+1
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,7 @@ symbols! {
253253
debug_trait,
254254
declare_lint_pass,
255255
decl_macro,
256+
debug,
256257
Debug,
257258
Decodable,
258259
Default,

src/test/ui/layout/debug.rs

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// normalize-stderr-test "pref: Align \{\n *pow2: [1-3],\n *\}" -> "pref: $$PREF_ALIGN"
2+
#![feature(never_type, rustc_attrs)]
3+
#![crate_type = "lib"]
4+
5+
#[rustc_layout(debug)]
6+
enum E { Foo, Bar(!, i32, i32) } //~ ERROR: layout debugging
7+
8+
#[rustc_layout(debug)]
9+
struct S { f1: i32, f2: (), f3: i32 } //~ ERROR: layout debugging
10+
11+
#[rustc_layout(debug)]
12+
union U { f1: (i32, i32), f3: i32 } //~ ERROR: layout debugging
13+
14+
#[rustc_layout(debug)]
15+
type Test = Result<i32, i32>; //~ ERROR: layout debugging

0 commit comments

Comments
 (0)