11use rustc_ast:: Attribute ;
2- use rustc_hir as hir ;
2+ use rustc_hir:: def :: DefKind ;
33use rustc_hir:: def_id:: LocalDefId ;
4- use rustc_hir:: itemlikevisit:: ItemLikeVisitor ;
5- use rustc_hir:: ItemKind ;
64use rustc_middle:: ty:: layout:: { HasParamEnv , HasTyCtxt , LayoutError , LayoutOfHelpers , TyAndLayout } ;
75use rustc_middle:: ty:: { ParamEnv , Ty , TyCtxt } ;
86use rustc_span:: symbol:: sym;
@@ -12,97 +10,87 @@ use rustc_target::abi::{HasDataLayout, TargetDataLayout};
1210pub fn test_layout ( tcx : TyCtxt < ' _ > ) {
1311 if tcx. features ( ) . rustc_attrs {
1412 // if the `rustc_attrs` feature is not enabled, don't bother testing layout
15- tcx. hir ( ) . visit_all_item_likes ( & mut LayoutTest { tcx } ) ;
16- }
17- }
18-
19- struct LayoutTest < ' tcx > {
20- tcx : TyCtxt < ' tcx > ,
21- }
22-
23- impl < ' tcx > ItemLikeVisitor < ' tcx > for LayoutTest < ' tcx > {
24- fn visit_item ( & mut self , item : & ' tcx hir:: Item < ' tcx > ) {
25- match item. kind {
26- ItemKind :: TyAlias ( ..)
27- | ItemKind :: Enum ( ..)
28- | ItemKind :: Struct ( ..)
29- | ItemKind :: Union ( ..) => {
30- for attr in self . tcx . get_attrs ( item. def_id . to_def_id ( ) , sym:: rustc_layout) {
31- self . dump_layout_of ( item. def_id , item, attr) ;
13+ for id in tcx. hir ( ) . items ( ) {
14+ if matches ! (
15+ tcx. def_kind( id. def_id) ,
16+ DefKind :: TyAlias | DefKind :: Enum | DefKind :: Struct | DefKind :: Union
17+ ) {
18+ for attr in tcx. get_attrs ( id. def_id . to_def_id ( ) , sym:: rustc_layout) {
19+ dump_layout_of ( tcx, id. def_id , attr) ;
3220 }
3321 }
34- _ => { }
3522 }
3623 }
37-
38- fn visit_trait_item ( & mut self , _: & ' tcx hir:: TraitItem < ' tcx > ) { }
39- fn visit_impl_item ( & mut self , _: & ' tcx hir:: ImplItem < ' tcx > ) { }
40- fn visit_foreign_item ( & mut self , _: & ' tcx hir:: ForeignItem < ' tcx > ) { }
4124}
4225
43- impl < ' tcx > LayoutTest < ' tcx > {
44- fn dump_layout_of ( & self , item_def_id : LocalDefId , item : & hir:: Item < ' tcx > , attr : & Attribute ) {
45- let tcx = self . tcx ;
46- let param_env = self . tcx . param_env ( item_def_id) ;
47- let ty = self . tcx . type_of ( item_def_id) ;
48- match self . tcx . layout_of ( param_env. and ( ty) ) {
49- Ok ( ty_layout) => {
50- // Check out the `#[rustc_layout(..)]` attribute to tell what to dump.
51- // The `..` are the names of fields to dump.
52- let meta_items = attr. meta_item_list ( ) . unwrap_or_default ( ) ;
53- for meta_item in meta_items {
54- match meta_item. name_or_empty ( ) {
55- sym:: abi => {
56- self . tcx . sess . span_err ( item. span , & format ! ( "abi: {:?}" , ty_layout. abi) ) ;
57- }
26+ fn dump_layout_of < ' tcx > ( tcx : TyCtxt < ' tcx > , item_def_id : LocalDefId , attr : & Attribute ) {
27+ let tcx = tcx;
28+ let param_env = tcx. param_env ( item_def_id) ;
29+ let ty = tcx. type_of ( item_def_id) ;
30+ match tcx. layout_of ( param_env. and ( ty) ) {
31+ Ok ( ty_layout) => {
32+ // Check out the `#[rustc_layout(..)]` attribute to tell what to dump.
33+ // The `..` are the names of fields to dump.
34+ let meta_items = attr. meta_item_list ( ) . unwrap_or_default ( ) ;
35+ for meta_item in meta_items {
36+ match meta_item. name_or_empty ( ) {
37+ sym:: abi => {
38+ tcx. sess . span_err (
39+ tcx. def_span ( item_def_id. to_def_id ( ) ) ,
40+ & format ! ( "abi: {:?}" , ty_layout. abi) ,
41+ ) ;
42+ }
5843
59- sym:: align => {
60- self . tcx
61- . sess
62- . span_err ( item. span , & format ! ( "align: {:?}" , ty_layout. align) ) ;
63- }
44+ sym:: align => {
45+ tcx. sess . span_err (
46+ tcx. def_span ( item_def_id. to_def_id ( ) ) ,
47+ & format ! ( "align: {:?}" , ty_layout. align) ,
48+ ) ;
49+ }
6450
65- sym:: size => {
66- self . tcx
67- . sess
68- . span_err ( item. span , & format ! ( "size: {:?}" , ty_layout. size) ) ;
69- }
51+ sym:: size => {
52+ tcx. sess . span_err (
53+ tcx. def_span ( item_def_id. to_def_id ( ) ) ,
54+ & format ! ( "size: {:?}" , ty_layout. size) ,
55+ ) ;
56+ }
7057
71- sym:: homogeneous_aggregate => {
72- self . tcx . sess . span_err (
73- item. span ,
74- & format ! (
75- "homogeneous_aggregate: {:?}" ,
76- ty_layout
77- . homogeneous_aggregate( & UnwrapLayoutCx { tcx, param_env } ) ,
78- ) ,
79- ) ;
80- }
58+ sym:: homogeneous_aggregate => {
59+ tcx. sess . span_err (
60+ tcx. def_span ( item_def_id. to_def_id ( ) ) ,
61+ & format ! (
62+ "homogeneous_aggregate: {:?}" ,
63+ ty_layout. homogeneous_aggregate( & UnwrapLayoutCx { tcx, param_env } ) ,
64+ ) ,
65+ ) ;
66+ }
8167
82- sym:: debug => {
83- let normalized_ty = self . tcx . normalize_erasing_regions (
84- param_env. with_reveal_all_normalized ( self . tcx ) ,
85- ty,
86- ) ;
87- self . tcx . sess . span_err (
88- item . span ,
89- & format ! ( "layout_of({:?}) = {:#?}" , normalized_ty, * ty_layout) ,
90- ) ;
91- }
68+ sym:: debug => {
69+ let normalized_ty = tcx. normalize_erasing_regions (
70+ param_env. with_reveal_all_normalized ( tcx) ,
71+ ty,
72+ ) ;
73+ tcx. sess . span_err (
74+ tcx . def_span ( item_def_id . to_def_id ( ) ) ,
75+ & format ! ( "layout_of({:?}) = {:#?}" , normalized_ty, * ty_layout) ,
76+ ) ;
77+ }
9278
93- name => {
94- self . tcx . sess . span_err (
95- meta_item. span ( ) ,
96- & format ! ( "unrecognized field name `{}`" , name) ,
97- ) ;
98- }
79+ name => {
80+ tcx. sess . span_err (
81+ meta_item. span ( ) ,
82+ & format ! ( "unrecognized field name `{}`" , name) ,
83+ ) ;
9984 }
10085 }
10186 }
87+ }
10288
103- Err ( layout_error) => {
104- self . tcx . sess . span_err ( item. span , & format ! ( "layout error: {:?}" , layout_error) ) ;
105- }
89+ Err ( layout_error) => {
90+ tcx. sess . span_err (
91+ tcx. def_span ( item_def_id. to_def_id ( ) ) ,
92+ & format ! ( "layout error: {:?}" , layout_error) ,
93+ ) ;
10694 }
10795 }
10896}
0 commit comments