mirror of https://codeberg.org/topola/topola.git
contracts: Put contract-bound function body in a `try` block if needed
This makes Topola dependent on nightly Rust. If `try` blocks aren't stabilized before the first release, we'll trivially just undo this change temporarily, as contracts are just elaborate assertions.
This commit is contained in:
parent
0cf7c718f3
commit
f0e2ba6e3a
|
|
@ -1,3 +1,4 @@
|
|||
#![feature(try_blocks)]
|
||||
extern crate sdl2;
|
||||
|
||||
macro_rules! dbg_dot {
|
||||
|
|
|
|||
|
|
@ -5,8 +5,8 @@
|
|||
use proc_macro2::{Ident, Span, TokenStream};
|
||||
use quote::ToTokens;
|
||||
use syn::{
|
||||
spanned::Spanned, visit_mut as visitor, Attribute, Expr, ExprCall,
|
||||
ReturnType, TypeImplTrait,
|
||||
spanned::Spanned, visit_mut as visitor, Attribute, Expr, ExprCall, ExprTry,
|
||||
ReturnType, Type, TypeImplTrait,
|
||||
};
|
||||
|
||||
use crate::implementation::{
|
||||
|
|
@ -341,7 +341,14 @@ pub(crate) fn generate(
|
|||
if let ReturnType::Type(.., ref return_type) =
|
||||
func.function.sig.output
|
||||
{
|
||||
break 'blk quote::quote! { let ret: #return_type = 'run: #block; };
|
||||
let mut try_detector = TryDetector { found_try: false };
|
||||
syn::visit::visit_block(&mut try_detector, &mut block);
|
||||
|
||||
if try_detector.found_try {
|
||||
break 'blk quote::quote! { let ret: #return_type = 'run: { try { #block? } }; };
|
||||
} else {
|
||||
break 'blk quote::quote! { let ret: #return_type = 'run: #block; };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -401,3 +408,13 @@ impl<'a> syn::visit::Visit<'a> for ImplDetector {
|
|||
self.found_impl = true;
|
||||
}
|
||||
}
|
||||
|
||||
struct TryDetector {
|
||||
found_try: bool,
|
||||
}
|
||||
|
||||
impl<'a> syn::visit::Visit<'a> for TryDetector {
|
||||
fn visit_expr_try(&mut self, _node: &'a ExprTry) {
|
||||
self.found_try = true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue