Skip to content

Commit

Permalink
unsafe block
Browse files Browse the repository at this point in the history
  • Loading branch information
Grant Wuerker committed Mar 7, 2024
1 parent 65f3804 commit c80078a
Show file tree
Hide file tree
Showing 13 changed files with 158 additions and 7 deletions.
2 changes: 1 addition & 1 deletion crates/hir-analysis/src/name_resolution/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -425,7 +425,7 @@ impl<'db, 'a> Visitor for EarlyPathVisitor<'db, 'a> {
expr: ExprId,
expr_data: &Expr,
) {
if matches!(expr_data, Expr::Block(_)) {
if matches!(expr_data, Expr::Block { .. }) {
walk_expr(self, ctxt, expr)
}
}
Expand Down
2 changes: 1 addition & 1 deletion crates/hir/src/hir_def/body.rs
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ impl<'db> Visitor for BlockOrderCalculator<'db> {
expr: ExprId,
expr_data: &Expr,
) {
if ctxt.body() == self.body && matches!(expr_data, Expr::Block(..)) {
if ctxt.body() == self.body && matches!(expr_data, Expr::Block { .. }) {
self.order.insert(expr, self.fresh_number);
self.fresh_number += 1;
}
Expand Down
5 changes: 4 additions & 1 deletion crates/hir/src/hir_def/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@ use super::{Body, GenericArgListId, IdentId, IntegerId, LitKind, Partial, PatId,
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum Expr {
Lit(LitKind),
Block(Vec<StmtId>),
Block {
stmts: Vec<StmtId>,
is_unsafe: bool,
},
/// The first `ExprId` is the lhs, the second is the rhs.
///
/// and a `BinOp`.
Expand Down
8 changes: 7 additions & 1 deletion crates/hir/src/lower/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,13 @@ impl Expr {
let stmt = Stmt::push_to_body(ctxt, stmt);
stmts.push(stmt);
}
let expr_id = ctxt.push_expr(Self::Block(stmts), HirOrigin::raw(&ast));
let expr_id = ctxt.push_expr(
Self::Block {
stmts,
is_unsafe: block.unsafe_kw().is_some(),
},
HirOrigin::raw(&ast),
);

for item in block.items() {
ItemKind::lower_ast(ctxt.f_ctxt, item);
Expand Down
8 changes: 8 additions & 0 deletions crates/hir/src/span/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,14 @@ define_lazy_span_node!(

define_lazy_span_node!(LazyMatchArmSpan);

define_lazy_span_node!(
LazyBlockExprSpan,
ast::BlockExpr,
@token {
(unsafe_kw, unsafe_kw),
}
);

#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
pub(crate) struct ExprRoot {
expr: ExprId,
Expand Down
4 changes: 2 additions & 2 deletions crates/hir/src/visitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -909,7 +909,7 @@ where
},
),

Expr::Block(stmts) => {
Expr::Block { stmts, .. } => {
let s_graph = ctxt.top_mod().scope_graph(ctxt.db);
let scope = ctxt.scope();
for item in s_graph.child_items(scope) {
Expand Down Expand Up @@ -1987,7 +1987,7 @@ where
/// `scope` is the scope that encloses the expression.
pub fn with_expr(db: &'db dyn HirDb, scope: ScopeId, body: Body, expr: ExprId) -> Self {
let scope_id = match expr.data(db, body) {
Partial::Present(Expr::Block(_)) => ScopeId::Block(body, expr),
Partial::Present(Expr::Block { .. }) => ScopeId::Block(body, expr),
_ => scope,
};

Expand Down
4 changes: 4 additions & 0 deletions crates/parser2/src/ast/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,10 @@ impl BlockExpr {
pub fn items(&self) -> impl Iterator<Item = super::Item> {
support::children(self.syntax())
}

pub fn unsafe_kw(&self) -> Option<SyntaxToken> {
support::token(self.syntax(), SK::UnsafeKw)
}
}

ast_node! {
Expand Down
5 changes: 5 additions & 0 deletions crates/parser2/src/parser/expr_atom.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ pub(super) fn parse_expr_atom<S: TokenStream>(
match parser.current_kind() {
Some(IfKw) => parser.parse(IfExprScope::default(), None),
Some(MatchKw) => parser.parse(MatchExprScope::default(), None),
Some(UnsafeKw) => parser.parse(BlockExprScope::default(), None),
Some(LBrace) => parser.parse(BlockExprScope::default(), None),
Some(LParen) => parser.parse(ParenScope::default(), None),
Some(LBracket) => parser.parse(ArrayScope::default(), None),
Expand Down Expand Up @@ -53,6 +54,10 @@ define_scope! {
}
impl super::Parse for BlockExprScope {
fn parse<S: TokenStream>(&mut self, parser: &mut Parser<S>) {
if parser.current_kind() == Some(SyntaxKind::UnsafeKw) {
parser.bump_expected(SyntaxKind::UnsafeKw);
}

parser.bump_expected(SyntaxKind::LBrace);

loop {
Expand Down
2 changes: 2 additions & 0 deletions crates/parser2/src/syntax_kind.rs
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,8 @@ pub enum SyntaxKind {
IfExpr,
/// `match x { pat => { .. } }`
MatchExpr,
/// `unsafe { foo() }`
UnsafeExpr,
/// `(1 + 2)`
ParenExpr,
/// x = 1
Expand Down
7 changes: 7 additions & 0 deletions crates/parser2/test_files/syntax_node/exprs/unsafe.fe
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
unsafe { foo() }

unsafe {
let a = 42
std::evm::mstore(offset: 0, value: a)
return
}
84 changes: 84 additions & 0 deletions crates/parser2/test_files/syntax_node/exprs/unsafe.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
---
source: crates/parser2/tests/syntax_node.rs
expression: node
input_file: crates/parser2/test_files/syntax_node/exprs/unsafe.fe
---
Root@0..97
BlockExpr@0..16
UnsafeKw@0..6 "unsafe"
WhiteSpace@6..7 " "
LBrace@7..8 "{"
WhiteSpace@8..9 " "
ExprStmt@9..14
CallExpr@9..14
PathExpr@9..12
Path@9..12
PathSegment@9..12
Ident@9..12 "foo"
CallArgList@12..14
LParen@12..13 "("
RParen@13..14 ")"
WhiteSpace@14..15 " "
RBrace@15..16 "}"
Newline@16..18 "\n\n"
BlockExpr@18..96
UnsafeKw@18..24 "unsafe"
WhiteSpace@24..25 " "
LBrace@25..26 "{"
Newline@26..27 "\n"
WhiteSpace@27..31 " "
LetStmt@31..41
LetKw@31..34 "let"
WhiteSpace@34..35 " "
PathPat@35..36
Path@35..36
PathSegment@35..36
Ident@35..36 "a"
WhiteSpace@36..37 " "
Eq@37..38 "="
WhiteSpace@38..39 " "
LitExpr@39..41
Lit@39..41
Int@39..41 "42"
Newline@41..42 "\n"
WhiteSpace@42..46 " "
ExprStmt@46..83
CallExpr@46..83
PathExpr@46..62
Path@46..62
PathSegment@46..49
Ident@46..49 "std"
Colon2@49..51 "::"
PathSegment@51..54
Ident@51..54 "evm"
Colon2@54..56 "::"
PathSegment@56..62
Ident@56..62 "mstore"
CallArgList@62..83
LParen@62..63 "("
CallArg@63..72
Ident@63..69 "offset"
Colon@69..70 ":"
WhiteSpace@70..71 " "
LitExpr@71..72
Lit@71..72
Int@71..72 "0"
Comma@72..73 ","
WhiteSpace@73..74 " "
CallArg@74..82
Ident@74..79 "value"
Colon@79..80 ":"
WhiteSpace@80..81 " "
PathExpr@81..82
Path@81..82
PathSegment@81..82
Ident@81..82 "a"
RParen@82..83 ")"
Newline@83..84 "\n"
WhiteSpace@84..88 " "
ReturnStmt@88..94
ReturnKw@88..94 "return"
Newline@94..95 "\n"
RBrace@95..96 "}"
Newline@96..97 "\n"

4 changes: 4 additions & 0 deletions crates/parser2/test_files/syntax_node/stmts/let.fe
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,8 @@ let x = if b {
let x = match b {
MyEnum::A(x) | MyEnum::B(x) => x
_ => 0
}

let z = unsafe {
foo()
}
30 changes: 29 additions & 1 deletion crates/parser2/test_files/syntax_node/stmts/let.snap
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ source: crates/parser2/tests/syntax_node.rs
expression: node
input_file: crates/parser2/test_files/syntax_node/stmts/let.fe
---
Root@0..231
Root@0..261
LetStmt@0..5
LetKw@0..3 "let"
WhiteSpace@3..4 " "
Expand Down Expand Up @@ -298,4 +298,32 @@ [email protected]
Int@228..229 "0"
Newline@229..230 "\n"
RBrace@230..231 "}"
Newline@231..233 "\n\n"
LetStmt@233..261
LetKw@233..236 "let"
WhiteSpace@236..237 " "
PathPat@237..238
Path@237..238
PathSegment@237..238
Ident@237..238 "z"
WhiteSpace@238..239 " "
Eq@239..240 "="
WhiteSpace@240..241 " "
BlockExpr@241..261
UnsafeKw@241..247 "unsafe"
WhiteSpace@247..248 " "
LBrace@248..249 "{"
Newline@249..250 "\n"
WhiteSpace@250..254 " "
ExprStmt@254..259
CallExpr@254..259
PathExpr@254..257
Path@254..257
PathSegment@254..257
Ident@254..257 "foo"
CallArgList@257..259
LParen@257..258 "("
RParen@258..259 ")"
Newline@259..260 "\n"
RBrace@260..261 "}"

0 comments on commit c80078a

Please sign in to comment.