Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion crates/hir_expand/src/db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ fn macro_expand_with_arg(
Some(it) => it,
None => return MacroResult::error("Fail to find macro definition".into()),
};
let ExpandResult(tt, err) = macro_rules.0.expand(db, lazy_id, &macro_arg.0);
let ExpandResult { value: tt, err } = macro_rules.0.expand(db, lazy_id, &macro_arg.0);
// Set a hard limit for the expanded tt
let count = tt.count();
if count > 262144 {
Expand Down
24 changes: 13 additions & 11 deletions crates/mbe/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -246,33 +246,35 @@ fn validate(pattern: &tt::Subtree) -> Result<(), ParseError> {
Ok(())
}

#[derive(Debug)]
pub struct ExpandResult<T>(pub T, pub Option<ExpandError>);
#[derive(Debug, Clone, Eq, PartialEq)]
pub struct ExpandResult<T> {
pub value: T,
pub err: Option<ExpandError>,
}

impl<T> ExpandResult<T> {
pub fn ok(t: T) -> ExpandResult<T> {
ExpandResult(t, None)
pub fn ok(value: T) -> Self {
Self { value, err: None }
}

pub fn only_err(err: ExpandError) -> ExpandResult<T>
pub fn only_err(err: ExpandError) -> Self
where
T: Default,
{
ExpandResult(Default::default(), Some(err))
Self { value: Default::default(), err: Some(err) }
}

pub fn map<U>(self, f: impl FnOnce(T) -> U) -> ExpandResult<U> {
ExpandResult(f(self.0), self.1)
ExpandResult { value: f(self.value), err: self.err }
}

pub fn result(self) -> Result<T, ExpandError> {
self.1.map(Err).unwrap_or(Ok(self.0))
self.err.map(Err).unwrap_or(Ok(self.value))
}
}

impl<T: Default> From<Result<T, ExpandError>> for ExpandResult<T> {
fn from(result: Result<T, ExpandError>) -> ExpandResult<T> {
result
.map_or_else(|e| ExpandResult(Default::default(), Some(e)), |it| ExpandResult(it, None))
fn from(result: Result<T, ExpandError>) -> Self {
result.map_or_else(|e| Self::only_err(e), |it| Self::ok(it))
}
}
15 changes: 9 additions & 6 deletions crates/mbe/src/mbe_expander.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,10 @@ fn expand_rules(rules: &[crate::Rule], input: &tt::Subtree) -> ExpandResult<tt::
// If we find a rule that applies without errors, we're done.
// Unconditionally returning the transcription here makes the
// `test_repeat_bad_var` test fail.
let ExpandResult(res, transcribe_err) =
let ExpandResult { value, err: transcribe_err } =
transcriber::transcribe(&rule.rhs, &new_match.bindings);
if transcribe_err.is_none() {
return ExpandResult::ok(res);
return ExpandResult::ok(value);
}
}
// Use the rule if we matched more tokens, or had fewer errors
Expand All @@ -47,11 +47,11 @@ fn expand_rules(rules: &[crate::Rule], input: &tt::Subtree) -> ExpandResult<tt::
}
if let Some((match_, rule)) = match_ {
// if we got here, there was no match without errors
let ExpandResult(result, transcribe_err) =
let ExpandResult { value, err: transcribe_err } =
transcriber::transcribe(&rule.rhs, &match_.bindings);
ExpandResult(result, match_.err.or(transcribe_err))
ExpandResult { value, err: match_.err.or(transcribe_err) }
} else {
ExpandResult(tt::Subtree::default(), Some(ExpandError::NoMatchingRule))
ExpandResult::only_err(ExpandError::NoMatchingRule)
}
}

Expand Down Expand Up @@ -143,7 +143,10 @@ mod tests {
}

fn assert_err(macro_body: &str, invocation: &str, err: ExpandError) {
assert_eq!(expand_first(&create_rules(&format_macro(macro_body)), invocation).1, Some(err));
assert_eq!(
expand_first(&create_rules(&format_macro(macro_body)), invocation).err,
Some(err)
);
}

fn format_macro(macro_body: &str) -> String {
Expand Down
9 changes: 5 additions & 4 deletions crates/mbe/src/mbe_expander/matcher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,8 @@ fn match_subtree(
continue;
}
};
let ExpandResult(matched, match_err) = match_meta_var(kind.as_str(), src);
let ExpandResult { value: matched, err: match_err } =
match_meta_var(kind.as_str(), src);
match matched {
Some(fragment) => {
res.bindings.inner.insert(name.clone(), Binding::Fragment(fragment));
Expand Down Expand Up @@ -342,17 +343,17 @@ impl<'a> TtIter<'a> {
token_trees: res.into_iter().cloned().collect(),
})),
};
ExpandResult(res, err)
ExpandResult { value: res, err }
}

pub(crate) fn eat_vis(&mut self) -> Option<tt::TokenTree> {
let mut fork = self.clone();
match fork.expect_fragment(Visibility) {
ExpandResult(tt, None) => {
ExpandResult { value: tt, err: None } => {
*self = fork;
tt
}
ExpandResult(_, Some(_)) => None,
ExpandResult { value: _, err: Some(_) } => None,
}
}
}
Expand Down
18 changes: 11 additions & 7 deletions crates/mbe/src/mbe_expander/transcriber.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,25 +93,26 @@ fn expand_subtree(
match op {
Op::TokenTree(tt @ tt::TokenTree::Leaf(..)) => arena.push(tt.clone()),
Op::TokenTree(tt::TokenTree::Subtree(tt)) => {
let ExpandResult(tt, e) = expand_subtree(ctx, tt, arena);
let ExpandResult { value: tt, err: e } = expand_subtree(ctx, tt, arena);
err = err.or(e);
arena.push(tt.into());
}
Op::Var { name, kind: _ } => {
let ExpandResult(fragment, e) = expand_var(ctx, name);
let ExpandResult { value: fragment, err: e } = expand_var(ctx, name);
err = err.or(e);
push_fragment(arena, fragment);
}
Op::Repeat { subtree, kind, separator } => {
let ExpandResult(fragment, e) = expand_repeat(ctx, subtree, kind, separator, arena);
let ExpandResult { value: fragment, err: e } =
expand_repeat(ctx, subtree, kind, separator, arena);
err = err.or(e);
push_fragment(arena, fragment)
}
}
}
// drain the elements added in this instance of expand_subtree
let tts = arena.drain(start_elements..arena.len()).collect();
ExpandResult(tt::Subtree { delimiter: template.delimiter, token_trees: tts }, err)
ExpandResult { value: tt::Subtree { delimiter: template.delimiter, token_trees: tts }, err }
}

fn expand_var(ctx: &mut ExpandCtx, v: &SmolStr) -> ExpandResult<Fragment> {
Expand Down Expand Up @@ -152,7 +153,7 @@ fn expand_var(ctx: &mut ExpandCtx, v: &SmolStr) -> ExpandResult<Fragment> {
ExpandResult::ok(Fragment::Tokens(tt))
} else {
ctx.bindings.get(&v, &mut ctx.nesting).map_or_else(
|e| ExpandResult(Fragment::Tokens(tt::TokenTree::empty()), Some(e)),
|e| ExpandResult { value: Fragment::Tokens(tt::TokenTree::empty()), err: Some(e) },
|b| ExpandResult::ok(b.clone()),
)
}
Expand All @@ -174,7 +175,7 @@ fn expand_repeat(
let mut counter = 0;

loop {
let ExpandResult(mut t, e) = expand_subtree(ctx, template, arena);
let ExpandResult { value: mut t, err: e } = expand_subtree(ctx, template, arena);
let nesting_state = ctx.nesting.last_mut().unwrap();
if nesting_state.at_end || !nesting_state.hit {
break;
Expand Down Expand Up @@ -234,7 +235,10 @@ fn expand_repeat(
let tt = tt::Subtree { delimiter: None, token_trees: buf }.into();

if RepeatKind::OneOrMore == kind && counter == 0 {
return ExpandResult(Fragment::Tokens(tt), Some(ExpandError::UnexpectedToken));
return ExpandResult {
value: Fragment::Tokens(tt),
err: Some(ExpandError::UnexpectedToken),
};
}
ExpandResult::ok(Fragment::Tokens(tt))
}
Expand Down