Skip to content

Commit 726dc18

Browse files
Use syn::Error compile error instead of unreachable! for span_pos failure
1 parent a8d9fc6 commit 726dc18

1 file changed

Lines changed: 39 additions & 26 deletions

File tree

mlua_derive/src/chunk/token.rs

Lines changed: 39 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
use std::cmp::{Eq, PartialEq};
2+
use std::convert::TryFrom;
23
use std::fmt::{self, Display, Formatter};
34
use std::vec::IntoIter;
45

56
use proc_macro::{Delimiter, Span, TokenStream, TokenTree};
6-
use proc_macro2::Span as Span2;
7-
use proc_macro2::TokenStream as TokenStream2;
7+
use proc_macro2::{Span as Span2, TokenStream as TokenStream2};
88
use syn;
99

1010
#[derive(Clone, Copy, Debug)]
@@ -33,17 +33,21 @@ impl Pos {
3333
}
3434
}
3535

36-
fn span_pos(span: &Span) -> (Pos, Pos) {
36+
fn span_pos(span: &Span) -> Result<(Pos, Pos), TokenStream2> {
3737
let span2: Span2 = (*span).into();
3838
let start = span2.start();
3939
let end = span2.end();
4040

4141
// Rust 1.88 stabilized Span APIs, so this branch must be unreachable
4242
if start.line == 0 || end.line == 0 {
43-
unreachable!("cannot retrieve span location information; mlua requires nightly Rust or stable >= 1.88");
43+
return Err(syn::Error::new(
44+
Span2::call_site(),
45+
"cannot retrieve span location information; mlua requires nightly Rust or stable >= 1.88",
46+
)
47+
.to_compile_error());
4448
}
4549

46-
(Pos::new(start.line, start.column), Pos::new(end.line, end.column))
50+
Ok((Pos::new(start.line, start.column), Pos::new(end.line, end.column)))
4751
}
4852

4953
/// Attribute of token.
@@ -73,33 +77,32 @@ impl PartialEq for Token {
7377
impl Eq for Token {}
7478

7579
impl Token {
76-
fn new(tree: TokenTree) -> Self {
77-
let (start, end) = span_pos(&tree.span());
80+
fn new(tree: TokenTree) -> Result<Self, TokenStream2> {
81+
let (start, end) = span_pos(&tree.span())?;
7882
let source = tree.span().source_text().unwrap_or_else(|| tree.to_string());
79-
Self {
83+
Ok(Self {
8084
source,
8185
start,
8286
end,
8387
tree,
8488
attr: TokenAttr::None,
85-
}
89+
})
8690
}
8791

88-
fn new_delim(source: String, tree: TokenTree, open: bool) -> Self {
89-
let (start, end) = span_pos(&tree.span());
92+
fn new_delim(source: String, tree: TokenTree, open: bool) -> Result<Self, TokenStream2> {
93+
let (start, end) = span_pos(&tree.span())?;
9094
let (start, end) = if open {
9195
(start, start.right())
9296
} else {
9397
(end.left(), end)
9498
};
95-
96-
Self {
99+
Ok(Self {
97100
source,
98101
tree,
99102
start,
100103
end,
101104
attr: TokenAttr::None,
102-
}
105+
})
103106
}
104107

105108
pub(crate) fn tree(&self) -> &TokenTree {
@@ -133,7 +136,11 @@ pub(crate) struct Tokens(pub(crate) Vec<Token>);
133136

134137
impl Tokens {
135138
pub(crate) fn retokenize(tt: TokenStream) -> Result<Tokens, TokenStream2> {
136-
let flat: Vec<Token> = tt.into_iter().flat_map(Tokens::from).collect();
139+
let mut flat = Vec::new();
140+
for tree in tt.into_iter() {
141+
flat.extend(Tokens::try_from(tree)?.0);
142+
}
143+
137144
let mut tokens = Vec::new();
138145
let mut iter = flat.into_iter();
139146
while let Some(t) = iter.next() {
@@ -144,8 +151,11 @@ impl Tokens {
144151
{
145152
tokens.push(next.attr(TokenAttr::Cap));
146153
} else {
147-
return Err(syn::Error::new(t.tree.span().into(), "`$` must be followed by an identifier")
148-
.to_compile_error());
154+
return Err(syn::Error::new(
155+
t.tree.span().into(),
156+
"`$` must be followed by an identifier",
157+
)
158+
.to_compile_error());
149159
}
150160
} else {
151161
tokens.push(t);
@@ -164,8 +174,10 @@ impl IntoIterator for Tokens {
164174
}
165175
}
166176

167-
impl From<TokenTree> for Tokens {
168-
fn from(tt: TokenTree) -> Self {
177+
impl TryFrom<TokenTree> for Tokens {
178+
type Error = TokenStream2;
179+
180+
fn try_from(tt: TokenTree) -> Result<Self, TokenStream2> {
169181
let tts = match tt.clone() {
170182
TokenTree::Group(g) => {
171183
let (b, e) = match g.delimiter() {
@@ -176,15 +188,16 @@ impl From<TokenTree> for Tokens {
176188
};
177189
let (b, e) = (b.into(), e.into());
178190

179-
vec![Token::new_delim(b, tt.clone(), true)]
180-
.into_iter()
181-
.chain(g.stream().into_iter().flat_map(Tokens::from))
182-
.chain(vec![Token::new_delim(e, tt, false)])
183-
.collect()
191+
let mut result = vec![Token::new_delim(b, tt.clone(), true)?];
192+
for inner in g.stream().into_iter() {
193+
result.extend(Tokens::try_from(inner)?.0);
194+
}
195+
result.push(Token::new_delim(e, tt, false)?);
196+
result
184197
}
185-
_ => vec![Token::new(tt)],
198+
_ => vec![Token::new(tt)?],
186199
};
187-
Tokens(tts)
200+
Ok(Tokens(tts))
188201
}
189202
}
190203

0 commit comments

Comments
 (0)