Skip to content

Commit f2c5365

Browse files
author
Grant Wuerker
committed
unsafe block
1 parent 65f3804 commit f2c5365

File tree

15 files changed

+311
-13
lines changed

15 files changed

+311
-13
lines changed

crates/hir-analysis/src/name_resolution/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -425,7 +425,7 @@ impl<'db, 'a> Visitor for EarlyPathVisitor<'db, 'a> {
425425
expr: ExprId,
426426
expr_data: &Expr,
427427
) {
428-
if matches!(expr_data, Expr::Block(_)) {
428+
if matches!(expr_data, Expr::Block { .. }) {
429429
walk_expr(self, ctxt, expr)
430430
}
431431
}

crates/hir/src/hir_def/body.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ impl<'db> Visitor for BlockOrderCalculator<'db> {
164164
expr: ExprId,
165165
expr_data: &Expr,
166166
) {
167-
if ctxt.body() == self.body && matches!(expr_data, Expr::Block(..)) {
167+
if ctxt.body() == self.body && matches!(expr_data, Expr::Block { .. }) {
168168
self.order.insert(expr, self.fresh_number);
169169
self.fresh_number += 1;
170170
}

crates/hir/src/hir_def/expr.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,10 @@ use super::{Body, GenericArgListId, IdentId, IntegerId, LitKind, Partial, PatId,
77
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
88
pub enum Expr {
99
Lit(LitKind),
10-
Block(Vec<StmtId>),
10+
Block {
11+
stmts: Vec<StmtId>,
12+
is_unsafe: bool,
13+
},
1114
/// The first `ExprId` is the lhs, the second is the rhs.
1215
///
1316
/// and a `BinOp`.

crates/hir/src/lower/expr.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,13 @@ impl Expr {
2929
let stmt = Stmt::push_to_body(ctxt, stmt);
3030
stmts.push(stmt);
3131
}
32-
let expr_id = ctxt.push_expr(Self::Block(stmts), HirOrigin::raw(&ast));
32+
let expr_id = ctxt.push_expr(
33+
Self::Block {
34+
stmts,
35+
is_unsafe: block.unsafe_kw().is_some(),
36+
},
37+
HirOrigin::raw(&ast),
38+
);
3339

3440
for item in block.items() {
3541
ItemKind::lower_ast(ctxt.f_ctxt, item);

crates/hir/src/span/expr.rs

+8
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,14 @@ define_lazy_span_node!(
199199

200200
define_lazy_span_node!(LazyMatchArmSpan);
201201

202+
define_lazy_span_node!(
203+
LazyBlockExprSpan,
204+
ast::BlockExpr,
205+
@token {
206+
(unsafe_kw, unsafe_kw),
207+
}
208+
);
209+
202210
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
203211
pub(crate) struct ExprRoot {
204212
expr: ExprId,

crates/hir/src/visitor.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -909,7 +909,7 @@ where
909909
},
910910
),
911911

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

crates/parser2/src/ast/expr.rs

+4
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,10 @@ impl BlockExpr {
7474
pub fn items(&self) -> impl Iterator<Item = super::Item> {
7575
support::children(self.syntax())
7676
}
77+
78+
pub fn unsafe_kw(&self) -> Option<SyntaxToken> {
79+
support::token(self.syntax(), SK::UnsafeKw)
80+
}
7781
}
7882

7983
ast_node! {

crates/parser2/src/parser/expr_atom.rs

+13-2
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ pub(super) fn parse_expr_atom<S: TokenStream>(
2323
match parser.current_kind() {
2424
Some(IfKw) => parser.parse(IfExprScope::default(), None),
2525
Some(MatchKw) => parser.parse(MatchExprScope::default(), None),
26+
Some(UnsafeKw) => parser.parse(BlockExprScope::default(), None),
2627
Some(LBrace) => parser.parse(BlockExprScope::default(), None),
2728
Some(LParen) => parser.parse(ParenScope::default(), None),
2829
Some(LBracket) => parser.parse(ArrayScope::default(), None),
@@ -53,6 +54,10 @@ define_scope! {
5354
}
5455
impl super::Parse for BlockExprScope {
5556
fn parse<S: TokenStream>(&mut self, parser: &mut Parser<S>) {
57+
if parser.current_kind() == Some(SyntaxKind::UnsafeKw) {
58+
parser.bump_expected(SyntaxKind::UnsafeKw);
59+
}
60+
5661
parser.bump_expected(SyntaxKind::LBrace);
5762

5863
loop {
@@ -67,8 +72,14 @@ impl super::Parse for BlockExprScope {
6772
.map(SyntaxKind::is_item_head)
6873
.unwrap_or_default()
6974
{
70-
parser.parse(ItemScope::default(), None);
71-
continue;
75+
let is_unsafe_block = parser.dry_run(|parser| {
76+
parser.bump_if(SyntaxKind::UnsafeKw) && parser.bump_if(SyntaxKind::LBrace)
77+
});
78+
79+
if !is_unsafe_block {
80+
parser.parse(ItemScope::default(), None);
81+
continue;
82+
}
7283
}
7384

7485
if !parse_stmt(parser, None) {

crates/parser2/src/parser/item.rs

+7
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,13 @@ impl super::Parse for ItemScope {
7171
fn parse<S: TokenStream>(&mut self, parser: &mut Parser<S>) {
7272
use crate::SyntaxKind::*;
7373

74+
// if parser.peek_two() == (Some(UnsafeKw), Some(LBrace)) {
75+
// parser.parse(BlockExprScope::default(), None);
76+
// return;
77+
// } else {
78+
// println!("{:?}", parser.peek_two(),)
79+
// }
80+
7481
let mut checkpoint = attr::parse_attr_list(parser);
7582
let modifier_scope = ItemModifierScope::default();
7683
let modifier = match parser.current_kind() {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
unsafe { foo() }
2+
3+
unsafe {
4+
let a = 42
5+
std::evm::mstore(offset: 0, value: a)
6+
return
7+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
---
2+
source: crates/parser2/tests/syntax_node.rs
3+
expression: node
4+
input_file: crates/parser2/test_files/syntax_node/exprs/unsafe.fe
5+
---
6+
Root@0..97
7+
BlockExpr@0..16
8+
UnsafeKw@0..6 "unsafe"
9+
WhiteSpace@6..7 " "
10+
LBrace@7..8 "{"
11+
WhiteSpace@8..9 " "
12+
ExprStmt@9..14
13+
CallExpr@9..14
14+
PathExpr@9..12
15+
Path@9..12
16+
PathSegment@9..12
17+
Ident@9..12 "foo"
18+
CallArgList@12..14
19+
LParen@12..13 "("
20+
RParen@13..14 ")"
21+
WhiteSpace@14..15 " "
22+
RBrace@15..16 "}"
23+
Newline@16..18 "\n\n"
24+
BlockExpr@18..96
25+
UnsafeKw@18..24 "unsafe"
26+
WhiteSpace@24..25 " "
27+
LBrace@25..26 "{"
28+
Newline@26..27 "\n"
29+
WhiteSpace@27..31 " "
30+
LetStmt@31..41
31+
LetKw@31..34 "let"
32+
WhiteSpace@34..35 " "
33+
PathPat@35..36
34+
Path@35..36
35+
PathSegment@35..36
36+
Ident@35..36 "a"
37+
WhiteSpace@36..37 " "
38+
Eq@37..38 "="
39+
WhiteSpace@38..39 " "
40+
LitExpr@39..41
41+
Lit@39..41
42+
Int@39..41 "42"
43+
Newline@41..42 "\n"
44+
WhiteSpace@42..46 " "
45+
ExprStmt@46..83
46+
CallExpr@46..83
47+
PathExpr@46..62
48+
Path@46..62
49+
PathSegment@46..49
50+
Ident@46..49 "std"
51+
Colon2@49..51 "::"
52+
PathSegment@51..54
53+
Ident@51..54 "evm"
54+
Colon2@54..56 "::"
55+
PathSegment@56..62
56+
Ident@56..62 "mstore"
57+
CallArgList@62..83
58+
LParen@62..63 "("
59+
CallArg@63..72
60+
Ident@63..69 "offset"
61+
Colon@69..70 ":"
62+
WhiteSpace@70..71 " "
63+
LitExpr@71..72
64+
Lit@71..72
65+
Int@71..72 "0"
66+
Comma@72..73 ","
67+
WhiteSpace@73..74 " "
68+
CallArg@74..82
69+
Ident@74..79 "value"
70+
Colon@79..80 ":"
71+
WhiteSpace@80..81 " "
72+
PathExpr@81..82
73+
Path@81..82
74+
PathSegment@81..82
75+
Ident@81..82 "a"
76+
RParen@82..83 ")"
77+
Newline@83..84 "\n"
78+
WhiteSpace@84..88 " "
79+
ReturnStmt@88..94
80+
ReturnKw@88..94 "return"
81+
Newline@94..95 "\n"
82+
RBrace@95..96 "}"
83+
Newline@96..97 "\n"
84+

crates/parser2/test_files/syntax_node/items/func.fe

+23-1
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,26 @@ fn generics1<T: Trait, U>(t: T, u: Option<U>) -> T
1818
t
1919
}
2020

21-
fn decl<T, U>(t: MyStruct<T, U>) -> Result<T, Err> {}
21+
fn decl<T, U>(t: MyStruct<T, U>) -> Result<T, Err> {}
22+
23+
fn foo() {
24+
unsafe {
25+
bar()
26+
}
27+
}
28+
29+
fn foo2() {
30+
unsafe {
31+
bar2()
32+
}
33+
}
34+
35+
pub unsafe fn foo3() {
36+
unsafe
37+
38+
39+
{
40+
bar3()
41+
}
42+
}
43+

crates/parser2/test_files/syntax_node/items/func.snap

+117-3
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ source: crates/parser2/tests/syntax_node.rs
33
expression: node
44
input_file: crates/parser2/test_files/syntax_node/items/func.fe
55
---
6-
Root@0..361
7-
ItemList@0..361
6+
Root@0..532
7+
ItemList@0..532
88
Item@0..32
99
Func@0..30
1010
ItemModifier@0..3
@@ -282,7 +282,7 @@ [email protected]
282282
Newline@304..305 "\n"
283283
RBrace@305..306 "}"
284284
Newline@306..308 "\n\n"
285-
Item@308..361
285+
Item@308..363
286286
Func@308..361
287287
FnKw@308..310 "fn"
288288
WhiteSpace@310..311 " "
@@ -348,4 +348,118 @@ [email protected]
348348
BlockExpr@359..361
349349
LBrace@359..360 "{"
350350
RBrace@360..361 "}"
351+
Newline@361..363 "\n\n"
352+
Item@363..410
353+
Func@363..408
354+
FnKw@363..365 "fn"
355+
WhiteSpace@365..366 " "
356+
Ident@366..369 "foo"
357+
FuncParamList@369..371
358+
LParen@369..370 "("
359+
RParen@370..371 ")"
360+
WhiteSpace@371..372 " "
361+
BlockExpr@372..408
362+
LBrace@372..373 "{"
363+
Newline@373..374 "\n"
364+
WhiteSpace@374..378 " "
365+
ExprStmt@378..406
366+
BlockExpr@378..406
367+
UnsafeKw@378..384 "unsafe"
368+
WhiteSpace@384..385 " "
369+
LBrace@385..386 "{"
370+
Newline@386..387 "\n"
371+
WhiteSpace@387..395 " "
372+
ExprStmt@395..400
373+
CallExpr@395..400
374+
PathExpr@395..398
375+
Path@395..398
376+
PathSegment@395..398
377+
Ident@395..398 "bar"
378+
CallArgList@398..400
379+
LParen@398..399 "("
380+
RParen@399..400 ")"
381+
Newline@400..401 "\n"
382+
WhiteSpace@401..405 " "
383+
RBrace@405..406 "}"
384+
Newline@406..407 "\n"
385+
RBrace@407..408 "}"
386+
Newline@408..410 "\n\n"
387+
Item@410..462
388+
Func@410..460
389+
FnKw@410..412 "fn"
390+
WhiteSpace@412..413 " "
391+
Ident@413..417 "foo2"
392+
FuncParamList@417..419
393+
LParen@417..418 "("
394+
RParen@418..419 ")"
395+
WhiteSpace@419..420 " "
396+
BlockExpr@420..460
397+
LBrace@420..421 "{"
398+
Newline@421..422 "\n"
399+
WhiteSpace@422..426 " "
400+
ExprStmt@426..458
401+
BlockExpr@426..458
402+
UnsafeKw@426..432 "unsafe"
403+
WhiteSpace@432..436 " "
404+
LBrace@436..437 "{"
405+
Newline@437..438 "\n"
406+
WhiteSpace@438..446 " "
407+
ExprStmt@446..452
408+
CallExpr@446..452
409+
PathExpr@446..450
410+
Path@446..450
411+
PathSegment@446..450
412+
Ident@446..450 "bar2"
413+
CallArgList@450..452
414+
LParen@450..451 "("
415+
RParen@451..452 ")"
416+
Newline@452..453 "\n"
417+
WhiteSpace@453..457 " "
418+
RBrace@457..458 "}"
419+
Newline@458..459 "\n"
420+
RBrace@459..460 "}"
421+
Newline@460..462 "\n\n"
422+
Item@462..532
423+
Func@462..530
424+
ItemModifier@462..472
425+
PubKw@462..465 "pub"
426+
WhiteSpace@465..466 " "
427+
UnsafeKw@466..472 "unsafe"
428+
WhiteSpace@472..473 " "
429+
FnKw@473..475 "fn"
430+
WhiteSpace@475..476 " "
431+
Ident@476..480 "foo3"
432+
FuncParamList@480..482
433+
LParen@480..481 "("
434+
RParen@481..482 ")"
435+
WhiteSpace@482..483 " "
436+
BlockExpr@483..530
437+
LBrace@483..484 "{"
438+
Newline@484..485 "\n"
439+
WhiteSpace@485..489 " "
440+
ExprStmt@489..528
441+
BlockExpr@489..528
442+
UnsafeKw@489..495 "unsafe"
443+
Newline@495..496 "\n"
444+
WhiteSpace@496..500 " "
445+
Newline@500..502 "\n\n"
446+
WhiteSpace@502..506 " "
447+
LBrace@506..507 "{"
448+
Newline@507..508 "\n"
449+
WhiteSpace@508..516 " "
450+
ExprStmt@516..522
451+
CallExpr@516..522
452+
PathExpr@516..520
453+
Path@516..520
454+
PathSegment@516..520
455+
Ident@516..520 "bar3"
456+
CallArgList@520..522
457+
LParen@520..521 "("
458+
RParen@521..522 ")"
459+
Newline@522..523 "\n"
460+
WhiteSpace@523..527 " "
461+
RBrace@527..528 "}"
462+
Newline@528..529 "\n"
463+
RBrace@529..530 "}"
464+
Newline@530..532 "\n\n"
351465

0 commit comments

Comments
 (0)