@@ -43,7 +43,7 @@ use syn::{Expr, Item, ItemConst, parse2, spanned::Spanned};
4343use crate :: {
4444 EraseGhost ,
4545 attr_block_trait:: { AnyAttrBlock , AnyFnOrLoop } ,
46- syntax:: { self , mk_verifier_attr_syn, mk_verus_attr_syn} ,
46+ syntax:: { self , has_external_code_syn , mk_verifier_attr_syn, mk_verus_attr_syn} ,
4747 syntax_trait,
4848 unerased_proxies:: VERUS_UNERASED_PROXY ,
4949} ;
@@ -159,7 +159,7 @@ pub(crate) fn rewrite_verus_attribute(
159159 spec_f. sig . ident = ident. clone ( ) ;
160160 spec_f. attrs = vec ! [ mk_verus_attr_syn( f. span( ) , quote! { spec } ) ] ;
161161 // remove proof-related macros
162- replace_block ( EraseGhost :: Erase , spec_f. block_mut ( ) . unwrap ( ) ) ;
162+ replace_block ( EraseGhost :: Erase , spec_f. block_mut ( ) . unwrap ( ) , false ) ;
163163 spec_fun = Some ( spec_f) ;
164164
165165 attributes
@@ -194,6 +194,7 @@ pub(crate) fn rewrite_verus_attribute(
194194
195195struct ExecReplacer {
196196 erase : EraseGhost ,
197+ inside_external_code : bool ,
197198}
198199
199200impl VisitMut for ExecReplacer {
@@ -202,7 +203,7 @@ impl VisitMut for ExecReplacer {
202203 fn visit_macro_mut ( & mut self , mac : & mut syn:: Macro ) {
203204 syn:: visit_mut:: visit_macro_mut ( self , mac) ;
204205 // Only replace in verification mode
205- if !self . erase . keep ( ) {
206+ if !self . erase . keep ( ) || self . inside_external_code {
206207 return ;
207208 }
208209 if let Some ( x) = mac. path . segments . first_mut ( ) {
@@ -291,7 +292,7 @@ impl VisitMut for ExecReplacer {
291292 fn visit_expr_for_loop_mut ( & mut self , for_loop : & mut syn:: ExprForLoop ) {
292293 syn:: visit_mut:: visit_expr_for_loop_mut ( self , for_loop) ;
293294
294- if !self . erase . keep ( ) {
295+ if !self . erase . keep ( ) || self . inside_external_code {
295296 return ;
296297 }
297298
@@ -370,13 +371,17 @@ fn is_verus_proof_stmt(stmt: &syn::Stmt) -> bool {
370371// TODO: when tracked/ghost is supported, we need to clear verus-related
371372// attributes for expression so that unverfied `cargo build` does not need to
372373// enable unstable feature for macro.
373- pub ( crate ) fn replace_block ( erase : EraseGhost , fblock : & mut syn:: Block ) {
374- let mut replacer = ExecReplacer { erase } ;
374+ pub ( crate ) fn replace_block (
375+ erase : EraseGhost ,
376+ fblock : & mut syn:: Block ,
377+ inside_external_code : bool ,
378+ ) {
379+ let mut replacer = ExecReplacer { erase, inside_external_code } ;
375380 replacer. visit_block_mut ( fblock) ;
376381}
377382
378383pub ( crate ) fn replace_expr ( erase : EraseGhost , expr : & mut syn:: Expr ) {
379- let mut replacer = ExecReplacer { erase } ;
384+ let mut replacer = ExecReplacer { erase, inside_external_code : false } ;
380385 replacer. visit_expr_mut ( expr) ;
381386}
382387
@@ -637,7 +642,8 @@ pub(crate) fn rewrite_verus_spec_on_fun_or_loop(
637642 let _ = fun. block_mut ( ) . unwrap ( ) . stmts . splice ( 0 ..0 , new_stmts) ;
638643
639644 // Parse and replace proof_xxx!() inside function and replace panic.
640- replace_block ( erase, fun. block_mut ( ) . unwrap ( ) ) ;
645+ let inside_external_code = has_external_code_syn ( & fun. attrs ) ;
646+ replace_block ( erase, fun. block_mut ( ) . unwrap ( ) , inside_external_code) ;
641647 fun. to_tokens ( & mut new_stream) ;
642648 proc_macro:: TokenStream :: from ( new_stream)
643649 }
@@ -974,7 +980,8 @@ fn rewrite_const_ret_proxy(const_fun: &mut syn::ItemFn) -> syn::ItemFn {
974980 // But just do it to be safe and consistent with verus macro.
975981 let span = const_fun. sig . constness . unwrap ( ) . span ( ) ;
976982 let mut proxy_fun = const_fun. clone ( ) ;
977- replace_block ( EraseGhost :: Erase , const_fun. block_mut ( ) . unwrap ( ) ) ;
983+ let inside_external_code = has_external_code_syn ( & const_fun. attrs ) ;
984+ replace_block ( EraseGhost :: Erase , const_fun. block_mut ( ) . unwrap ( ) , inside_external_code) ;
978985 const_fun. attrs . push ( mk_verifier_attr_syn ( span, quote ! { external } ) ) ;
979986 const_fun. attrs . push ( mk_verus_attr_syn ( span, quote ! { uses_unerased_proxy } ) ) ;
980987 const_fun. attrs . push ( mk_verus_attr_syn ( span, quote ! { encoded_const } ) ) ;
0 commit comments