11use rustc_ast:: Attribute ;
22use rustc_hir:: def:: DefKind ;
3- use rustc_hir:: def_id:: DefId ;
3+ use rustc_hir:: def_id:: LocalDefId ;
44use rustc_middle:: ty:: layout:: { FnAbiError , LayoutError } ;
55use rustc_middle:: ty:: { self , GenericArgs , Instance , Ty , TyCtxt } ;
66use rustc_span:: source_map:: Spanned ;
77use rustc_span:: symbol:: sym;
88use rustc_target:: abi:: call:: FnAbi ;
99
10+ use super :: layout_test:: ensure_wf;
1011use crate :: errors:: { AbiInvalidAttribute , AbiNe , AbiOf , UnrecognizedField } ;
1112
1213pub fn test_abi ( tcx : TyCtxt < ' _ > ) {
1314 if !tcx. features ( ) . rustc_attrs {
1415 // if the `rustc_attrs` feature is not enabled, don't bother testing ABI
1516 return ;
1617 }
17- for id in tcx. hir ( ) . items ( ) {
18- for attr in tcx. get_attrs ( id. owner_id , sym:: rustc_abi) {
19- match tcx. def_kind ( id. owner_id ) {
20- DefKind :: Fn => {
21- dump_abi_of_fn_item ( tcx, id. owner_id . def_id . into ( ) , attr) ;
18+ for id in tcx. hir_crate_items ( ( ) ) . definitions ( ) {
19+ for attr in tcx. get_attrs ( id, sym:: rustc_abi) {
20+ match tcx. def_kind ( id) {
21+ DefKind :: Fn | DefKind :: AssocFn => {
22+ dump_abi_of_fn_item ( tcx, id, attr) ;
2223 }
2324 DefKind :: TyAlias { .. } => {
24- dump_abi_of_fn_type ( tcx, id. owner_id . def_id . into ( ) , attr) ;
25+ dump_abi_of_fn_type ( tcx, id, attr) ;
2526 }
2627 _ => {
27- tcx. sess . emit_err ( AbiInvalidAttribute { span : tcx. def_span ( id. owner_id ) } ) ;
28- }
29- }
30- }
31- if matches ! ( tcx. def_kind( id. owner_id) , DefKind :: Impl { .. } ) {
32- // To find associated functions we need to go into the child items here.
33- for & id in tcx. associated_item_def_ids ( id. owner_id ) {
34- for attr in tcx. get_attrs ( id, sym:: rustc_abi) {
35- match tcx. def_kind ( id) {
36- DefKind :: AssocFn => {
37- dump_abi_of_fn_item ( tcx, id, attr) ;
38- }
39- _ => {
40- tcx. sess . emit_err ( AbiInvalidAttribute { span : tcx. def_span ( id) } ) ;
41- }
42- }
28+ tcx. sess . emit_err ( AbiInvalidAttribute { span : tcx. def_span ( id) } ) ;
4329 }
4430 }
4531 }
@@ -49,7 +35,7 @@ pub fn test_abi(tcx: TyCtxt<'_>) {
4935fn unwrap_fn_abi < ' tcx > (
5036 abi : Result < & ' tcx FnAbi < ' tcx , Ty < ' tcx > > , & ' tcx FnAbiError < ' tcx > > ,
5137 tcx : TyCtxt < ' tcx > ,
52- item_def_id : DefId ,
38+ item_def_id : LocalDefId ,
5339) -> & ' tcx FnAbi < ' tcx , Ty < ' tcx > > {
5440 match abi {
5541 Ok ( abi) => abi,
@@ -71,10 +57,10 @@ fn unwrap_fn_abi<'tcx>(
7157 }
7258}
7359
74- fn dump_abi_of_fn_item ( tcx : TyCtxt < ' _ > , item_def_id : DefId , attr : & Attribute ) {
60+ fn dump_abi_of_fn_item ( tcx : TyCtxt < ' _ > , item_def_id : LocalDefId , attr : & Attribute ) {
7561 let param_env = tcx. param_env ( item_def_id) ;
7662 let args = GenericArgs :: identity_for_item ( tcx, item_def_id) ;
77- let instance = match Instance :: resolve ( tcx, param_env, item_def_id, args) {
63+ let instance = match Instance :: resolve ( tcx, param_env, item_def_id. into ( ) , args) {
7864 Ok ( Some ( instance) ) => instance,
7965 Ok ( None ) => {
8066 // Not sure what to do here, but `LayoutError::Unknown` seems reasonable?
@@ -99,7 +85,7 @@ fn dump_abi_of_fn_item(tcx: TyCtxt<'_>, item_def_id: DefId, attr: &Attribute) {
9985 for meta_item in meta_items {
10086 match meta_item. name_or_empty ( ) {
10187 sym:: debug => {
102- let fn_name = tcx. item_name ( item_def_id) ;
88+ let fn_name = tcx. item_name ( item_def_id. into ( ) ) ;
10389 tcx. sess . emit_err ( AbiOf {
10490 span : tcx. def_span ( item_def_id) ,
10591 fn_name,
@@ -128,9 +114,13 @@ fn test_abi_eq<'tcx>(abi1: &'tcx FnAbi<'tcx, Ty<'tcx>>, abi2: &'tcx FnAbi<'tcx,
128114 && abi1. args . iter ( ) . zip ( abi2. args . iter ( ) ) . all ( |( arg1, arg2) | arg1. eq_abi ( arg2) )
129115}
130116
131- fn dump_abi_of_fn_type ( tcx : TyCtxt < ' _ > , item_def_id : DefId , attr : & Attribute ) {
117+ fn dump_abi_of_fn_type ( tcx : TyCtxt < ' _ > , item_def_id : LocalDefId , attr : & Attribute ) {
132118 let param_env = tcx. param_env ( item_def_id) ;
133119 let ty = tcx. type_of ( item_def_id) . instantiate_identity ( ) ;
120+ let span = tcx. def_span ( item_def_id) ;
121+ if !ensure_wf ( tcx, param_env, ty, item_def_id, span) {
122+ return ;
123+ }
134124 let meta_items = attr. meta_item_list ( ) . unwrap_or_default ( ) ;
135125 for meta_item in meta_items {
136126 match meta_item. name_or_empty ( ) {
@@ -147,12 +137,8 @@ fn dump_abi_of_fn_type(tcx: TyCtxt<'_>, item_def_id: DefId, attr: &Attribute) {
147137 item_def_id,
148138 ) ;
149139
150- let fn_name = tcx. item_name ( item_def_id) ;
151- tcx. sess . emit_err ( AbiOf {
152- span : tcx. def_span ( item_def_id) ,
153- fn_name,
154- fn_abi : format ! ( "{:#?}" , abi) ,
155- } ) ;
140+ let fn_name = tcx. item_name ( item_def_id. into ( ) ) ;
141+ tcx. sess . emit_err ( AbiOf { span, fn_name, fn_abi : format ! ( "{:#?}" , abi) } ) ;
156142 }
157143 sym:: assert_eq => {
158144 let ty:: Tuple ( fields) = ty. kind ( ) else {
@@ -196,7 +182,7 @@ fn dump_abi_of_fn_type(tcx: TyCtxt<'_>, item_def_id: DefId, attr: &Attribute) {
196182
197183 if !test_abi_eq ( abi1, abi2) {
198184 tcx. sess . emit_err ( AbiNe {
199- span : tcx . def_span ( item_def_id ) ,
185+ span,
200186 left : format ! ( "{:#?}" , abi1) ,
201187 right : format ! ( "{:#?}" , abi2) ,
202188 } ) ;
0 commit comments