Skip to content

Commit

Permalink
Insert builtin#asm into asm! expansion
Browse files Browse the repository at this point in the history
  • Loading branch information
Veykril committed Sep 5, 2023
1 parent 1504830 commit 06843e4
Show file tree
Hide file tree
Showing 13 changed files with 146 additions and 6 deletions.
9 changes: 6 additions & 3 deletions crates/hir-def/src/body/lower.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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();
Expand Down
3 changes: 2 additions & 1 deletion crates/hir-def/src/body/pretty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
7 changes: 7 additions & 0 deletions crates/hir-def/src/hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,7 @@ pub enum Expr {
Literal(Literal),
Underscore,
OffsetOf(OffsetOf),
InlineAsm(InlineAsm),
}

#[derive(Debug, Clone, PartialEq, Eq)]
Expand All @@ -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,
Expand Down Expand Up @@ -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);
Expand Down
1 change: 1 addition & 0 deletions crates/hir-ty/src/infer/closure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
4 changes: 4 additions & 0 deletions crates/hir-ty/src/infer/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
1 change: 1 addition & 0 deletions crates/hir-ty/src/infer/mutability.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
3 changes: 3 additions & 0 deletions crates/hir-ty/src/mir/lower.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,15 @@
<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>
1 change: 1 addition & 0 deletions crates/parser/src/grammar/expressions/atom.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down
105 changes: 105 additions & 0 deletions crates/parser/test_data/parser/inline/ok/0207_builtin_expr.rast
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
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
STRING "\"\""
COMMA ","
WHITESPACE " "
FORMAT_ARGS_ARG
LITERAL
INT_NUMBER "0"
COMMA ","
WHITESPACE " "
FORMAT_ARGS_ARG
LITERAL
INT_NUMBER "1"
COMMA ","
WHITESPACE " "
FORMAT_ARGS_ARG
NAME
IDENT "a"
WHITESPACE " "
EQ "="
WHITESPACE " "
BIN_EXPR
LITERAL
INT_NUMBER "2"
WHITESPACE " "
PLUS "+"
WHITESPACE " "
LITERAL
INT_NUMBER "3"
COMMA ","
WHITESPACE " "
FORMAT_ARGS_ARG
BIN_EXPR
PATH_EXPR
PATH
PATH_SEGMENT
NAME_REF
IDENT "a"
WHITESPACE " "
PLUS "+"
WHITESPACE " "
PATH_EXPR
PATH
PATH_SEGMENT
NAME_REF
IDENT "b"
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"
5 changes: 5 additions & 0 deletions crates/parser/test_data/parser/inline/ok/0207_builtin_expr.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
fn foo() {
builtin#asm(0);
builtin#format_args(0);
builtin#offset_of(Foo, bar.baz.0);
}
2 changes: 1 addition & 1 deletion crates/syntax/rust.ungram
Original file line number Diff line number Diff line change
Expand Up @@ -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' '(' ')'
Expand Down
1 change: 1 addition & 0 deletions crates/syntax/src/ast/generated/nodes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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![')']) }
}

Expand Down

0 comments on commit 06843e4

Please sign in to comment.