mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-26 04:53:34 +00:00
Use named fields in ExpandResult
This commit is contained in:
parent
0bcd8147ec
commit
c784c8ec76
5 changed files with 39 additions and 29 deletions
|
@ -242,7 +242,7 @@ fn macro_expand_with_arg(
|
||||||
Some(it) => it,
|
Some(it) => it,
|
||||||
None => return MacroResult::error("Fail to find macro definition".into()),
|
None => return MacroResult::error("Fail to find macro definition".into()),
|
||||||
};
|
};
|
||||||
let ExpandResult(tt, err) = macro_rules.0.expand(db, lazy_id, ¯o_arg.0);
|
let ExpandResult { value: tt, err } = macro_rules.0.expand(db, lazy_id, ¯o_arg.0);
|
||||||
// Set a hard limit for the expanded tt
|
// Set a hard limit for the expanded tt
|
||||||
let count = tt.count();
|
let count = tt.count();
|
||||||
if count > 262144 {
|
if count > 262144 {
|
||||||
|
|
|
@ -246,33 +246,35 @@ fn validate(pattern: &tt::Subtree) -> Result<(), ParseError> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||||
pub struct ExpandResult<T>(pub T, pub Option<ExpandError>);
|
pub struct ExpandResult<T> {
|
||||||
|
pub value: T,
|
||||||
|
pub err: Option<ExpandError>,
|
||||||
|
}
|
||||||
|
|
||||||
impl<T> ExpandResult<T> {
|
impl<T> ExpandResult<T> {
|
||||||
pub fn ok(t: T) -> ExpandResult<T> {
|
pub fn ok(value: T) -> Self {
|
||||||
ExpandResult(t, None)
|
Self { value, err: None }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn only_err(err: ExpandError) -> ExpandResult<T>
|
pub fn only_err(err: ExpandError) -> Self
|
||||||
where
|
where
|
||||||
T: Default,
|
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> {
|
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> {
|
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> {
|
impl<T: Default> From<Result<T, ExpandError>> for ExpandResult<T> {
|
||||||
fn from(result: Result<T, ExpandError>) -> ExpandResult<T> {
|
fn from(result: Result<T, ExpandError>) -> Self {
|
||||||
result
|
result.map_or_else(|e| Self::only_err(e), |it| Self::ok(it))
|
||||||
.map_or_else(|e| ExpandResult(Default::default(), Some(e)), |it| ExpandResult(it, None))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.
|
// If we find a rule that applies without errors, we're done.
|
||||||
// Unconditionally returning the transcription here makes the
|
// Unconditionally returning the transcription here makes the
|
||||||
// `test_repeat_bad_var` test fail.
|
// `test_repeat_bad_var` test fail.
|
||||||
let ExpandResult(res, transcribe_err) =
|
let ExpandResult { value, err: transcribe_err } =
|
||||||
transcriber::transcribe(&rule.rhs, &new_match.bindings);
|
transcriber::transcribe(&rule.rhs, &new_match.bindings);
|
||||||
if transcribe_err.is_none() {
|
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
|
// Use the rule if we matched more tokens, or had fewer errors
|
||||||
|
@ -47,11 +47,11 @@ fn expand_rules(rules: &[crate::Rule], input: &tt::Subtree) -> ExpandResult<tt::
|
||||||
}
|
}
|
||||||
if let Some((match_, rule)) = match_ {
|
if let Some((match_, rule)) = match_ {
|
||||||
// if we got here, there was no match without errors
|
// 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);
|
transcriber::transcribe(&rule.rhs, &match_.bindings);
|
||||||
ExpandResult(result, match_.err.or(transcribe_err))
|
ExpandResult { value, err: match_.err.or(transcribe_err) }
|
||||||
} else {
|
} else {
|
||||||
ExpandResult(tt::Subtree::default(), Some(ExpandError::NoMatchingRule))
|
ExpandResult::only_err(ExpandError::NoMatchingRule)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -143,7 +143,10 @@ mod tests {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn assert_err(macro_body: &str, invocation: &str, err: ExpandError) {
|
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 {
|
fn format_macro(macro_body: &str) -> String {
|
||||||
|
|
|
@ -158,7 +158,8 @@ fn match_subtree(
|
||||||
continue;
|
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 {
|
match matched {
|
||||||
Some(fragment) => {
|
Some(fragment) => {
|
||||||
res.bindings.inner.insert(name.clone(), Binding::Fragment(fragment));
|
res.bindings.inner.insert(name.clone(), Binding::Fragment(fragment));
|
||||||
|
@ -342,17 +343,17 @@ impl<'a> TtIter<'a> {
|
||||||
token_trees: res.into_iter().cloned().collect(),
|
token_trees: res.into_iter().cloned().collect(),
|
||||||
})),
|
})),
|
||||||
};
|
};
|
||||||
ExpandResult(res, err)
|
ExpandResult { value: res, err }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn eat_vis(&mut self) -> Option<tt::TokenTree> {
|
pub(crate) fn eat_vis(&mut self) -> Option<tt::TokenTree> {
|
||||||
let mut fork = self.clone();
|
let mut fork = self.clone();
|
||||||
match fork.expect_fragment(Visibility) {
|
match fork.expect_fragment(Visibility) {
|
||||||
ExpandResult(tt, None) => {
|
ExpandResult { value: tt, err: None } => {
|
||||||
*self = fork;
|
*self = fork;
|
||||||
tt
|
tt
|
||||||
}
|
}
|
||||||
ExpandResult(_, Some(_)) => None,
|
ExpandResult { value: _, err: Some(_) } => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -93,17 +93,18 @@ fn expand_subtree(
|
||||||
match op {
|
match op {
|
||||||
Op::TokenTree(tt @ tt::TokenTree::Leaf(..)) => arena.push(tt.clone()),
|
Op::TokenTree(tt @ tt::TokenTree::Leaf(..)) => arena.push(tt.clone()),
|
||||||
Op::TokenTree(tt::TokenTree::Subtree(tt)) => {
|
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);
|
err = err.or(e);
|
||||||
arena.push(tt.into());
|
arena.push(tt.into());
|
||||||
}
|
}
|
||||||
Op::Var { name, kind: _ } => {
|
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);
|
err = err.or(e);
|
||||||
push_fragment(arena, fragment);
|
push_fragment(arena, fragment);
|
||||||
}
|
}
|
||||||
Op::Repeat { subtree, kind, separator } => {
|
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);
|
err = err.or(e);
|
||||||
push_fragment(arena, fragment)
|
push_fragment(arena, fragment)
|
||||||
}
|
}
|
||||||
|
@ -111,7 +112,7 @@ fn expand_subtree(
|
||||||
}
|
}
|
||||||
// drain the elements added in this instance of expand_subtree
|
// drain the elements added in this instance of expand_subtree
|
||||||
let tts = arena.drain(start_elements..arena.len()).collect();
|
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> {
|
fn expand_var(ctx: &mut ExpandCtx, v: &SmolStr) -> ExpandResult<Fragment> {
|
||||||
|
@ -152,7 +153,7 @@ fn expand_var(ctx: &mut ExpandCtx, v: &SmolStr) -> ExpandResult<Fragment> {
|
||||||
ExpandResult::ok(Fragment::Tokens(tt))
|
ExpandResult::ok(Fragment::Tokens(tt))
|
||||||
} else {
|
} else {
|
||||||
ctx.bindings.get(&v, &mut ctx.nesting).map_or_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()),
|
|b| ExpandResult::ok(b.clone()),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -174,7 +175,7 @@ fn expand_repeat(
|
||||||
let mut counter = 0;
|
let mut counter = 0;
|
||||||
|
|
||||||
loop {
|
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();
|
let nesting_state = ctx.nesting.last_mut().unwrap();
|
||||||
if nesting_state.at_end || !nesting_state.hit {
|
if nesting_state.at_end || !nesting_state.hit {
|
||||||
break;
|
break;
|
||||||
|
@ -234,7 +235,10 @@ fn expand_repeat(
|
||||||
let tt = tt::Subtree { delimiter: None, token_trees: buf }.into();
|
let tt = tt::Subtree { delimiter: None, token_trees: buf }.into();
|
||||||
|
|
||||||
if RepeatKind::OneOrMore == kind && counter == 0 {
|
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))
|
ExpandResult::ok(Fragment::Tokens(tt))
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue