aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/hir_expand/src/db.rs2
-rw-r--r--crates/mbe/src/lib.rs24
-rw-r--r--crates/mbe/src/mbe_expander.rs15
-rw-r--r--crates/mbe/src/mbe_expander/matcher.rs9
-rw-r--r--crates/mbe/src/mbe_expander/transcriber.rs18
5 files changed, 39 insertions, 29 deletions
diff --git a/crates/hir_expand/src/db.rs b/crates/hir_expand/src/db.rs
index a9099eb22..3deac1711 100644
--- a/crates/hir_expand/src/db.rs
+++ b/crates/hir_expand/src/db.rs
@@ -242,7 +242,7 @@ fn macro_expand_with_arg(
242 Some(it) => it, 242 Some(it) => it,
243 None => return MacroResult::error("Fail to find macro definition".into()), 243 None => return MacroResult::error("Fail to find macro definition".into()),
244 }; 244 };
245 let ExpandResult(tt, err) = macro_rules.0.expand(db, lazy_id, &macro_arg.0); 245 let ExpandResult { value: tt, err } = macro_rules.0.expand(db, lazy_id, &macro_arg.0);
246 // Set a hard limit for the expanded tt 246 // Set a hard limit for the expanded tt
247 let count = tt.count(); 247 let count = tt.count();
248 if count > 262144 { 248 if count > 262144 {
diff --git a/crates/mbe/src/lib.rs b/crates/mbe/src/lib.rs
index f854ca09a..183e3b988 100644
--- a/crates/mbe/src/lib.rs
+++ b/crates/mbe/src/lib.rs
@@ -246,33 +246,35 @@ fn validate(pattern: &tt::Subtree) -> Result<(), ParseError> {
246 Ok(()) 246 Ok(())
247} 247}
248 248
249#[derive(Debug)] 249#[derive(Debug, Clone, Eq, PartialEq)]
250pub struct ExpandResult<T>(pub T, pub Option<ExpandError>); 250pub struct ExpandResult<T> {
251 pub value: T,
252 pub err: Option<ExpandError>,
253}
251 254
252impl<T> ExpandResult<T> { 255impl<T> ExpandResult<T> {
253 pub fn ok(t: T) -> ExpandResult<T> { 256 pub fn ok(value: T) -> Self {
254 ExpandResult(t, None) 257 Self { value, err: None }
255 } 258 }
256 259
257 pub fn only_err(err: ExpandError) -> ExpandResult<T> 260 pub fn only_err(err: ExpandError) -> Self
258 where 261 where
259 T: Default, 262 T: Default,
260 { 263 {
261 ExpandResult(Default::default(), Some(err)) 264 Self { value: Default::default(), err: Some(err) }
262 } 265 }
263 266
264 pub fn map<U>(self, f: impl FnOnce(T) -> U) -> ExpandResult<U> { 267 pub fn map<U>(self, f: impl FnOnce(T) -> U) -> ExpandResult<U> {
265 ExpandResult(f(self.0), self.1) 268 ExpandResult { value: f(self.value), err: self.err }
266 } 269 }
267 270
268 pub fn result(self) -> Result<T, ExpandError> { 271 pub fn result(self) -> Result<T, ExpandError> {
269 self.1.map(Err).unwrap_or(Ok(self.0)) 272 self.err.map(Err).unwrap_or(Ok(self.value))
270 } 273 }
271} 274}
272 275
273impl<T: Default> From<Result<T, ExpandError>> for ExpandResult<T> { 276impl<T: Default> From<Result<T, ExpandError>> for ExpandResult<T> {
274 fn from(result: Result<T, ExpandError>) -> ExpandResult<T> { 277 fn from(result: Result<T, ExpandError>) -> Self {
275 result 278 result.map_or_else(|e| Self::only_err(e), |it| Self::ok(it))
276 .map_or_else(|e| ExpandResult(Default::default(), Some(e)), |it| ExpandResult(it, None))
277 } 279 }
278} 280}
diff --git a/crates/mbe/src/mbe_expander.rs b/crates/mbe/src/mbe_expander.rs
index 1ad8b9f8a..97bce0536 100644
--- a/crates/mbe/src/mbe_expander.rs
+++ b/crates/mbe/src/mbe_expander.rs
@@ -28,10 +28,10 @@ fn expand_rules(rules: &[crate::Rule], input: &tt::Subtree) -> ExpandResult<tt::
28 // If we find a rule that applies without errors, we're done. 28 // If we find a rule that applies without errors, we're done.
29 // Unconditionally returning the transcription here makes the 29 // Unconditionally returning the transcription here makes the
30 // `test_repeat_bad_var` test fail. 30 // `test_repeat_bad_var` test fail.
31 let ExpandResult(res, transcribe_err) = 31 let ExpandResult { value, err: transcribe_err } =
32 transcriber::transcribe(&rule.rhs, &new_match.bindings); 32 transcriber::transcribe(&rule.rhs, &new_match.bindings);
33 if transcribe_err.is_none() { 33 if transcribe_err.is_none() {
34 return ExpandResult::ok(res); 34 return ExpandResult::ok(value);
35 } 35 }
36 } 36 }
37 // Use the rule if we matched more tokens, or had fewer errors 37 // 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::
47 } 47 }
48 if let Some((match_, rule)) = match_ { 48 if let Some((match_, rule)) = match_ {
49 // if we got here, there was no match without errors 49 // if we got here, there was no match without errors
50 let ExpandResult(result, transcribe_err) = 50 let ExpandResult { value, err: transcribe_err } =
51 transcriber::transcribe(&rule.rhs, &match_.bindings); 51 transcriber::transcribe(&rule.rhs, &match_.bindings);
52 ExpandResult(result, match_.err.or(transcribe_err)) 52 ExpandResult { value, err: match_.err.or(transcribe_err) }
53 } else { 53 } else {
54 ExpandResult(tt::Subtree::default(), Some(ExpandError::NoMatchingRule)) 54 ExpandResult::only_err(ExpandError::NoMatchingRule)
55 } 55 }
56} 56}
57 57
@@ -143,7 +143,10 @@ mod tests {
143 } 143 }
144 144
145 fn assert_err(macro_body: &str, invocation: &str, err: ExpandError) { 145 fn assert_err(macro_body: &str, invocation: &str, err: ExpandError) {
146 assert_eq!(expand_first(&create_rules(&format_macro(macro_body)), invocation).1, Some(err)); 146 assert_eq!(
147 expand_first(&create_rules(&format_macro(macro_body)), invocation).err,
148 Some(err)
149 );
147 } 150 }
148 151
149 fn format_macro(macro_body: &str) -> String { 152 fn format_macro(macro_body: &str) -> String {
diff --git a/crates/mbe/src/mbe_expander/matcher.rs b/crates/mbe/src/mbe_expander/matcher.rs
index 39a8eefbd..3f8445897 100644
--- a/crates/mbe/src/mbe_expander/matcher.rs
+++ b/crates/mbe/src/mbe_expander/matcher.rs
@@ -158,7 +158,8 @@ fn match_subtree(
158 continue; 158 continue;
159 } 159 }
160 }; 160 };
161 let ExpandResult(matched, match_err) = match_meta_var(kind.as_str(), src); 161 let ExpandResult { value: matched, err: match_err } =
162 match_meta_var(kind.as_str(), src);
162 match matched { 163 match matched {
163 Some(fragment) => { 164 Some(fragment) => {
164 res.bindings.inner.insert(name.clone(), Binding::Fragment(fragment)); 165 res.bindings.inner.insert(name.clone(), Binding::Fragment(fragment));
@@ -342,17 +343,17 @@ impl<'a> TtIter<'a> {
342 token_trees: res.into_iter().cloned().collect(), 343 token_trees: res.into_iter().cloned().collect(),
343 })), 344 })),
344 }; 345 };
345 ExpandResult(res, err) 346 ExpandResult { value: res, err }
346 } 347 }
347 348
348 pub(crate) fn eat_vis(&mut self) -> Option<tt::TokenTree> { 349 pub(crate) fn eat_vis(&mut self) -> Option<tt::TokenTree> {
349 let mut fork = self.clone(); 350 let mut fork = self.clone();
350 match fork.expect_fragment(Visibility) { 351 match fork.expect_fragment(Visibility) {
351 ExpandResult(tt, None) => { 352 ExpandResult { value: tt, err: None } => {
352 *self = fork; 353 *self = fork;
353 tt 354 tt
354 } 355 }
355 ExpandResult(_, Some(_)) => None, 356 ExpandResult { value: _, err: Some(_) } => None,
356 } 357 }
357 } 358 }
358} 359}
diff --git a/crates/mbe/src/mbe_expander/transcriber.rs b/crates/mbe/src/mbe_expander/transcriber.rs
index c9525c5bf..616119ba9 100644
--- a/crates/mbe/src/mbe_expander/transcriber.rs
+++ b/crates/mbe/src/mbe_expander/transcriber.rs
@@ -93,17 +93,18 @@ fn expand_subtree(
93 match op { 93 match op {
94 Op::TokenTree(tt @ tt::TokenTree::Leaf(..)) => arena.push(tt.clone()), 94 Op::TokenTree(tt @ tt::TokenTree::Leaf(..)) => arena.push(tt.clone()),
95 Op::TokenTree(tt::TokenTree::Subtree(tt)) => { 95 Op::TokenTree(tt::TokenTree::Subtree(tt)) => {
96 let ExpandResult(tt, e) = expand_subtree(ctx, tt, arena); 96 let ExpandResult { value: tt, err: e } = expand_subtree(ctx, tt, arena);
97 err = err.or(e); 97 err = err.or(e);
98 arena.push(tt.into()); 98 arena.push(tt.into());
99 } 99 }
100 Op::Var { name, kind: _ } => { 100 Op::Var { name, kind: _ } => {
101 let ExpandResult(fragment, e) = expand_var(ctx, name); 101 let ExpandResult { value: fragment, err: e } = expand_var(ctx, name);
102 err = err.or(e); 102 err = err.or(e);
103 push_fragment(arena, fragment); 103 push_fragment(arena, fragment);
104 } 104 }
105 Op::Repeat { subtree, kind, separator } => { 105 Op::Repeat { subtree, kind, separator } => {
106 let ExpandResult(fragment, e) = expand_repeat(ctx, subtree, kind, separator, arena); 106 let ExpandResult { value: fragment, err: e } =
107 expand_repeat(ctx, subtree, kind, separator, arena);
107 err = err.or(e); 108 err = err.or(e);
108 push_fragment(arena, fragment) 109 push_fragment(arena, fragment)
109 } 110 }
@@ -111,7 +112,7 @@ fn expand_subtree(
111 } 112 }
112 // drain the elements added in this instance of expand_subtree 113 // drain the elements added in this instance of expand_subtree
113 let tts = arena.drain(start_elements..arena.len()).collect(); 114 let tts = arena.drain(start_elements..arena.len()).collect();
114 ExpandResult(tt::Subtree { delimiter: template.delimiter, token_trees: tts }, err) 115 ExpandResult { value: tt::Subtree { delimiter: template.delimiter, token_trees: tts }, err }
115} 116}
116 117
117fn expand_var(ctx: &mut ExpandCtx, v: &SmolStr) -> ExpandResult<Fragment> { 118fn expand_var(ctx: &mut ExpandCtx, v: &SmolStr) -> ExpandResult<Fragment> {
@@ -152,7 +153,7 @@ fn expand_var(ctx: &mut ExpandCtx, v: &SmolStr) -> ExpandResult<Fragment> {
152 ExpandResult::ok(Fragment::Tokens(tt)) 153 ExpandResult::ok(Fragment::Tokens(tt))
153 } else { 154 } else {
154 ctx.bindings.get(&v, &mut ctx.nesting).map_or_else( 155 ctx.bindings.get(&v, &mut ctx.nesting).map_or_else(
155 |e| ExpandResult(Fragment::Tokens(tt::TokenTree::empty()), Some(e)), 156 |e| ExpandResult { value: Fragment::Tokens(tt::TokenTree::empty()), err: Some(e) },
156 |b| ExpandResult::ok(b.clone()), 157 |b| ExpandResult::ok(b.clone()),
157 ) 158 )
158 } 159 }
@@ -174,7 +175,7 @@ fn expand_repeat(
174 let mut counter = 0; 175 let mut counter = 0;
175 176
176 loop { 177 loop {
177 let ExpandResult(mut t, e) = expand_subtree(ctx, template, arena); 178 let ExpandResult { value: mut t, err: e } = expand_subtree(ctx, template, arena);
178 let nesting_state = ctx.nesting.last_mut().unwrap(); 179 let nesting_state = ctx.nesting.last_mut().unwrap();
179 if nesting_state.at_end || !nesting_state.hit { 180 if nesting_state.at_end || !nesting_state.hit {
180 break; 181 break;
@@ -234,7 +235,10 @@ fn expand_repeat(
234 let tt = tt::Subtree { delimiter: None, token_trees: buf }.into(); 235 let tt = tt::Subtree { delimiter: None, token_trees: buf }.into();
235 236
236 if RepeatKind::OneOrMore == kind && counter == 0 { 237 if RepeatKind::OneOrMore == kind && counter == 0 {
237 return ExpandResult(Fragment::Tokens(tt), Some(ExpandError::UnexpectedToken)); 238 return ExpandResult {
239 value: Fragment::Tokens(tt),
240 err: Some(ExpandError::UnexpectedToken),
241 };
238 } 242 }
239 ExpandResult::ok(Fragment::Tokens(tt)) 243 ExpandResult::ok(Fragment::Tokens(tt))
240} 244}