Skip to content

Commit 9b8eb80

Browse files
committed
Parse builtin# syntax
1 parent db4684e commit 9b8eb80

File tree

17 files changed

+257
-81
lines changed

17 files changed

+257
-81
lines changed

crates/hir-def/src/body/lower.rs

+4-5
Original file line numberDiff line numberDiff line change
@@ -579,11 +579,6 @@ impl ExprCollector<'_> {
579579
syntax_ptr,
580580
)
581581
}
582-
ast::Expr::BoxExpr(e) => {
583-
let expr = self.collect_expr_opt(e.expr());
584-
self.alloc_expr(Expr::Box { expr }, syntax_ptr)
585-
}
586-
587582
ast::Expr::ArrayExpr(e) => {
588583
let kind = e.kind();
589584

@@ -653,6 +648,9 @@ impl ExprCollector<'_> {
653648
}
654649
}
655650
ast::Expr::UnderscoreExpr(_) => self.alloc_expr(Expr::Underscore, syntax_ptr),
651+
ast::Expr::AsmExpr(_) => self.missing_expr(),
652+
ast::Expr::OffsetOfExpr(_) => self.missing_expr(),
653+
ast::Expr::FormatArgsExpr(_) => self.missing_expr(),
656654
})
657655
}
658656

@@ -663,6 +661,7 @@ impl ExprCollector<'_> {
663661
let result_expr_id = self.alloc_expr(Expr::Missing, syntax_ptr);
664662
let prev_binding_owner = self.current_binding_owner.take();
665663
self.current_binding_owner = Some(result_expr_id);
664+
666665
(result_expr_id, prev_binding_owner)
667666
}
668667

crates/hir-def/src/macro_expansion_tests/builtin_fn_macro.rs

+29
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,35 @@ fn main() { 0 as u32; }
2222
);
2323
}
2424

25+
#[test]
26+
fn test_asm_expand() {
27+
check(
28+
r#"
29+
#[rustc_builtin_macro]
30+
macro_rules! asm {() => {}}
31+
32+
fn main() {
33+
let i: u64 = 3;
34+
let o: u64;
35+
unsafe {
36+
asm!(
37+
"mov {0}, {1}",
38+
"add {0}, 5",
39+
out(reg) o,
40+
in(reg) i,
41+
);
42+
}
43+
}
44+
"#,
45+
expect![[r#"
46+
#[rustc_builtin_macro]
47+
macro_rules! column {() => {}}
48+
49+
fn main() { 0 as u32; }
50+
"#]],
51+
);
52+
}
53+
2554
#[test]
2655
fn test_line_expand() {
2756
check(

crates/hir-expand/src/builtin_fn_macro.rs

+8-4
Original file line numberDiff line numberDiff line change
@@ -399,6 +399,8 @@ fn asm_expand(
399399
_id: MacroCallId,
400400
tt: &tt::Subtree,
401401
) -> ExpandResult<tt::Subtree> {
402+
// FIXME: parse asm here
403+
402404
// We expand all assembly snippets to `format_args!` invocations to get format syntax
403405
// highlighting for them.
404406

@@ -415,10 +417,12 @@ fn asm_expand(
415417
}
416418
}
417419

418-
let expanded = quote! {{
419-
##literals
420-
loop {}
421-
}};
420+
let pound = quote! {@PUNCT '#'};
421+
let expanded = quote! {
422+
builtin #pound asm {
423+
##literals
424+
}
425+
};
422426
ExpandResult::ok(expanded)
423427
}
424428

crates/hir-ty/src/infer/closure.rs

+1
Original file line numberDiff line numberDiff line change
@@ -620,6 +620,7 @@ impl InferenceContext<'_> {
620620
| Expr::Tuple { exprs, is_assignee_expr: _ } => {
621621
self.consume_exprs(exprs.iter().copied())
622622
}
623+
623624
Expr::Missing
624625
| Expr::Continue { .. }
625626
| Expr::Path(_)

crates/ide-assists/src/handlers/convert_bool_then.rs

-1
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,6 @@ pub(crate) fn convert_if_to_bool_then(acc: &mut Assists, ctx: &AssistContext<'_>
103103
cond,
104104
ast::Expr::BinExpr(_)
105105
| ast::Expr::BlockExpr(_)
106-
| ast::Expr::BoxExpr(_)
107106
| ast::Expr::BreakExpr(_)
108107
| ast::Expr::CastExpr(_)
109108
| ast::Expr::ClosureExpr(_)

crates/ide-assists/src/handlers/promote_local_to_const.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -120,8 +120,7 @@ fn is_body_const(sema: &Semantics<'_, RootDatabase>, expr: &ast::Expr) -> bool {
120120
is_const &=
121121
sema.resolve_method_call(&call).map(|it| it.is_const(sema.db)).unwrap_or(true)
122122
}
123-
ast::Expr::BoxExpr(_)
124-
| ast::Expr::ForExpr(_)
123+
ast::Expr::ForExpr(_)
125124
| ast::Expr::ReturnExpr(_)
126125
| ast::Expr::TryExpr(_)
127126
| ast::Expr::YieldExpr(_)

crates/ide-assists/src/handlers/remove_dbg.rs

+1-4
Original file line numberDiff line numberDiff line change
@@ -113,10 +113,7 @@ fn compute_dbg_replacement(macro_expr: ast::MacroExpr) -> Option<(TextRange, Opt
113113
Some(parent) => match (expr, parent) {
114114
(ast::Expr::CastExpr(_), ast::Expr::CastExpr(_)) => false,
115115
(
116-
ast::Expr::BoxExpr(_)
117-
| ast::Expr::PrefixExpr(_)
118-
| ast::Expr::RefExpr(_)
119-
| ast::Expr::MacroExpr(_),
116+
ast::Expr::PrefixExpr(_) | ast::Expr::RefExpr(_) | ast::Expr::MacroExpr(_),
120117
ast::Expr::AwaitExpr(_)
121118
| ast::Expr::CallExpr(_)
122119
| ast::Expr::CastExpr(_)

crates/ide-assists/src/utils/suggest_name.rs

-1
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,6 @@ pub(crate) fn for_variable(expr: &ast::Expr, sema: &Semantics<'_, RootDatabase>)
103103

104104
match expr {
105105
ast::Expr::RefExpr(inner) => next_expr = inner.expr(),
106-
ast::Expr::BoxExpr(inner) => next_expr = inner.expr(),
107106
ast::Expr::AwaitExpr(inner) => next_expr = inner.expr(),
108107
// ast::Expr::BlockExpr(block) => expr = block.tail_expr(),
109108
ast::Expr::CastExpr(inner) => next_expr = inner.expr(),

crates/ide-db/src/syntax_helpers/node_ext.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,6 @@ pub fn for_each_tail_expr(expr: &ast::Expr, cb: &mut dyn FnMut(&ast::Expr)) {
312312
ast::Expr::ArrayExpr(_)
313313
| ast::Expr::AwaitExpr(_)
314314
| ast::Expr::BinExpr(_)
315-
| ast::Expr::BoxExpr(_)
316315
| ast::Expr::BreakExpr(_)
317316
| ast::Expr::CallExpr(_)
318317
| ast::Expr::CastExpr(_)
@@ -335,7 +334,10 @@ pub fn for_each_tail_expr(expr: &ast::Expr, cb: &mut dyn FnMut(&ast::Expr)) {
335334
| ast::Expr::LetExpr(_)
336335
| ast::Expr::UnderscoreExpr(_)
337336
| ast::Expr::YieldExpr(_)
338-
| ast::Expr::YeetExpr(_) => cb(expr),
337+
| ast::Expr::YeetExpr(_)
338+
| ast::Expr::OffsetOfExpr(_)
339+
| ast::Expr::FormatArgsExpr(_)
340+
| ast::Expr::AsmExpr(_) => cb(expr),
339341
}
340342
}
341343

crates/ide/src/syntax_highlighting/tests.rs

+9-1
Original file line numberDiff line numberDiff line change
@@ -534,7 +534,15 @@ fn main() {
534534
assert!(true, "{}", 1);
535535
assert!(true, "{} asdasd", 1);
536536
toho!("{}fmt", 0);
537-
asm!("mov eax, {0}");
537+
let i: u64 = 3;
538+
let o: u64;
539+
asm!(
540+
"mov {0}, {1}",
541+
"add {0}, 5",
542+
out(reg) o,
543+
in(reg) i,
544+
);
545+
538546
format_args!(concat!("{}"), "{}");
539547
format_args!("{} {} {} {} {} {}", backslash, format_args!("{}", 0), foo, "bar", toho!(), backslash);
540548
}"#,

crates/parser/src/grammar/expressions/atom.rs

+37-17
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use crate::grammar::types::type_;
2+
13
use super::*;
24

35
// test expr_literals
@@ -73,6 +75,9 @@ pub(super) fn atom_expr(
7375
if let Some(m) = literal(p) {
7476
return Some((m, BlockLike::NotBlock));
7577
}
78+
if p.at_contextual_kw(T![builtin]) && p.nth_at(1, T![#]) {
79+
return Some((builtin_expr(p)?, BlockLike::NotBlock));
80+
}
7681
if paths::is_path_start(p) {
7782
return Some(path_expr(p, r));
7883
}
@@ -93,7 +98,6 @@ pub(super) fn atom_expr(
9398
m.complete(p, UNDERSCORE_EXPR)
9499
}
95100
T![loop] => loop_expr(p, None),
96-
T![box] => box_expr(p, None),
97101
T![while] => while_expr(p, None),
98102
T![try] => try_block_expr(p, None),
99103
T![match] => match_expr(p),
@@ -212,6 +216,38 @@ fn tuple_expr(p: &mut Parser<'_>) -> CompletedMarker {
212216
m.complete(p, if saw_expr && !saw_comma { PAREN_EXPR } else { TUPLE_EXPR })
213217
}
214218

219+
// test builtin_expr
220+
// fn foo() {
221+
// builtin#asm(0);
222+
// builtin#format_args(0);
223+
// builtin#builtin(0);
224+
// }
225+
fn builtin_expr(p: &mut Parser<'_>) -> Option<CompletedMarker> {
226+
let m = p.start();
227+
p.bump_remap(T![builtin]);
228+
p.bump(T![#]);
229+
if p.at_contextual_kw(T![offset_of]) {
230+
p.expect(T!['(']);
231+
type_(p);
232+
p.bump(T![,]);
233+
p.expect(T![')']);
234+
Some(m.complete(p, OFFSET_OF_EXPR))
235+
} else if p.at_contextual_kw(T![format_args]) {
236+
p.expect(T!['(']);
237+
expr(p);
238+
p.expect(T![')']);
239+
Some(m.complete(p, FORMAT_ARGS_EXPR))
240+
} else if p.at_contextual_kw(T![asm]) {
241+
p.expect(T!['(']);
242+
expr(p);
243+
p.expect(T![')']);
244+
Some(m.complete(p, ASM_EXPR))
245+
} else {
246+
m.abandon(p);
247+
None
248+
}
249+
}
250+
215251
// test array_expr
216252
// fn foo() {
217253
// [];
@@ -662,19 +698,3 @@ fn try_block_expr(p: &mut Parser<'_>, m: Option<Marker>) -> CompletedMarker {
662698
}
663699
m.complete(p, BLOCK_EXPR)
664700
}
665-
666-
// test box_expr
667-
// fn foo() {
668-
// let x = box 1i32;
669-
// let y = (box 1i32, box 2i32);
670-
// let z = Foo(box 1i32, box 2i32);
671-
// }
672-
fn box_expr(p: &mut Parser<'_>, m: Option<Marker>) -> CompletedMarker {
673-
assert!(p.at(T![box]));
674-
let m = m.unwrap_or_else(|| p.start());
675-
p.bump(T![box]);
676-
if p.at_ts(EXPR_FIRST) {
677-
expr(p);
678-
}
679-
m.complete(p, BOX_EXPR)
680-
}

crates/parser/src/lexed_str.rs

+1
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,7 @@ impl<'a> Converter<'a> {
221221
rustc_lexer::TokenKind::Caret => T![^],
222222
rustc_lexer::TokenKind::Percent => T![%],
223223
rustc_lexer::TokenKind::Unknown => ERROR,
224+
rustc_lexer::TokenKind::UnknownPrefix if token_text == "builtin" => IDENT,
224225
rustc_lexer::TokenKind::UnknownPrefix => {
225226
err = "unknown literal prefix";
226227
IDENT

0 commit comments

Comments
 (0)