1
1
use rustc_ast:: Attribute ;
2
2
use rustc_hir:: def:: DefKind ;
3
- use rustc_hir:: def_id:: DefId ;
3
+ use rustc_hir:: def_id:: LocalDefId ;
4
4
use rustc_middle:: ty:: layout:: { FnAbiError , LayoutError } ;
5
5
use rustc_middle:: ty:: { self , GenericArgs , Instance , Ty , TyCtxt } ;
6
6
use rustc_span:: source_map:: Spanned ;
7
7
use rustc_span:: symbol:: sym;
8
8
use rustc_target:: abi:: call:: FnAbi ;
9
9
10
+ use super :: layout_test:: ensure_wf;
10
11
use crate :: errors:: { AbiInvalidAttribute , AbiNe , AbiOf , UnrecognizedField } ;
11
12
12
13
pub fn test_abi ( tcx : TyCtxt < ' _ > ) {
13
14
if !tcx. features ( ) . rustc_attrs {
14
15
// if the `rustc_attrs` feature is not enabled, don't bother testing ABI
15
16
return ;
16
17
}
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) ;
22
23
}
23
24
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) ;
25
26
}
26
27
_ => {
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) } ) ;
43
29
}
44
30
}
45
31
}
@@ -49,7 +35,7 @@ pub fn test_abi(tcx: TyCtxt<'_>) {
49
35
fn unwrap_fn_abi < ' tcx > (
50
36
abi : Result < & ' tcx FnAbi < ' tcx , Ty < ' tcx > > , & ' tcx FnAbiError < ' tcx > > ,
51
37
tcx : TyCtxt < ' tcx > ,
52
- item_def_id : DefId ,
38
+ item_def_id : LocalDefId ,
53
39
) -> & ' tcx FnAbi < ' tcx , Ty < ' tcx > > {
54
40
match abi {
55
41
Ok ( abi) => abi,
@@ -71,10 +57,10 @@ fn unwrap_fn_abi<'tcx>(
71
57
}
72
58
}
73
59
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 ) {
75
61
let param_env = tcx. param_env ( item_def_id) ;
76
62
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) {
78
64
Ok ( Some ( instance) ) => instance,
79
65
Ok ( None ) => {
80
66
// 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) {
99
85
for meta_item in meta_items {
100
86
match meta_item. name_or_empty ( ) {
101
87
sym:: debug => {
102
- let fn_name = tcx. item_name ( item_def_id) ;
88
+ let fn_name = tcx. item_name ( item_def_id. into ( ) ) ;
103
89
tcx. sess . emit_err ( AbiOf {
104
90
span : tcx. def_span ( item_def_id) ,
105
91
fn_name,
@@ -128,9 +114,13 @@ fn test_abi_eq<'tcx>(abi1: &'tcx FnAbi<'tcx, Ty<'tcx>>, abi2: &'tcx FnAbi<'tcx,
128
114
&& abi1. args . iter ( ) . zip ( abi2. args . iter ( ) ) . all ( |( arg1, arg2) | arg1. eq_abi ( arg2) )
129
115
}
130
116
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 ) {
132
118
let param_env = tcx. param_env ( item_def_id) ;
133
119
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
+ }
134
124
let meta_items = attr. meta_item_list ( ) . unwrap_or_default ( ) ;
135
125
for meta_item in meta_items {
136
126
match meta_item. name_or_empty ( ) {
@@ -147,12 +137,8 @@ fn dump_abi_of_fn_type(tcx: TyCtxt<'_>, item_def_id: DefId, attr: &Attribute) {
147
137
item_def_id,
148
138
) ;
149
139
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) } ) ;
156
142
}
157
143
sym:: assert_eq => {
158
144
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) {
196
182
197
183
if !test_abi_eq ( abi1, abi2) {
198
184
tcx. sess . emit_err ( AbiNe {
199
- span : tcx . def_span ( item_def_id ) ,
185
+ span,
200
186
left : format ! ( "{:#?}" , abi1) ,
201
187
right : format ! ( "{:#?}" , abi2) ,
202
188
} ) ;
0 commit comments