diff options
-rw-r--r-- | crates/hir_expand/src/db.rs | 2 | ||||
-rw-r--r-- | crates/mbe/src/lib.rs | 24 | ||||
-rw-r--r-- | crates/mbe/src/mbe_expander.rs | 15 | ||||
-rw-r--r-- | crates/mbe/src/mbe_expander/matcher.rs | 9 | ||||
-rw-r--r-- | crates/mbe/src/mbe_expander/transcriber.rs | 18 |
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, ¯o_arg.0); | 245 | let ExpandResult { value: tt, err } = macro_rules.0.expand(db, lazy_id, ¯o_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)] |
250 | pub struct ExpandResult<T>(pub T, pub Option<ExpandError>); | 250 | pub struct ExpandResult<T> { |
251 | pub value: T, | ||
252 | pub err: Option<ExpandError>, | ||
253 | } | ||
251 | 254 | ||
252 | impl<T> ExpandResult<T> { | 255 | impl<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 | ||
273 | impl<T: Default> From<Result<T, ExpandError>> for ExpandResult<T> { | 276 | impl<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 | ||
117 | fn expand_var(ctx: &mut ExpandCtx, v: &SmolStr) -> ExpandResult<Fragment> { | 118 | fn 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 | } |