Skip to content

Commit 2e7170e

Browse files
bors[bot]Veykril
andauthored
Merge #11166
11166: minor: Simplify r=Veykril a=Veykril bors r+ Co-authored-by: Lukas Wirth <[email protected]>
2 parents 367cd5c + f31863b commit 2e7170e

File tree

4 files changed

+65
-83
lines changed

4 files changed

+65
-83
lines changed

crates/hir_def/src/macro_expansion_tests/mbe/meta_syntax.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,11 +69,11 @@ macro_rules! e3 { ($(i:ident)_) => () }
6969
/* error: invalid macro definition: invalid repeat */
7070
7171
macro_rules! f1 { ($i) => ($i) }
72-
/* error: invalid macro definition: bad fragment specifier 1 */
72+
/* error: invalid macro definition: missing fragment specifier */
7373
macro_rules! f2 { ($i:) => ($i) }
74-
/* error: invalid macro definition: bad fragment specifier 1 */
74+
/* error: invalid macro definition: missing fragment specifier */
7575
macro_rules! f3 { ($i:_) => () }
76-
/* error: invalid macro definition: bad fragment specifier 1 */
76+
/* error: invalid macro definition: missing fragment specifier */
7777
"#]],
7878
)
7979
}

crates/mbe/src/expander/matcher.rs

Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -571,18 +571,18 @@ fn match_loop(pattern: &MetaTemplate, src: &tt::Subtree) -> Match {
571571

572572
if !error_items.is_empty() {
573573
error_recover_item = error_items.pop().map(|it| it.bindings);
574-
} else if !eof_items.is_empty() {
575-
error_recover_item = Some(eof_items[0].bindings.clone());
574+
} else if let [state, ..] = &*eof_items {
575+
error_recover_item = Some(state.bindings.clone());
576576
}
577577

578578
// We need to do some post processing after the `match_loop_inner`.
579579
// If we reached the EOF, check that there is EXACTLY ONE possible matcher. Otherwise,
580580
// either the parse is ambiguous (which should never happen) or there is a syntax error.
581581
if src.peek_n(0).is_none() && stack.is_empty() {
582-
if eof_items.len() == 1 {
582+
if let [state] = &*eof_items {
583583
// remove all errors, because it is the correct answer !
584584
res = Match::default();
585-
res.bindings = bindings_builder.build(&eof_items[0].bindings);
585+
res.bindings = bindings_builder.build(&state.bindings);
586586
} else {
587587
// Error recovery
588588
if let Some(item) = error_recover_item {
@@ -598,10 +598,10 @@ fn match_loop(pattern: &MetaTemplate, src: &tt::Subtree) -> Match {
598598
//
599599
// Another possibility is that we need to call out to parse some rust nonterminal
600600
// (black-box) parser. However, if there is not EXACTLY ONE of these, something is wrong.
601-
if (bb_items.is_empty() && next_items.is_empty())
602-
|| (!bb_items.is_empty() && !next_items.is_empty())
603-
|| bb_items.len() > 1
604-
{
601+
let has_leftover_tokens = (bb_items.is_empty() && next_items.is_empty())
602+
|| !(bb_items.is_empty() || next_items.is_empty())
603+
|| bb_items.len() > 1;
604+
if has_leftover_tokens {
605605
res.unmatched_tts += src.len();
606606
while let Some(it) = stack.pop() {
607607
src = it;
@@ -624,7 +624,11 @@ fn match_loop(pattern: &MetaTemplate, src: &tt::Subtree) -> Match {
624624
stack.push(src.clone());
625625
src = TtIter::new(subtree);
626626
}
627-
None if !stack.is_empty() => src = stack.pop().unwrap(),
627+
None => {
628+
if let Some(iter) = stack.pop() {
629+
src = iter;
630+
}
631+
}
628632
_ => (),
629633
}
630634
}
@@ -662,29 +666,23 @@ fn match_loop(pattern: &MetaTemplate, src: &tt::Subtree) -> Match {
662666
fn match_leaf(lhs: &tt::Leaf, src: &mut TtIter) -> Result<(), ExpandError> {
663667
let rhs = match src.expect_leaf() {
664668
Ok(l) => l,
665-
Err(()) => {
666-
return Err(err!("expected leaf: `{}`", lhs));
667-
}
669+
Err(()) => return Err(err!("expected leaf: `{}`", lhs)),
668670
};
669671
match (lhs, rhs) {
670672
(
671673
tt::Leaf::Punct(tt::Punct { char: lhs, .. }),
672674
tt::Leaf::Punct(tt::Punct { char: rhs, .. }),
673-
) if lhs == rhs => (),
675+
) if lhs == rhs => Ok(()),
674676
(
675677
tt::Leaf::Ident(tt::Ident { text: lhs, .. }),
676678
tt::Leaf::Ident(tt::Ident { text: rhs, .. }),
677-
) if lhs == rhs => (),
679+
) if lhs == rhs => Ok(()),
678680
(
679681
tt::Leaf::Literal(tt::Literal { text: lhs, .. }),
680682
tt::Leaf::Literal(tt::Literal { text: rhs, .. }),
681-
) if lhs == rhs => (),
682-
_ => {
683-
return Err(ExpandError::UnexpectedToken);
684-
}
683+
) if lhs == rhs => Ok(()),
684+
_ => Err(ExpandError::UnexpectedToken),
685685
}
686-
687-
Ok(())
688686
}
689687

690688
fn match_meta_var(kind: &str, input: &mut TtIter) -> ExpandResult<Option<Fragment>> {

crates/mbe/src/expander/transcriber.rs

Lines changed: 25 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,10 @@
44
use syntax::SmolStr;
55
use tt::{Delimiter, Subtree};
66

7-
use super::ExpandResult;
87
use crate::{
98
expander::{Binding, Bindings, Fragment},
109
parser::{Op, RepeatKind, Separator},
11-
ExpandError, MetaTemplate,
10+
ExpandError, ExpandResult, MetaTemplate,
1211
};
1312

1413
impl Bindings {
@@ -17,36 +16,36 @@ impl Bindings {
1716
}
1817

1918
fn get(&self, name: &str, nesting: &mut [NestingState]) -> Result<&Fragment, ExpandError> {
20-
let mut b: &Binding = self.inner.get(name).ok_or_else(|| {
21-
ExpandError::BindingError(format!("could not find binding `{}`", name))
22-
})?;
19+
macro_rules! binding_err {
20+
($($arg:tt)*) => { ExpandError::BindingError(format!($($arg)*)) };
21+
}
22+
23+
let mut b: &Binding = self
24+
.inner
25+
.get(name)
26+
.ok_or_else(|| binding_err!("could not find binding `{}`", name))?;
2327
for nesting_state in nesting.iter_mut() {
2428
nesting_state.hit = true;
2529
b = match b {
2630
Binding::Fragment(_) => break,
2731
Binding::Nested(bs) => bs.get(nesting_state.idx).ok_or_else(|| {
2832
nesting_state.at_end = true;
29-
ExpandError::BindingError(format!("could not find nested binding `{}`", name))
33+
binding_err!("could not find nested binding `{}`", name)
3034
})?,
3135
Binding::Empty => {
3236
nesting_state.at_end = true;
33-
return Err(ExpandError::BindingError(format!(
34-
"could not find empty binding `{}`",
35-
name
36-
)));
37+
return Err(binding_err!("could not find empty binding `{}`", name));
3738
}
3839
};
3940
}
4041
match b {
4142
Binding::Fragment(it) => Ok(it),
42-
Binding::Nested(_) => Err(ExpandError::BindingError(format!(
43-
"expected simple binding, found nested binding `{}`",
44-
name
45-
))),
46-
Binding::Empty => Err(ExpandError::BindingError(format!(
47-
"expected simple binding, found empty binding `{}`",
48-
name
49-
))),
43+
Binding::Nested(_) => {
44+
Err(binding_err!("expected simple binding, found nested binding `{}`", name))
45+
}
46+
Binding::Empty => {
47+
Err(binding_err!("expected simple binding, found empty binding `{}`", name))
48+
}
5049
}
5150
}
5251
}
@@ -109,7 +108,7 @@ fn expand_subtree(
109108
}
110109
}
111110
// drain the elements added in this instance of expand_subtree
112-
let tts = arena.drain(start_elements..arena.len()).collect();
111+
let tts = arena.drain(start_elements..).collect();
113112
ExpandResult { value: tt::Subtree { delimiter, token_trees: tts }, err }
114113
}
115114

@@ -193,23 +192,22 @@ fn expand_repeat(
193192
push_subtree(&mut buf, t);
194193

195194
if let Some(sep) = separator {
196-
match sep {
195+
has_seps = match sep {
197196
Separator::Ident(ident) => {
198-
has_seps = 1;
199197
buf.push(tt::Leaf::from(ident.clone()).into());
198+
1
200199
}
201200
Separator::Literal(lit) => {
202-
has_seps = 1;
203201
buf.push(tt::Leaf::from(lit.clone()).into());
202+
1
204203
}
205-
206204
Separator::Puncts(puncts) => {
207-
has_seps = puncts.len();
208-
for punct in puncts {
209-
buf.push(tt::Leaf::from(*punct).into());
205+
for &punct in puncts {
206+
buf.push(tt::Leaf::from(punct).into());
210207
}
208+
puncts.len()
211209
}
212-
}
210+
};
213211
}
214212

215213
if RepeatKind::ZeroOrOne == kind {

crates/mbe/src/parser.rs

Lines changed: 19 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ impl MetaTemplate {
4141
let mut res = Vec::new();
4242
while let Some(first) = src.next() {
4343
let op = next_op(first, &mut src, mode)?;
44-
res.push(op)
44+
res.push(op);
4545
}
4646

4747
Ok(MetaTemplate(res))
@@ -110,12 +110,6 @@ macro_rules! err {
110110
};
111111
}
112112

113-
macro_rules! bail {
114-
($($tt:tt)*) => {
115-
return Err(err!($($tt)*))
116-
};
117-
}
118-
119113
fn next_op<'a>(first: &tt::TokenTree, src: &mut TtIter<'a>, mode: Mode) -> Result<Op, ParseError> {
120114
let res = match first {
121115
tt::TokenTree::Leaf(leaf @ tt::Leaf::Punct(tt::Punct { char: '$', .. })) => {
@@ -131,26 +125,24 @@ fn next_op<'a>(first: &tt::TokenTree, src: &mut TtIter<'a>, mode: Mode) -> Resul
131125
Op::Repeat { tokens, separator, kind }
132126
}
133127
tt::TokenTree::Leaf(leaf) => match leaf {
134-
tt::Leaf::Punct(_) => return Err(ParseError::Expected("ident".to_string())),
135128
tt::Leaf::Ident(ident) if ident.text == "crate" => {
136129
// We simply produce identifier `$crate` here. And it will be resolved when lowering ast to Path.
137130
Op::Leaf(tt::Leaf::from(tt::Ident { text: "$crate".into(), id: ident.id }))
138131
}
139132
tt::Leaf::Ident(ident) => {
140-
let name = ident.text.clone();
141133
let kind = eat_fragment_kind(src, mode)?;
134+
let name = ident.text.clone();
142135
let id = ident.id;
143136
Op::Var { name, kind, id }
144137
}
145-
tt::Leaf::Literal(lit) => {
146-
if is_boolean_literal(lit) {
147-
let name = lit.text.clone();
148-
let kind = eat_fragment_kind(src, mode)?;
149-
let id = lit.id;
150-
Op::Var { name, kind, id }
151-
} else {
152-
bail!("bad var 2");
153-
}
138+
tt::Leaf::Literal(lit) if is_boolean_literal(lit) => {
139+
let kind = eat_fragment_kind(src, mode)?;
140+
let name = lit.text.clone();
141+
let id = lit.id;
142+
Op::Var { name, kind, id }
143+
}
144+
tt::Leaf::Punct(_) | tt::Leaf::Literal(_) => {
145+
return Err(ParseError::Expected("ident".to_string()))
154146
}
155147
},
156148
}
@@ -166,8 +158,8 @@ fn next_op<'a>(first: &tt::TokenTree, src: &mut TtIter<'a>, mode: Mode) -> Resul
166158

167159
fn eat_fragment_kind(src: &mut TtIter<'_>, mode: Mode) -> Result<Option<SmolStr>, ParseError> {
168160
if let Mode::Pattern = mode {
169-
src.expect_char(':').map_err(|()| err!("bad fragment specifier 1"))?;
170-
let ident = src.expect_ident().map_err(|()| err!("bad fragment specifier 1"))?;
161+
src.expect_char(':').map_err(|()| err!("missing fragment specifier"))?;
162+
let ident = src.expect_ident().map_err(|()| err!("missing fragment specifier"))?;
171163
return Ok(Some(ident.text.clone()));
172164
};
173165
Ok(None)
@@ -199,21 +191,15 @@ fn parse_repeat(src: &mut TtIter) -> Result<(Option<Separator>, RepeatKind), Par
199191
'*' => RepeatKind::ZeroOrMore,
200192
'+' => RepeatKind::OneOrMore,
201193
'?' => RepeatKind::ZeroOrOne,
202-
_ => {
203-
match &mut separator {
204-
Separator::Puncts(puncts) => {
205-
if puncts.len() == 3 {
206-
return Err(ParseError::InvalidRepeat);
207-
}
208-
puncts.push(*punct)
209-
}
210-
_ => return Err(ParseError::InvalidRepeat),
194+
_ => match &mut separator {
195+
Separator::Puncts(puncts) if puncts.len() != 3 => {
196+
puncts.push(*punct);
197+
continue;
211198
}
212-
continue;
213-
}
199+
_ => return Err(ParseError::InvalidRepeat),
200+
},
214201
};
215-
let separator = if has_sep { Some(separator) } else { None };
216-
return Ok((separator, repeat_kind));
202+
return Ok((has_sep.then(|| separator), repeat_kind));
217203
}
218204
}
219205
}

0 commit comments

Comments
 (0)