| ... | @@ -532,11 +532,13 @@ const Parser = struct { | ... | @@ -532,11 +532,13 @@ const Parser = struct { |
| 532 | /// / KEYWORD_usingnamespace Expr SEMICOLON | 532 | /// / KEYWORD_usingnamespace Expr SEMICOLON |
| 533 | fn expectTopLevelDecl(p: *Parser) !Node.Index { | 533 | fn expectTopLevelDecl(p: *Parser) !Node.Index { |
| 534 | const extern_export_inline_token = p.nextToken(); | 534 | const extern_export_inline_token = p.nextToken(); |
| | 535 | var is_extern: bool = false; |
| 535 | var expect_fn: bool = false; | 536 | var expect_fn: bool = false; |
| 536 | var expect_var_or_fn: bool = false; | 537 | var expect_var_or_fn: bool = false; |
| 537 | switch (p.token_tags[extern_export_inline_token]) { | 538 | switch (p.token_tags[extern_export_inline_token]) { |
| 538 | .keyword_extern => { | 539 | .keyword_extern => { |
| 539 | _ = p.eatToken(.string_literal); | 540 | _ = p.eatToken(.string_literal); |
| | 541 | is_extern = true; |
| 540 | expect_var_or_fn = true; | 542 | expect_var_or_fn = true; |
| 541 | }, | 543 | }, |
| 542 | .keyword_export => expect_var_or_fn = true, | 544 | .keyword_export => expect_var_or_fn = true, |
| ... | @@ -554,6 +556,10 @@ const Parser = struct { | ... | @@ -554,6 +556,10 @@ const Parser = struct { |
| 554 | const fn_decl_index = try p.reserveNode(); | 556 | const fn_decl_index = try p.reserveNode(); |
| 555 | const body_block = try p.parseBlock(); | 557 | const body_block = try p.parseBlock(); |
| 556 | assert(body_block != 0); | 558 | assert(body_block != 0); |
| | 559 | if (is_extern) { |
| | 560 | try p.warnMsg(.{ .tag = .extern_fn_body, .token = extern_export_inline_token }); |
| | 561 | return null_node; |
| | 562 | } |
| 557 | return p.setNode(fn_decl_index, .{ | 563 | return p.setNode(fn_decl_index, .{ |
| 558 | .tag = .fn_decl, | 564 | .tag = .fn_decl, |
| 559 | .main_token = p.nodes.items(.main_token)[fn_proto], | 565 | .main_token = p.nodes.items(.main_token)[fn_proto], |