Unnamed repository; edit this file 'description' to name the repository.
Insert builtin#asm into asm! expansion
Lukas Wirth 2023-09-05
parent 1504830 · commit 3431d58
-rw-r--r--crates/hir-def/src/body/lower.rs9
-rw-r--r--crates/hir-def/src/body/pretty.rs3
-rw-r--r--crates/hir-def/src/hir.rs7
-rw-r--r--crates/hir-ty/src/infer/closure.rs1
-rw-r--r--crates/hir-ty/src/infer/expr.rs4
-rw-r--r--crates/hir-ty/src/infer/mutability.rs1
-rw-r--r--crates/hir-ty/src/mir/lower.rs3
-rw-r--r--crates/ide/src/syntax_highlighting/test_data/highlight_strings.html10
-rw-r--r--crates/parser/src/grammar/expressions/atom.rs1
-rw-r--r--crates/parser/test_data/parser/inline/ok/0207_builtin_expr.rast62
-rw-r--r--crates/parser/test_data/parser/inline/ok/0207_builtin_expr.rs5
-rw-r--r--crates/syntax/rust.ungram2
-rw-r--r--crates/syntax/src/ast/generated/nodes.rs1
13 files changed, 103 insertions, 6 deletions
diff --git a/crates/hir-def/src/body/lower.rs b/crates/hir-def/src/body/lower.rs
index b536da2e57..038032e05d 100644
--- a/crates/hir-def/src/body/lower.rs
+++ b/crates/hir-def/src/body/lower.rs
@@ -30,8 +30,8 @@ use crate::{
expander::Expander,
hir::{
dummy_expr_id, Array, Binding, BindingAnnotation, BindingId, BindingProblems, CaptureBy,
- ClosureKind, Expr, ExprId, Label, LabelId, Literal, LiteralOrConst, MatchArm, Movability,
- OffsetOf, Pat, PatId, RecordFieldPat, RecordLitField, Statement,
+ ClosureKind, Expr, ExprId, InlineAsm, Label, LabelId, Literal, LiteralOrConst, MatchArm,
+ Movability, OffsetOf, Pat, PatId, RecordFieldPat, RecordLitField, Statement,
},
item_scope::BuiltinShadowMode,
lang_item::LangItem,
@@ -648,7 +648,10 @@ impl ExprCollector<'_> {
}
}
ast::Expr::UnderscoreExpr(_) => self.alloc_expr(Expr::Underscore, syntax_ptr),
- ast::Expr::AsmExpr(_) => self.missing_expr(),
+ ast::Expr::AsmExpr(e) => {
+ let expr = Expr::InlineAsm(InlineAsm { e: self.collect_expr_opt(e.expr()) });
+ self.alloc_expr(expr, syntax_ptr)
+ }
ast::Expr::OffsetOfExpr(e) => {
let container = Interned::new(TypeRef::from_ast_opt(&self.ctx(), e.ty()));
let fields = e.fields().map(|it| it.as_name()).collect();
diff --git a/crates/hir-def/src/body/pretty.rs b/crates/hir-def/src/body/pretty.rs
index 6058fcbb65..602a7983c7 100644
--- a/crates/hir-def/src/body/pretty.rs
+++ b/crates/hir-def/src/body/pretty.rs
@@ -155,8 +155,9 @@ impl Printer<'_> {
match expr {
Expr::Missing => w!(self, "�"),
Expr::Underscore => w!(self, "_"),
+ Expr::InlineAsm(_) => w!(self, "builtin#asm(_)"),
Expr::OffsetOf(offset_of) => {
- w!(self, "builtin#offset_of!(");
+ w!(self, "builtin#offset_of(");
self.print_type_ref(&offset_of.container);
w!(
self,
diff --git a/crates/hir-def/src/hir.rs b/crates/hir-def/src/hir.rs
index f03df800a0..1c86af456d 100644
--- a/crates/hir-def/src/hir.rs
+++ b/crates/hir-def/src/hir.rs
@@ -282,6 +282,7 @@ pub enum Expr {
Literal(Literal),
Underscore,
OffsetOf(OffsetOf),
+ InlineAsm(InlineAsm),
}
#[derive(Debug, Clone, PartialEq, Eq)]
@@ -290,6 +291,11 @@ pub struct OffsetOf {
pub fields: Box<[Name]>,
}
+#[derive(Debug, Clone, PartialEq, Eq)]
+pub struct InlineAsm {
+ pub e: ExprId,
+}
+
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ClosureKind {
Closure,
@@ -349,6 +355,7 @@ impl Expr {
match self {
Expr::Missing => {}
Expr::Path(_) | Expr::OffsetOf(_) => {}
+ Expr::InlineAsm(e) => f(e.e),
Expr::If { condition, then_branch, else_branch } => {
f(*condition);
f(*then_branch);
diff --git a/crates/hir-ty/src/infer/closure.rs b/crates/hir-ty/src/infer/closure.rs
index ceb96a7165..1f040393f1 100644
--- a/crates/hir-ty/src/infer/closure.rs
+++ b/crates/hir-ty/src/infer/closure.rs
@@ -453,6 +453,7 @@ impl InferenceContext<'_> {
fn walk_expr_without_adjust(&mut self, tgt_expr: ExprId) {
match &self.body[tgt_expr] {
Expr::OffsetOf(_) => (),
+ Expr::InlineAsm(e) => self.walk_expr_without_adjust(e.e),
Expr::If { condition, then_branch, else_branch } => {
self.consume_expr(*condition);
self.consume_expr(*then_branch);
diff --git a/crates/hir-ty/src/infer/expr.rs b/crates/hir-ty/src/infer/expr.rs
index d139d929fc..555a9fae48 100644
--- a/crates/hir-ty/src/infer/expr.rs
+++ b/crates/hir-ty/src/infer/expr.rs
@@ -844,6 +844,10 @@ impl InferenceContext<'_> {
expected
}
Expr::OffsetOf(_) => TyKind::Scalar(Scalar::Uint(UintTy::Usize)).intern(Interner),
+ Expr::InlineAsm(it) => {
+ self.infer_expr_no_expect(it.e);
+ self.result.standard_types.unit.clone()
+ }
};
// use a new type variable if we got unknown here
let ty = self.insert_type_vars_shallow(ty);
diff --git a/crates/hir-ty/src/infer/mutability.rs b/crates/hir-ty/src/infer/mutability.rs
index 853c171a06..b8a1af96fb 100644
--- a/crates/hir-ty/src/infer/mutability.rs
+++ b/crates/hir-ty/src/infer/mutability.rs
@@ -35,6 +35,7 @@ impl InferenceContext<'_> {
fn infer_mut_expr_without_adjust(&mut self, tgt_expr: ExprId, mutability: Mutability) {
match &self.body[tgt_expr] {
Expr::Missing => (),
+ Expr::InlineAsm(e) => self.infer_mut_expr_without_adjust(e.e, Mutability::Not),
Expr::OffsetOf(_) => (),
&Expr::If { condition, then_branch, else_branch } => {
self.infer_mut_expr(condition, Mutability::Not);
diff --git a/crates/hir-ty/src/mir/lower.rs b/crates/hir-ty/src/mir/lower.rs
index 3410c87d39..b6408cea50 100644
--- a/crates/hir-ty/src/mir/lower.rs
+++ b/crates/hir-ty/src/mir/lower.rs
@@ -373,6 +373,9 @@ impl<'ctx> MirLowerCtx<'ctx> {
Expr::OffsetOf(_) => {
not_supported!("builtin#offset_of")
}
+ Expr::InlineAsm(_) => {
+ not_supported!("builtin#asm")
+ }
Expr::Missing => {
if let DefWithBodyId::FunctionId(f) = self.owner {
let assoc = f.lookup(self.db.upcast());
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_strings.html b/crates/ide/src/syntax_highlighting/test_data/highlight_strings.html
index 3ac8aa9cc9..9c5c6d50ea 100644
--- a/crates/ide/src/syntax_highlighting/test_data/highlight_strings.html
+++ b/crates/ide/src/syntax_highlighting/test_data/highlight_strings.html
@@ -176,7 +176,15 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
<span class="macro">assert</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="bool_literal macro">true</span><span class="comma macro">,</span> <span class="string_literal macro">"</span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro">"</span><span class="comma macro">,</span> <span class="numeric_literal macro">1</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
<span class="macro">assert</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="bool_literal macro">true</span><span class="comma macro">,</span> <span class="string_literal macro">"</span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro"> asdasd"</span><span class="comma macro">,</span> <span class="numeric_literal macro">1</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
<span class="macro">toho</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"</span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro">fmt"</span><span class="comma macro">,</span> <span class="numeric_literal macro">0</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
- <span class="macro unsafe">asm</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"mov eax, </span><span class="format_specifier">{</span><span class="numeric_literal">0</span><span class="format_specifier">}</span><span class="string_literal macro">"</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
+ <span class="keyword">let</span> <span class="variable declaration">i</span><span class="colon">:</span> <span class="builtin_type">u64</span> <span class="operator">=</span> <span class="numeric_literal">3</span><span class="semicolon">;</span>
+ <span class="keyword">let</span> <span class="variable declaration">o</span><span class="colon">:</span> <span class="builtin_type">u64</span><span class="semicolon">;</span>
+ <span class="macro unsafe">asm</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span>
+ <span class="string_literal macro">"mov </span><span class="format_specifier">{</span><span class="numeric_literal">0</span><span class="format_specifier">}</span><span class="string_literal macro">, </span><span class="format_specifier">{</span><span class="numeric_literal">1</span><span class="format_specifier">}</span><span class="string_literal macro">"</span><span class="comma macro">,</span>
+ <span class="string_literal macro">"add </span><span class="format_specifier">{</span><span class="numeric_literal">0</span><span class="format_specifier">}</span><span class="string_literal macro">, 5"</span><span class="comma macro">,</span>
+ <span class="none macro">out</span><span class="parenthesis macro">(</span><span class="none macro">reg</span><span class="parenthesis macro">)</span> <span class="none macro">o</span><span class="comma macro">,</span>
+ <span class="keyword control macro">in</span><span class="parenthesis macro">(</span><span class="none macro">reg</span><span class="parenthesis macro">)</span> <span class="none macro">i</span><span class="comma macro">,</span>
+ <span class="parenthesis macro">)</span><span class="semicolon">;</span>
+
<span class="macro">format_args</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="none macro">concat</span><span class="punctuation macro">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"</span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro">"</span><span class="parenthesis macro">)</span><span class="comma macro">,</span> <span class="string_literal macro">"{}"</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
<span class="macro">format_args</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"</span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro"> </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro"> </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro"> </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro"> </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro"> </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro">"</span><span class="comma macro">,</span> <span class="variable macro reference">backslash</span><span class="comma macro">,</span> <span class="none macro">format_args</span><span class="punctuation macro">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"</span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro">"</span><span class="comma macro">,</span> <span class="numeric_literal macro">0</span><span class="parenthesis macro">)</span><span class="comma macro">,</span> <span class="unresolved_reference macro">foo</span><span class="comma macro">,</span> <span class="string_literal macro">"bar"</span><span class="comma macro">,</span> <span class="none macro">toho</span><span class="punctuation macro">!</span><span class="parenthesis macro">(</span><span class="parenthesis macro">)</span><span class="comma macro">,</span> <span class="variable macro reference">backslash</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
<span class="brace">}</span></code></pre> \ No newline at end of file
diff --git a/crates/parser/src/grammar/expressions/atom.rs b/crates/parser/src/grammar/expressions/atom.rs
index 1dd68f556c..e13284d1b7 100644
--- a/crates/parser/src/grammar/expressions/atom.rs
+++ b/crates/parser/src/grammar/expressions/atom.rs
@@ -254,6 +254,7 @@ fn builtin_expr(p: &mut Parser<'_>) -> Option<CompletedMarker> {
} else if p.at_contextual_kw(T![asm]) {
p.bump_remap(T![asm]);
p.expect(T!['(']);
+ // FIXME: We just put expression here so highlighting kind of keeps working
expr(p);
p.expect(T![')']);
Some(m.complete(p, ASM_EXPR))
diff --git a/crates/parser/test_data/parser/inline/ok/0207_builtin_expr.rast b/crates/parser/test_data/parser/inline/ok/0207_builtin_expr.rast
new file mode 100644
index 0000000000..f127b3e8c8
--- /dev/null
+++ b/crates/parser/test_data/parser/inline/ok/0207_builtin_expr.rast
@@ -0,0 +1,62 @@
+SOURCE_FILE
+ FN
+ FN_KW "fn"
+ WHITESPACE " "
+ NAME
+ IDENT "foo"
+ PARAM_LIST
+ L_PAREN "("
+ R_PAREN ")"
+ WHITESPACE " "
+ BLOCK_EXPR
+ STMT_LIST
+ L_CURLY "{"
+ WHITESPACE "\n "
+ EXPR_STMT
+ ASM_EXPR
+ BUILTIN_KW "builtin"
+ POUND "#"
+ ASM_KW "asm"
+ L_PAREN "("
+ LITERAL
+ INT_NUMBER "0"
+ R_PAREN ")"
+ SEMICOLON ";"
+ WHITESPACE "\n "
+ EXPR_STMT
+ FORMAT_ARGS_EXPR
+ BUILTIN_KW "builtin"
+ POUND "#"
+ FORMAT_ARGS_KW "format_args"
+ L_PAREN "("
+ LITERAL
+ INT_NUMBER "0"
+ R_PAREN ")"
+ SEMICOLON ";"
+ WHITESPACE "\n "
+ EXPR_STMT
+ OFFSET_OF_EXPR
+ BUILTIN_KW "builtin"
+ POUND "#"
+ OFFSET_OF_KW "offset_of"
+ L_PAREN "("
+ PATH_TYPE
+ PATH
+ PATH_SEGMENT
+ NAME_REF
+ IDENT "Foo"
+ COMMA ","
+ WHITESPACE " "
+ NAME_REF
+ IDENT "bar"
+ DOT "."
+ NAME_REF
+ IDENT "baz"
+ DOT "."
+ NAME_REF
+ INT_NUMBER "0"
+ R_PAREN ")"
+ SEMICOLON ";"
+ WHITESPACE "\n"
+ R_CURLY "}"
+ WHITESPACE "\n"
diff --git a/crates/parser/test_data/parser/inline/ok/0207_builtin_expr.rs b/crates/parser/test_data/parser/inline/ok/0207_builtin_expr.rs
new file mode 100644
index 0000000000..dbad0a91df
--- /dev/null
+++ b/crates/parser/test_data/parser/inline/ok/0207_builtin_expr.rs
@@ -0,0 +1,5 @@
+fn foo() {
+ builtin#asm(0);
+ builtin#format_args(0);
+ builtin#offset_of(Foo, bar.baz.0);
+}
diff --git a/crates/syntax/rust.ungram b/crates/syntax/rust.ungram
index d7b1c91216..2ce609b97a 100644
--- a/crates/syntax/rust.ungram
+++ b/crates/syntax/rust.ungram
@@ -379,7 +379,7 @@ OffsetOfExpr =
Attr* 'builtin' '#' 'offset_of' '(' Type ',' fields:(NameRef ('.' NameRef)* ) ')'
AsmExpr =
- Attr* 'builtin' '#' 'asm' '(' ')'
+ Attr* 'builtin' '#' 'asm' '(' Expr ')'
FormatArgsExpr =
Attr* 'builtin' '#' 'format_args' '(' ')'
diff --git a/crates/syntax/src/ast/generated/nodes.rs b/crates/syntax/src/ast/generated/nodes.rs
index d817589223..1c5e2282ec 100644
--- a/crates/syntax/src/ast/generated/nodes.rs
+++ b/crates/syntax/src/ast/generated/nodes.rs
@@ -814,6 +814,7 @@ impl AsmExpr {
pub fn pound_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![#]) }
pub fn asm_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![asm]) }
pub fn l_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['(']) }
+ pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) }
pub fn r_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![')']) }
}