@@ -3630,11 +3630,24 @@ fn check_function(
36303630 function : & mut Function ,
36313631 rtypes : & ResolutionTypes ,
36323632) -> Result < ( ) , VirErr > {
3633- // Reset this, we only need it per-function
3634- record. type_inv_info = TypeInvInfo { ctor_needs_check : HashMap :: new ( ) } ;
3635- record. var_modes = HashMap :: new ( ) ;
3636- record. temporary_modes = HashMap :: new ( ) ;
3637- record. mut_bor_place_modes = HashMap :: new ( ) ;
3633+ let Record {
3634+ // Global fields
3635+ erasure_modes : _,
3636+ // Per-function fields
3637+ type_inv_info,
3638+ read_kind_finals,
3639+ var_modes,
3640+ temporary_modes,
3641+ infer_spec_for_implicit_reborrows,
3642+ mut_bor_place_modes,
3643+ } = record;
3644+ // Reset the fields that are per-function
3645+ * type_inv_info = TypeInvInfo { ctor_needs_check : HashMap :: new ( ) } ;
3646+ * read_kind_finals = HashMap :: new ( ) ;
3647+ * var_modes = HashMap :: new ( ) ;
3648+ * temporary_modes = HashMap :: new ( ) ;
3649+ * infer_spec_for_implicit_reborrows = None ;
3650+ * mut_bor_place_modes = HashMap :: new ( ) ;
36383651
36393652 let mut fun_typing = typing. push_var_scope ( ) ;
36403653
@@ -3837,6 +3850,11 @@ fn check_function(
38373850 let mut body_typing = fun_typing. push_ret_mode ( ret_mode) ;
38383851 let mut body_typing = body_typing. push_block_ghostness ( Ghost :: of_mode ( function. x . mode ) ) ;
38393852 let mut body_typing = body_typing. push_in_pure ( pure_spec_fn) ;
3853+ let mut body_typing = if function. x . attrs . atomic {
3854+ body_typing. push_atomic_insts ( Some ( AtomicInstCollector :: new ( ) ) )
3855+ } else {
3856+ body_typing
3857+ } ;
38403858
38413859 assert ! ( record. infer_spec_for_implicit_reborrows. is_none( ) ) ;
38423860 record. infer_spec_for_implicit_reborrows = Some ( HashMap :: new ( ) ) ;
@@ -3862,6 +3880,14 @@ fn check_function(
38623880 ) ?;
38633881 }
38643882
3883+ if function. x . attrs . atomic {
3884+ body_typing
3885+ . atomic_insts
3886+ . as_ref ( )
3887+ . expect ( "atomic_insts" )
3888+ . validate ( & function. span , ValidateCtx :: AtomicFunction ) ?;
3889+ }
3890+
38653891 let borrow_spec = record. infer_spec_for_implicit_reborrows . as_ref ( ) . expect ( "borrow_spec" ) ;
38663892 if borrow_spec. len ( ) > 0 {
38673893 let mut functionx = function. x . clone ( ) ;
@@ -3948,7 +3974,7 @@ fn check_function(
39483974 Ok ( ( ) )
39493975}
39503976
3951- pub fn check_crate ( krate : & Krate ) -> Result < ( Krate , ErasureModes , ReadKindFinals ) , VirErr > {
3977+ pub fn check_crate ( krate : & Krate ) -> Result < ( Krate , ErasureModes , ReadKindFinals ) , Vec < VirErr > > {
39523978 let mut funs: HashMap < Fun , Function > = HashMap :: new ( ) ;
39533979 let mut datatypes: HashMap < Path , Datatype > = HashMap :: new ( ) ;
39543980 for function in krate. functions . iter ( ) {
@@ -3984,33 +4010,33 @@ pub fn check_crate(krate: &Krate) -> Result<(Krate, ErasureModes, ReadKindFinals
39844010 infer_spec_for_implicit_reborrows : None ,
39854011 mut_bor_place_modes : HashMap :: new ( ) ,
39864012 } ;
3987- let mut state = State {
3988- vars : ScopeMap :: new ( ) ,
3989- in_forall_stmt : false ,
3990- in_proof_in_spec : false ,
3991- block_ghostness : Ghost :: Exec ,
3992- ret_mode : None ,
3993- atomic_insts : None ,
3994- in_pure : false ,
3995- in_assert_query : None ,
3996- } ;
3997- let mut typing = Typing :: new ( & mut state) ;
4013+
39984014 let mut kratex = ( * * krate) . clone ( ) ;
39994015 let rtypes = ResolutionTypes :: new ( & ctxt. datatypes ) ;
4016+ let mut errors = vec ! [ ] ;
40004017 for function in kratex. functions . iter_mut ( ) {
40014018 ctxt. check_ghost_blocks = function. x . attrs . uses_ghost_blocks ;
40024019 ctxt. fun_mode = function. x . mode ;
4003- if function. x . attrs . atomic {
4004- let mut typing = typing. push_atomic_insts ( Some ( AtomicInstCollector :: new ( ) ) ) ;
4005- check_function ( & ctxt, & mut record, & mut typing, function, & rtypes) ?;
4006- typing
4007- . atomic_insts
4008- . as_ref ( )
4009- . expect ( "atomic_insts" )
4010- . validate ( & function. span , ValidateCtx :: AtomicFunction ) ?;
4011- } else {
4012- check_function ( & ctxt, & mut record, & mut typing, function, & rtypes) ?;
4020+
4021+ let mut state = State {
4022+ vars : ScopeMap :: new ( ) ,
4023+ in_forall_stmt : false ,
4024+ in_proof_in_spec : false ,
4025+ block_ghostness : Ghost :: Exec ,
4026+ ret_mode : None ,
4027+ atomic_insts : None ,
4028+ in_pure : false ,
4029+ in_assert_query : None ,
4030+ } ;
4031+ let mut typing = Typing :: new ( & mut state) ;
4032+
4033+ if let Err ( err) = check_function ( & ctxt, & mut record, & mut typing, function, & rtypes) {
4034+ errors. push ( err) ;
40134035 }
40144036 }
4015- Ok ( ( Arc :: new ( kratex) , record. erasure_modes , record. read_kind_finals ) )
4037+ if errors. len ( ) > 0 {
4038+ Err ( errors)
4039+ } else {
4040+ Ok ( ( Arc :: new ( kratex) , record. erasure_modes , record. read_kind_finals ) )
4041+ }
40164042}
0 commit comments