diff --git a/shared/yeast-macros/src/parse.rs b/shared/yeast-macros/src/parse.rs index 594a59e1b5d..fda419aefc7 100644 --- a/shared/yeast-macros/src/parse.rs +++ b/shared/yeast-macros/src/parse.rs @@ -891,7 +891,8 @@ pub fn parse_rule_top(input: TokenStream) -> Result { yeast::Rule::new(__query, Box::new(|__ast: &mut yeast::Ast, __captures: yeast::captures::Captures, __fresh: &yeast::tree_builder::FreshScope, __source_range: Option, __user_ctx: &mut _| { #(#bindings)* let mut #ctx_ident = yeast::build::BuildCtx::with_source_range(__ast, &__captures, __fresh, __source_range, __user_ctx); - #transform_body + let __result: Vec = { #transform_body }; + Ok(__result) })) } }) diff --git a/shared/yeast/src/lib.rs b/shared/yeast/src/lib.rs index d93a72221a9..0b0c00ec910 100644 --- a/shared/yeast/src/lib.rs +++ b/shared/yeast/src/lib.rs @@ -703,7 +703,9 @@ impl From for NodeContent { /// The transform function for a rule: takes the AST, captured variables, a /// fresh-name scope, the source range of the matched node, and a mutable /// reference to the user context of type `C`. Returns the IDs of the -/// replacement nodes. +/// replacement nodes, or an error message if the transform could not be +/// completed (for example, a required capture was missing, or a recursive +/// translation invoked by the transform failed). pub type Transform = Box< dyn Fn( &mut Ast, @@ -711,7 +713,7 @@ pub type Transform = Box< &tree_builder::FreshScope, Option, &mut C, - ) -> Vec + ) -> Result, String> + Send + Sync, >; @@ -752,7 +754,7 @@ impl Rule { user_ctx: &mut C, ) -> Result>, String> { match self.try_match(ast, node)? { - Some(captures) => Ok(Some(self.run_transform(ast, captures, node, fresh, user_ctx))), + Some(captures) => Ok(Some(self.run_transform(ast, captures, node, fresh, user_ctx)?)), None => Ok(None), } } @@ -777,7 +779,7 @@ impl Rule { node: Id, fresh: &tree_builder::FreshScope, user_ctx: &mut C, - ) -> Vec { + ) -> Result, String> { fresh.next_scope(); let source_range = ast.get_node(node).and_then(|n| match n.content { NodeContent::Range(r) => Some(r), @@ -974,7 +976,7 @@ fn apply_one_shot_rules_inner( } apply_one_shot_rules_inner(index, ast, user_ctx, captured_id, fresh, rewrite_depth + 1) })?; - let result = rule.run_transform(ast, captures, id, fresh, user_ctx); + let result = rule.run_transform(ast, captures, id, fresh, user_ctx)?; *user_ctx = snapshot; return Ok(result); }