@@ -13,6 +13,7 @@ use rustc_ast::Attribute;
13
13
use rustc_hir:: def:: DefKind ;
14
14
use rustc_hir:: def_id:: DefId ;
15
15
use rustc_middle:: mir:: { HasLocalDecls , Local } ;
16
+ use rustc_middle:: ty:: layout:: FnAbiOf ;
16
17
use rustc_middle:: ty:: { self , Instance } ;
17
18
use std:: collections:: BTreeMap ;
18
19
use std:: convert:: TryInto ;
@@ -232,46 +233,46 @@ impl<'tcx> GotocCtx<'tcx> {
232
233
self . reset_current_fn ( ) ;
233
234
}
234
235
235
- pub fn is_proof_harness ( & self , def_id : DefId ) -> bool {
236
- let all_attributes = self . tcx . get_attrs_unchecked ( def_id) ;
237
- let ( proof_attributes, _) = partition_kanitool_attributes ( all_attributes) ;
238
- if !proof_attributes. is_empty ( ) {
239
- let span = proof_attributes. first ( ) . unwrap ( ) . span ;
240
- if self . tcx . def_kind ( def_id) != DefKind :: Fn {
241
- self . tcx
242
- . sess
243
- . span_err ( span, "The kani::proof attribute can only be applied to functions." ) ;
244
- } else if self . tcx . generics_of ( def_id) . requires_monomorphization ( self . tcx ) {
236
+ /// Check that if an item is tagged with a proof_attribute, it is a valid harness.
237
+ fn check_proof_attribute ( & self , def_id : DefId , proof_attributes : Vec < & Attribute > ) {
238
+ assert ! ( !proof_attributes. is_empty( ) ) ;
239
+ let span = proof_attributes. first ( ) . unwrap ( ) . span ;
240
+ if proof_attributes. len ( ) > 1 {
241
+ self . tcx . sess . span_warn ( proof_attributes[ 0 ] . span , "Duplicate attribute" ) ;
242
+ }
243
+
244
+ if self . tcx . def_kind ( def_id) != DefKind :: Fn {
245
+ self . tcx
246
+ . sess
247
+ . span_err ( span, "The kani::proof attribute can only be applied to functions." ) ;
248
+ } else if self . tcx . generics_of ( def_id) . requires_monomorphization ( self . tcx ) {
249
+ self . tcx
250
+ . sess
251
+ . span_err ( span, "The proof attribute cannot be applied to generic functions." ) ;
252
+ } else {
253
+ let instance = Instance :: mono ( self . tcx , def_id) ;
254
+ if !self . fn_abi_of_instance ( instance, ty:: List :: empty ( ) ) . args . is_empty ( ) {
245
255
self . tcx
246
256
. sess
247
- . span_err ( span, "The proof attribute cannot be applied to generic functions ." ) ;
257
+ . span_err ( span, "Functions used as harnesses can not have any arguments ." ) ;
248
258
}
249
- self . tcx . sess . abort_if_errors ( ) ;
250
- true
251
- } else {
252
- false
253
259
}
254
260
}
255
261
256
- // Check that all attributes assigned to an item is valid.
262
+ pub fn is_proof_harness ( & self , def_id : DefId ) -> bool {
263
+ let all_attributes = self . tcx . get_attrs_unchecked ( def_id) ;
264
+ let ( proof_attributes, _) = partition_kanitool_attributes ( all_attributes) ;
265
+ !proof_attributes. is_empty ( )
266
+ }
267
+
268
+ /// Check that all attributes assigned to an item is valid.
269
+ /// Errors will be added to the session. Invoke self.tcx.sess.abort_if_errors() to terminate
270
+ /// the session in case of an error.
257
271
pub fn check_attributes ( & self , def_id : DefId ) {
258
272
let all_attributes = self . tcx . get_attrs_unchecked ( def_id) ;
259
273
let ( proof_attributes, other_attributes) = partition_kanitool_attributes ( all_attributes) ;
260
274
if !proof_attributes. is_empty ( ) {
261
- let span = proof_attributes. first ( ) . unwrap ( ) . span ;
262
- if self . tcx . def_kind ( def_id) != DefKind :: Fn {
263
- self . tcx
264
- . sess
265
- . span_err ( span, "The kani::proof attribute can only be applied to functions." ) ;
266
- } else if self . tcx . generics_of ( def_id) . requires_monomorphization ( self . tcx ) {
267
- self . tcx
268
- . sess
269
- . span_err ( span, "The proof attribute cannot be applied to generic functions." ) ;
270
- } else if proof_attributes. len ( ) > 1 {
271
- self . tcx
272
- . sess
273
- . span_warn ( proof_attributes[ 0 ] . span , "Only one '#[kani::proof]' allowed" ) ;
274
- }
275
+ self . check_proof_attribute ( def_id, proof_attributes) ;
275
276
} else if !other_attributes. is_empty ( ) {
276
277
self . tcx . sess . span_err (
277
278
other_attributes[ 0 ] . 1 . span ,
0 commit comments