From d655749aaeb31461f9af923bbf0b36d219cff343 Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Mon, 16 Mar 2020 12:22:10 +0100 Subject: Turn ExpandResult into struct --- crates/ra_hir_expand/src/db.rs | 12 ++++------ crates/ra_mbe/src/lib.rs | 32 +++++++++++++++++++++++++-- crates/ra_mbe/src/mbe_expander.rs | 16 ++++++++------ crates/ra_mbe/src/mbe_expander/matcher.rs | 21 +++++++----------- crates/ra_mbe/src/mbe_expander/transcriber.rs | 22 +++++++++--------- crates/ra_mbe/src/tests.rs | 3 +-- 6 files changed, 63 insertions(+), 43 deletions(-) diff --git a/crates/ra_hir_expand/src/db.rs b/crates/ra_hir_expand/src/db.rs index f1918817e..d171d2dfd 100644 --- a/crates/ra_hir_expand/src/db.rs +++ b/crates/ra_hir_expand/src/db.rs @@ -2,7 +2,7 @@ use std::sync::Arc; -use mbe::MacroRules; +use mbe::{ExpandResult, MacroRules}; use ra_db::{salsa, SourceDatabase}; use ra_parser::FragmentKind; use ra_prof::profile; @@ -31,12 +31,8 @@ impl TokenExpander { match self { TokenExpander::MacroRules(it) => it.expand(tt), // FIXME switch these to ExpandResult as well - TokenExpander::Builtin(it) => it - .expand(db, id, tt) - .map_or_else(|e| (tt::Subtree::default(), Some(e)), |r| (r, None)), - TokenExpander::BuiltinDerive(it) => it - .expand(db, id, tt) - .map_or_else(|e| (tt::Subtree::default(), Some(e)), |r| (r, None)), + TokenExpander::Builtin(it) => it.expand(db, id, tt).into(), + TokenExpander::BuiltinDerive(it) => it.expand(db, id, tt).into(), } } @@ -204,7 +200,7 @@ fn macro_expand_with_arg( Some(it) => it, None => return (None, Some("Fail to find macro definition".into())), }; - let (tt, err) = macro_rules.0.expand(db, lazy_id, ¯o_arg.0); + let ExpandResult(tt, err) = macro_rules.0.expand(db, lazy_id, ¯o_arg.0); // Set a hard limit for the expanded tt let count = tt.count(); if count > 65536 { diff --git a/crates/ra_mbe/src/lib.rs b/crates/ra_mbe/src/lib.rs index 3adec4978..6a9037bfc 100644 --- a/crates/ra_mbe/src/lib.rs +++ b/crates/ra_mbe/src/lib.rs @@ -30,8 +30,6 @@ pub enum ExpandError { InvalidRepeat, } -pub type ExpandResult = (T, Option); - pub use crate::syntax_bridge::{ ast_to_token_tree, parse_to_token_tree, syntax_node_to_token_tree, token_tree_to_syntax_node, TokenMap, @@ -211,5 +209,35 @@ fn validate(pattern: &tt::Subtree) -> Result<(), ParseError> { Ok(()) } +pub struct ExpandResult(pub T, pub Option); + +impl ExpandResult { + pub fn ok(t: T) -> ExpandResult { + ExpandResult(t, None) + } + + pub fn only_err(err: ExpandError) -> ExpandResult + where + T: Default, + { + ExpandResult(Default::default(), Some(err)) + } + + pub fn map(self, f: impl FnOnce(T) -> U) -> ExpandResult { + ExpandResult(f(self.0), self.1) + } + + pub fn result(self) -> Result { + self.1.map(Err).unwrap_or(Ok(self.0)) + } +} + +impl From> for ExpandResult { + fn from(result: Result) -> ExpandResult { + result + .map_or_else(|e| ExpandResult(Default::default(), Some(e)), |it| ExpandResult(it, None)) + } +} + #[cfg(test)] mod tests; diff --git a/crates/ra_mbe/src/mbe_expander.rs b/crates/ra_mbe/src/mbe_expander.rs index 204c30e3d..0a4d73dda 100644 --- a/crates/ra_mbe/src/mbe_expander.rs +++ b/crates/ra_mbe/src/mbe_expander.rs @@ -18,12 +18,13 @@ fn expand_rules(rules: &[crate::Rule], input: &tt::Subtree) -> ExpandResult = None; let mut err = Some(ExpandError::NoMatchingRule); for rule in rules { - let (new_match, bindings_err) = matcher::match_(&rule.lhs, input); + let ExpandResult(new_match, bindings_err) = matcher::match_(&rule.lhs, input); if bindings_err.is_none() { // if we find a rule that applies without errors, we're done - let (res, transcribe_err) = transcriber::transcribe(&rule.rhs, &new_match.bindings); + let ExpandResult(res, transcribe_err) = + transcriber::transcribe(&rule.rhs, &new_match.bindings); if transcribe_err.is_none() { - return (res, None); + return ExpandResult::ok(res); } } // use the rule if we matched more tokens, or had fewer patterns left @@ -43,10 +44,11 @@ fn expand_rules(rules: &[crate::Rule], input: &tt::Subtree) -> ExpandResult ExpandResult { res.bindings.inner.insert(name.clone(), Binding::Fragment(fragment)); @@ -308,17 +308,17 @@ impl<'a> TtIter<'a> { token_trees: res.into_iter().cloned().collect(), })), }; - (res, err) + ExpandResult(res, err) } pub(crate) fn eat_vis(&mut self) -> Option { let mut fork = self.clone(); match fork.expect_fragment(Visibility) { - (tt, None) => { + ExpandResult(tt, None) => { *self = fork; tt } - (_, Some(_)) => None, + ExpandResult(_, Some(_)) => None, } } } @@ -419,12 +419,11 @@ fn match_meta_var(kind: &str, input: &mut TtIter) -> ExpandResult Err(ExpandError::UnexpectedToken), }; - return to_expand_result(tt_result.map(|it| it.map(Fragment::Tokens))); + return tt_result.map(|it| it.map(Fragment::Tokens)).into(); } }; - let (tt, err) = input.expect_fragment(fragment); - let fragment = if kind == "expr" { tt.map(Fragment::Ast) } else { tt.map(Fragment::Tokens) }; - (fragment, err) + let result = input.expect_fragment(fragment); + result.map(|tt| if kind == "expr" { tt.map(Fragment::Ast) } else { tt.map(Fragment::Tokens) }) } fn collect_vars(buf: &mut Vec, pattern: &tt::Subtree) -> Result<(), ExpandError> { @@ -438,7 +437,3 @@ fn collect_vars(buf: &mut Vec, pattern: &tt::Subtree) -> Result<(), Exp } Ok(()) } - -fn to_expand_result(result: Result) -> ExpandResult { - result.map_or_else(|e| (Default::default(), Some(e)), |it| (it, None)) -} diff --git a/crates/ra_mbe/src/mbe_expander/transcriber.rs b/crates/ra_mbe/src/mbe_expander/transcriber.rs index c53c2d35e..4b173edd3 100644 --- a/crates/ra_mbe/src/mbe_expander/transcriber.rs +++ b/crates/ra_mbe/src/mbe_expander/transcriber.rs @@ -87,23 +87,23 @@ fn expand_subtree(ctx: &mut ExpandCtx, template: &tt::Subtree) -> ExpandResult buf.push(tt.clone()), Op::TokenTree(tt::TokenTree::Subtree(tt)) => { - let (tt, e) = expand_subtree(ctx, tt); + let ExpandResult(tt, e) = expand_subtree(ctx, tt); err = err.or(e); buf.push(tt.into()); } Op::Var { name, kind: _ } => { - let (fragment, e) = expand_var(ctx, name); + let ExpandResult(fragment, e) = expand_var(ctx, name); err = err.or(e); push_fragment(&mut buf, fragment); } Op::Repeat { subtree, kind, separator } => { - let (fragment, e) = expand_repeat(ctx, subtree, kind, separator); + let ExpandResult(fragment, e) = expand_repeat(ctx, subtree, kind, separator); err = err.or(e); push_fragment(&mut buf, fragment) } } } - (tt::Subtree { delimiter: template.delimiter, token_trees: buf }, err) + ExpandResult(tt::Subtree { delimiter: template.delimiter, token_trees: buf }, err) } fn expand_var(ctx: &mut ExpandCtx, v: &SmolStr) -> ExpandResult { @@ -112,7 +112,7 @@ fn expand_var(ctx: &mut ExpandCtx, v: &SmolStr) -> ExpandResult { let tt = tt::Leaf::from(tt::Ident { text: "$crate".into(), id: tt::TokenId::unspecified() }) .into(); - (Fragment::Tokens(tt), None) + ExpandResult::ok(Fragment::Tokens(tt)) } else if !ctx.bindings.contains(v) { // Note that it is possible to have a `$var` inside a macro which is not bound. // For example: @@ -141,11 +141,11 @@ fn expand_var(ctx: &mut ExpandCtx, v: &SmolStr) -> ExpandResult { ], } .into(); - (Fragment::Tokens(tt), None) + ExpandResult::ok(Fragment::Tokens(tt)) } else { ctx.bindings.get(&v, &mut ctx.nesting).map_or_else( - |e| (Fragment::Tokens(tt::TokenTree::empty()), Some(e)), - |b| (b.clone(), None), + |e| ExpandResult(Fragment::Tokens(tt::TokenTree::empty()), Some(e)), + |b| ExpandResult::ok(b.clone()), ) } } @@ -165,7 +165,7 @@ fn expand_repeat( let mut counter = 0; loop { - let (mut t, e) = expand_subtree(ctx, template); + let ExpandResult(mut t, e) = expand_subtree(ctx, template); let nesting_state = ctx.nesting.last_mut().unwrap(); if nesting_state.at_end || !nesting_state.hit { break; @@ -225,9 +225,9 @@ fn expand_repeat( let tt = tt::Subtree { delimiter: None, token_trees: buf }.into(); if RepeatKind::OneOrMore == kind && counter == 0 { - return (Fragment::Tokens(tt), Some(ExpandError::UnexpectedToken)); + return ExpandResult(Fragment::Tokens(tt), Some(ExpandError::UnexpectedToken)); } - (Fragment::Tokens(tt), None) + ExpandResult::ok(Fragment::Tokens(tt)) } fn push_fragment(buf: &mut Vec, fragment: Fragment) { diff --git a/crates/ra_mbe/src/tests.rs b/crates/ra_mbe/src/tests.rs index faf88c1b1..44f381938 100644 --- a/crates/ra_mbe/src/tests.rs +++ b/crates/ra_mbe/src/tests.rs @@ -1430,8 +1430,7 @@ impl MacroFixture { let (invocation_tt, _) = ast_to_token_tree(¯o_invocation.token_tree().unwrap()).unwrap(); - let (tt, err) = self.rules.expand(&invocation_tt); - err.map(Err).unwrap_or(Ok(tt)) + self.rules.expand(&invocation_tt).result() } fn assert_expand_err(&self, invocation: &str, err: &ExpandError) { -- cgit v1.2.3