11use rustc_abi:: { HasDataLayout , TargetDataLayout } ;
2- use rustc_hir:: Attribute ;
2+ use rustc_hir:: attrs :: { AttributeKind , RustcLayoutType } ;
33use rustc_hir:: def:: DefKind ;
44use rustc_hir:: def_id:: LocalDefId ;
5+ use rustc_hir:: find_attr;
56use rustc_middle:: span_bug;
67use rustc_middle:: ty:: layout:: { HasTyCtxt , HasTypingEnv , LayoutError , LayoutOfHelpers } ;
78use rustc_middle:: ty:: { self , Ty , TyCtxt } ;
9+ use rustc_span:: Span ;
810use rustc_span:: source_map:: Spanned ;
9- use rustc_span:: { Span , sym} ;
1011use rustc_trait_selection:: error_reporting:: InferCtxtErrorExt ;
1112use rustc_trait_selection:: infer:: TyCtxtInferExt ;
1213use rustc_trait_selection:: traits;
1314
14- use crate :: errors:: {
15- LayoutAbi , LayoutAlign , LayoutHomogeneousAggregate , LayoutInvalidAttribute , LayoutOf ,
16- LayoutSize , UnrecognizedArgument ,
17- } ;
15+ use crate :: errors:: { LayoutAbi , LayoutAlign , LayoutHomogeneousAggregate , LayoutOf , LayoutSize } ;
1816
1917pub fn test_layout ( tcx : TyCtxt < ' _ > ) {
2018 if !tcx. features ( ) . rustc_attrs ( ) {
2119 // if the `rustc_attrs` feature is not enabled, don't bother testing layout
2220 return ;
2321 }
2422 for id in tcx. hir_crate_items ( ( ) ) . definitions ( ) {
25- for attr in tcx. get_attrs ( id, sym :: rustc_layout ) {
26- match tcx . def_kind ( id ) {
27- DefKind :: TyAlias | DefKind :: Enum | DefKind :: Struct | DefKind :: Union => {
28- dump_layout_of ( tcx , id , attr ) ;
29- }
30- _ => {
31- tcx . dcx ( ) . emit_err ( LayoutInvalidAttribute { span : tcx . def_span ( id ) } ) ;
32- }
23+ let attrs = tcx. get_all_attrs ( id) ;
24+ if let Some ( attrs ) = find_attr ! ( attrs , AttributeKind :: RustcLayout ( attrs ) => attrs ) {
25+ // Attribute parsing handles error reporting
26+ if matches ! (
27+ tcx . def_kind ( id ) ,
28+ DefKind :: TyAlias | DefKind :: Enum | DefKind :: Struct | DefKind :: Union
29+ ) {
30+ dump_layout_of ( tcx , id , attrs ) ;
3331 }
3432 }
3533 }
@@ -66,7 +64,7 @@ pub fn ensure_wf<'tcx>(
6664 }
6765}
6866
69- fn dump_layout_of ( tcx : TyCtxt < ' _ > , item_def_id : LocalDefId , attr : & Attribute ) {
67+ fn dump_layout_of ( tcx : TyCtxt < ' _ > , item_def_id : LocalDefId , attrs : & [ RustcLayoutType ] ) {
7068 let typing_env = ty:: TypingEnv :: post_analysis ( tcx, item_def_id) ;
7169 let ty = tcx. type_of ( item_def_id) . instantiate_identity ( ) ;
7270 let span = tcx. def_span ( item_def_id. to_def_id ( ) ) ;
@@ -75,32 +73,29 @@ fn dump_layout_of(tcx: TyCtxt<'_>, item_def_id: LocalDefId, attr: &Attribute) {
7573 }
7674 match tcx. layout_of ( typing_env. as_query_input ( ty) ) {
7775 Ok ( ty_layout) => {
78- // Check out the `#[rustc_layout(..)]` attribute to tell what to dump.
79- // The `..` are the names of fields to dump.
80- let meta_items = attr. meta_item_list ( ) . unwrap_or_default ( ) ;
81- for meta_item in meta_items {
82- match meta_item. name ( ) {
76+ for attr in attrs {
77+ match attr {
8378 // FIXME: this never was about ABI and now this dump arg is confusing
84- Some ( sym :: abi ) => {
79+ RustcLayoutType :: Abi => {
8580 tcx. dcx ( ) . emit_err ( LayoutAbi {
8681 span,
8782 abi : format ! ( "{:?}" , ty_layout. backend_repr) ,
8883 } ) ;
8984 }
9085
91- Some ( sym :: align ) => {
86+ RustcLayoutType :: Align => {
9287 tcx. dcx ( ) . emit_err ( LayoutAlign {
9388 span,
9489 align : format ! ( "{:?}" , ty_layout. align) ,
9590 } ) ;
9691 }
9792
98- Some ( sym :: size ) => {
93+ RustcLayoutType :: Size => {
9994 tcx. dcx ( )
10095 . emit_err ( LayoutSize { span, size : format ! ( "{:?}" , ty_layout. size) } ) ;
10196 }
10297
103- Some ( sym :: homogeneous_aggregate ) => {
98+ RustcLayoutType :: HomogenousAggregate => {
10499 tcx. dcx ( ) . emit_err ( LayoutHomogeneousAggregate {
105100 span,
106101 homogeneous_aggregate : format ! (
@@ -111,16 +106,12 @@ fn dump_layout_of(tcx: TyCtxt<'_>, item_def_id: LocalDefId, attr: &Attribute) {
111106 } ) ;
112107 }
113108
114- Some ( sym :: debug ) => {
109+ RustcLayoutType :: Debug => {
115110 let normalized_ty = tcx. normalize_erasing_regions ( typing_env, ty) ;
116111 // FIXME: using the `Debug` impl here isn't ideal.
117112 let ty_layout = format ! ( "{:#?}" , * ty_layout) ;
118113 tcx. dcx ( ) . emit_err ( LayoutOf { span, normalized_ty, ty_layout } ) ;
119114 }
120-
121- _ => {
122- tcx. dcx ( ) . emit_err ( UnrecognizedArgument { span : meta_item. span ( ) } ) ;
123- }
124115 }
125116 }
126117 }
0 commit comments