Skip to content

Commit

Permalink
Rollup merge of rust-lang#69901 - RalfJung:rustc_layout, r=eddyb
Browse files Browse the repository at this point in the history
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. :)
  • Loading branch information
Dylan-DPC authored Mar 21, 2020
2 parents 16338b1 + 7b49678 commit c31cd0f
Show file tree
Hide file tree
Showing 4 changed files with 371 additions and 8 deletions.
29 changes: 21 additions & 8 deletions src/librustc_passes/layout_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,32 +17,38 @@ use rustc_span::symbol::sym;
pub fn test_layout(tcx: TyCtxt<'_>) {
if tcx.features().rustc_attrs {
// if the `rustc_attrs` feature is not enabled, don't bother testing layout
tcx.hir().krate().visit_all_item_likes(&mut VarianceTest { tcx });
tcx.hir().krate().visit_all_item_likes(&mut LayoutTest { tcx });
}
}

struct VarianceTest<'tcx> {
struct LayoutTest<'tcx> {
tcx: TyCtxt<'tcx>,
}

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

if let ItemKind::TyAlias(..) = item.kind {
for attr in self.tcx.get_attrs(item_def_id).iter() {
if attr.check_name(sym::rustc_layout) {
self.dump_layout_of(item_def_id, item, attr);
match item.kind {
ItemKind::TyAlias(..)
| ItemKind::Enum(..)
| ItemKind::Struct(..)
| ItemKind::Union(..) => {
for attr in self.tcx.get_attrs(item_def_id).iter() {
if attr.check_name(sym::rustc_layout) {
self.dump_layout_of(item_def_id, item, attr);
}
}
}
_ => {}
}
}

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

impl VarianceTest<'tcx> {
impl LayoutTest<'tcx> {
fn dump_layout_of(&self, item_def_id: DefId, item: &hir::Item<'tcx>, attr: &Attribute) {
let tcx = self.tcx;
let param_env = self.tcx.param_env(item_def_id);
Expand Down Expand Up @@ -81,6 +87,13 @@ impl VarianceTest<'tcx> {
);
}

sym::debug => {
self.tcx.sess.span_err(
item.span,
&format!("layout debugging: {:#?}", *ty_layout),
);
}

name => {
self.tcx.sess.span_err(
meta_item.span(),
Expand Down
1 change: 1 addition & 0 deletions src/librustc_span/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,7 @@ symbols! {
debug_trait,
declare_lint_pass,
decl_macro,
debug,
Debug,
Decodable,
Default,
Expand Down
14 changes: 14 additions & 0 deletions src/test/ui/layout/debug.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#![feature(never_type, rustc_attrs)]
#![crate_type = "lib"]

#[rustc_layout(debug)]
enum E { Foo, Bar(!, i32, i32) } //~ ERROR: layout debugging

#[rustc_layout(debug)]
struct S { f1: i32, f2: (), f3: i32 } //~ ERROR: layout debugging

#[rustc_layout(debug)]
union U { f1: (i32, i32), f3: i32 } //~ ERROR: layout debugging

#[rustc_layout(debug)]
type Test = Result<i32, i32>; //~ ERROR: layout debugging
Loading

0 comments on commit c31cd0f

Please sign in to comment.