Skip to content

Commit 455a0cf

Browse files
Merge #6681
6681: builtin_macro: move to `mbe::ExpandResult` r=jonas-schievink a=jonas-schievink bors r+ Co-authored-by: Jonas Schievink <[email protected]>
2 parents 70eb170 + 92f52c5 commit 455a0cf

File tree

3 files changed

+81
-52
lines changed

3 files changed

+81
-52
lines changed

crates/hir_expand/src/builtin_macro.rs

Lines changed: 79 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use crate::{
66

77
use base_db::FileId;
88
use either::Either;
9-
use mbe::parse_to_token_tree;
9+
use mbe::{parse_to_token_tree, ExpandResult};
1010
use parser::FragmentKind;
1111
use syntax::ast::{self, AstToken};
1212

@@ -28,7 +28,7 @@ macro_rules! register_builtin {
2828
db: &dyn AstDatabase,
2929
id: LazyMacroId,
3030
tt: &tt::Subtree,
31-
) -> Result<tt::Subtree, mbe::ExpandError> {
31+
) -> ExpandResult<tt::Subtree> {
3232
let expander = match *self {
3333
$( BuiltinFnLikeExpander::$kind => $expand, )*
3434
};
@@ -42,7 +42,7 @@ macro_rules! register_builtin {
4242
db: &dyn AstDatabase,
4343
arg_id: EagerMacroId,
4444
tt: &tt::Subtree,
45-
) -> Result<(tt::Subtree, FragmentKind), mbe::ExpandError> {
45+
) -> ExpandResult<Option<(tt::Subtree, FragmentKind)>> {
4646
let expander = match *self {
4747
$( EagerExpander::$e_kind => $e_expand, )*
4848
};
@@ -109,25 +109,28 @@ fn line_expand(
109109
_db: &dyn AstDatabase,
110110
_id: LazyMacroId,
111111
_tt: &tt::Subtree,
112-
) -> Result<tt::Subtree, mbe::ExpandError> {
112+
) -> ExpandResult<tt::Subtree> {
113113
// dummy implementation for type-checking purposes
114114
let line_num = 0;
115115
let expanded = quote! {
116116
#line_num
117117
};
118118

119-
Ok(expanded)
119+
ExpandResult::ok(expanded)
120120
}
121121

122122
fn stringify_expand(
123123
db: &dyn AstDatabase,
124124
id: LazyMacroId,
125125
_tt: &tt::Subtree,
126-
) -> Result<tt::Subtree, mbe::ExpandError> {
126+
) -> ExpandResult<tt::Subtree> {
127127
let loc = db.lookup_intern_macro(id);
128128

129129
let macro_content = {
130-
let arg = loc.kind.arg(db).ok_or_else(|| mbe::ExpandError::UnexpectedToken)?;
130+
let arg = match loc.kind.arg(db) {
131+
Some(arg) => arg,
132+
None => return ExpandResult::only_err(mbe::ExpandError::UnexpectedToken),
133+
};
131134
let macro_args = arg;
132135
let text = macro_args.text();
133136
let without_parens = TextSize::of('(')..text.len() - TextSize::of(')');
@@ -138,28 +141,28 @@ fn stringify_expand(
138141
#macro_content
139142
};
140143

141-
Ok(expanded)
144+
ExpandResult::ok(expanded)
142145
}
143146

144147
fn column_expand(
145148
_db: &dyn AstDatabase,
146149
_id: LazyMacroId,
147150
_tt: &tt::Subtree,
148-
) -> Result<tt::Subtree, mbe::ExpandError> {
151+
) -> ExpandResult<tt::Subtree> {
149152
// dummy implementation for type-checking purposes
150153
let col_num = 0;
151154
let expanded = quote! {
152155
#col_num
153156
};
154157

155-
Ok(expanded)
158+
ExpandResult::ok(expanded)
156159
}
157160

158161
fn assert_expand(
159162
_db: &dyn AstDatabase,
160163
_id: LazyMacroId,
161164
tt: &tt::Subtree,
162-
) -> Result<tt::Subtree, mbe::ExpandError> {
165+
) -> ExpandResult<tt::Subtree> {
163166
// A hacky implementation for goto def and hover
164167
// We expand `assert!(cond, arg1, arg2)` to
165168
// ```
@@ -191,14 +194,14 @@ fn assert_expand(
191194
let expanded = quote! {
192195
{ { (##arg_tts); } }
193196
};
194-
Ok(expanded)
197+
ExpandResult::ok(expanded)
195198
}
196199

197200
fn file_expand(
198201
_db: &dyn AstDatabase,
199202
_id: LazyMacroId,
200203
_tt: &tt::Subtree,
201-
) -> Result<tt::Subtree, mbe::ExpandError> {
204+
) -> ExpandResult<tt::Subtree> {
202205
// FIXME: RA purposefully lacks knowledge of absolute file names
203206
// so just return "".
204207
let file_name = "";
@@ -207,31 +210,33 @@ fn file_expand(
207210
#file_name
208211
};
209212

210-
Ok(expanded)
213+
ExpandResult::ok(expanded)
211214
}
212215

213216
fn compile_error_expand(
214217
_db: &dyn AstDatabase,
215218
_id: LazyMacroId,
216219
tt: &tt::Subtree,
217-
) -> Result<tt::Subtree, mbe::ExpandError> {
220+
) -> ExpandResult<tt::Subtree> {
218221
if tt.count() == 1 {
219222
if let tt::TokenTree::Leaf(tt::Leaf::Literal(it)) = &tt.token_trees[0] {
220223
let s = it.text.as_str();
221224
if s.contains('"') {
222-
return Ok(quote! { loop { #it }});
225+
return ExpandResult::ok(quote! { loop { #it }});
223226
}
224227
};
225228
}
226229

227-
Err(mbe::ExpandError::BindingError("Must be a string".into()))
230+
ExpandResult::only_err(mbe::ExpandError::BindingError(
231+
"`compile_error!` argument be a string".into(),
232+
))
228233
}
229234

230235
fn format_args_expand(
231236
_db: &dyn AstDatabase,
232237
_id: LazyMacroId,
233238
tt: &tt::Subtree,
234-
) -> Result<tt::Subtree, mbe::ExpandError> {
239+
) -> ExpandResult<tt::Subtree> {
235240
// We expand `format_args!("", a1, a2)` to
236241
// ```
237242
// std::fmt::Arguments::new_v1(&[], &[
@@ -257,7 +262,7 @@ fn format_args_expand(
257262
args.push(current);
258263
}
259264
if args.is_empty() {
260-
return Err(mbe::ExpandError::NoMatchingRule);
265+
return ExpandResult::only_err(mbe::ExpandError::NoMatchingRule);
261266
}
262267
let _format_string = args.remove(0);
263268
let arg_tts = args.into_iter().flat_map(|arg| {
@@ -266,7 +271,7 @@ fn format_args_expand(
266271
let expanded = quote! {
267272
std::fmt::Arguments::new_v1(&[], &[##arg_tts])
268273
};
269-
Ok(expanded)
274+
ExpandResult::ok(expanded)
270275
}
271276

272277
fn unquote_str(lit: &tt::Literal) -> Option<String> {
@@ -279,19 +284,24 @@ fn concat_expand(
279284
_db: &dyn AstDatabase,
280285
_arg_id: EagerMacroId,
281286
tt: &tt::Subtree,
282-
) -> Result<(tt::Subtree, FragmentKind), mbe::ExpandError> {
287+
) -> ExpandResult<Option<(tt::Subtree, FragmentKind)>> {
283288
let mut text = String::new();
284289
for (i, t) in tt.token_trees.iter().enumerate() {
285290
match t {
286291
tt::TokenTree::Leaf(tt::Leaf::Literal(it)) if i % 2 == 0 => {
287-
text += &unquote_str(&it).ok_or_else(|| mbe::ExpandError::ConversionError)?;
292+
text += &match unquote_str(&it) {
293+
Some(s) => s,
294+
None => {
295+
return ExpandResult::only_err(mbe::ExpandError::ConversionError);
296+
}
297+
};
288298
}
289299
tt::TokenTree::Leaf(tt::Leaf::Punct(punct)) if i % 2 == 1 && punct.char == ',' => (),
290-
_ => return Err(mbe::ExpandError::UnexpectedToken),
300+
_ => return ExpandResult::only_err(mbe::ExpandError::UnexpectedToken),
291301
}
292302
}
293303

294-
Ok((quote!(#text), FragmentKind::Expr))
304+
ExpandResult::ok(Some((quote!(#text), FragmentKind::Expr)))
295305
}
296306

297307
fn relative_file(
@@ -324,26 +334,35 @@ fn include_expand(
324334
db: &dyn AstDatabase,
325335
arg_id: EagerMacroId,
326336
tt: &tt::Subtree,
327-
) -> Result<(tt::Subtree, FragmentKind), mbe::ExpandError> {
328-
let path = parse_string(tt)?;
329-
let file_id = relative_file(db, arg_id.into(), &path, false)
330-
.ok_or_else(|| mbe::ExpandError::ConversionError)?;
331-
332-
// FIXME:
333-
// Handle include as expression
334-
let res = parse_to_token_tree(&db.file_text(file_id))
335-
.ok_or_else(|| mbe::ExpandError::ConversionError)?
336-
.0;
337-
338-
Ok((res, FragmentKind::Items))
337+
) -> ExpandResult<Option<(tt::Subtree, FragmentKind)>> {
338+
let res = (|| {
339+
let path = parse_string(tt)?;
340+
let file_id = relative_file(db, arg_id.into(), &path, false)
341+
.ok_or_else(|| mbe::ExpandError::ConversionError)?;
342+
343+
Ok(parse_to_token_tree(&db.file_text(file_id))
344+
.ok_or_else(|| mbe::ExpandError::ConversionError)?
345+
.0)
346+
})();
347+
348+
match res {
349+
Ok(res) => {
350+
// FIXME:
351+
// Handle include as expression
352+
ExpandResult::ok(Some((res, FragmentKind::Items)))
353+
}
354+
Err(e) => ExpandResult::only_err(e),
355+
}
339356
}
340357

341358
fn include_bytes_expand(
342359
_db: &dyn AstDatabase,
343360
_arg_id: EagerMacroId,
344361
tt: &tt::Subtree,
345-
) -> Result<(tt::Subtree, FragmentKind), mbe::ExpandError> {
346-
let _path = parse_string(tt)?;
362+
) -> ExpandResult<Option<(tt::Subtree, FragmentKind)>> {
363+
if let Err(e) = parse_string(tt) {
364+
return ExpandResult::only_err(e);
365+
}
347366

348367
// FIXME: actually read the file here if the user asked for macro expansion
349368
let res = tt::Subtree {
@@ -353,15 +372,18 @@ fn include_bytes_expand(
353372
id: tt::TokenId::unspecified(),
354373
}))],
355374
};
356-
Ok((res, FragmentKind::Expr))
375+
ExpandResult::ok(Some((res, FragmentKind::Expr)))
357376
}
358377

359378
fn include_str_expand(
360379
db: &dyn AstDatabase,
361380
arg_id: EagerMacroId,
362381
tt: &tt::Subtree,
363-
) -> Result<(tt::Subtree, FragmentKind), mbe::ExpandError> {
364-
let path = parse_string(tt)?;
382+
) -> ExpandResult<Option<(tt::Subtree, FragmentKind)>> {
383+
let path = match parse_string(tt) {
384+
Ok(it) => it,
385+
Err(e) => return ExpandResult::only_err(e),
386+
};
365387

366388
// FIXME: we're not able to read excluded files (which is most of them because
367389
// it's unusual to `include_str!` a Rust file), but we can return an empty string.
@@ -370,14 +392,14 @@ fn include_str_expand(
370392
let file_id = match relative_file(db, arg_id.into(), &path, true) {
371393
Some(file_id) => file_id,
372394
None => {
373-
return Ok((quote!(""), FragmentKind::Expr));
395+
return ExpandResult::ok(Some((quote!(""), FragmentKind::Expr)));
374396
}
375397
};
376398

377399
let text = db.file_text(file_id);
378400
let text = &*text;
379401

380-
Ok((quote!(#text), FragmentKind::Expr))
402+
ExpandResult::ok(Some((quote!(#text), FragmentKind::Expr)))
381403
}
382404

383405
fn get_env_inner(db: &dyn AstDatabase, arg_id: EagerMacroId, key: &str) -> Option<String> {
@@ -389,8 +411,11 @@ fn env_expand(
389411
db: &dyn AstDatabase,
390412
arg_id: EagerMacroId,
391413
tt: &tt::Subtree,
392-
) -> Result<(tt::Subtree, FragmentKind), mbe::ExpandError> {
393-
let key = parse_string(tt)?;
414+
) -> ExpandResult<Option<(tt::Subtree, FragmentKind)>> {
415+
let key = match parse_string(tt) {
416+
Ok(it) => it,
417+
Err(e) => return ExpandResult::only_err(e),
418+
};
394419

395420
// FIXME:
396421
// If the environment variable is not defined int rustc, then a compilation error will be emitted.
@@ -402,21 +427,25 @@ fn env_expand(
402427
let s = get_env_inner(db, arg_id, &key).unwrap_or_else(|| "__RA_UNIMPLEMENTED__".to_string());
403428
let expanded = quote! { #s };
404429

405-
Ok((expanded, FragmentKind::Expr))
430+
ExpandResult::ok(Some((expanded, FragmentKind::Expr)))
406431
}
407432

408433
fn option_env_expand(
409434
db: &dyn AstDatabase,
410435
arg_id: EagerMacroId,
411436
tt: &tt::Subtree,
412-
) -> Result<(tt::Subtree, FragmentKind), mbe::ExpandError> {
413-
let key = parse_string(tt)?;
437+
) -> ExpandResult<Option<(tt::Subtree, FragmentKind)>> {
438+
let key = match parse_string(tt) {
439+
Ok(it) => it,
440+
Err(e) => return ExpandResult::only_err(e),
441+
};
442+
414443
let expanded = match get_env_inner(db, arg_id, &key) {
415444
None => quote! { std::option::Option::None::<&str> },
416445
Some(s) => quote! { std::option::Some(#s) },
417446
};
418447

419-
Ok((expanded, FragmentKind::Expr))
448+
ExpandResult::ok(Some((expanded, FragmentKind::Expr)))
420449
}
421450

422451
#[cfg(test)]
@@ -485,7 +514,7 @@ mod tests {
485514
}
486515
});
487516

488-
let (subtree, fragment) = expander.expand(&db, arg_id, &parsed_args).unwrap();
517+
let (subtree, fragment) = expander.expand(&db, arg_id, &parsed_args).value.unwrap();
489518
let eager = EagerCallLoc {
490519
def,
491520
fragment,

crates/hir_expand/src/db.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@ impl TokenExpander {
3030
) -> mbe::ExpandResult<tt::Subtree> {
3131
match self {
3232
TokenExpander::MacroRules(it) => it.expand(tt),
33+
TokenExpander::Builtin(it) => it.expand(db, id, tt),
3334
// FIXME switch these to ExpandResult as well
34-
TokenExpander::Builtin(it) => it.expand(db, id, tt).into(),
3535
TokenExpander::BuiltinDerive(it) => it.expand(db, id, tt).into(),
3636
TokenExpander::ProcMacro(_) => {
3737
// We store the result in salsa db to prevent non-determinisc behavior in

crates/hir_expand/src/eager.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ pub fn expand_eager_macro(
6565
let subtree = to_subtree(&result)?;
6666

6767
if let MacroDefKind::BuiltInEager(eager) = def.kind {
68-
let (subtree, fragment) = eager.expand(db, arg_id, &subtree).ok()?;
68+
let (subtree, fragment) = eager.expand(db, arg_id, &subtree).value?;
6969
let eager = EagerCallLoc {
7070
def,
7171
fragment,

0 commit comments

Comments
 (0)