Commit b78c91951a

Andrew Kelley <superjoe30@gmail.com>
2017-02-02 19:23:18
remove ability to mark if and switch as inline
if and switch are implicitly inline if the condition/target expression is known at compile time. instead of: ``` inline if (condition) ... inline switch (target) ... ``` one can use: ``` if (comptime condition) ... switch (comptime target) ... ```
1 parent cd08c1f
doc/langref.md
@@ -73,7 +73,7 @@ BlockExpression = IfExpression | Block | WhileExpression | ForExpression | Switc
 
 CompTimeExpression = option("comptime") Expression
 
-SwitchExpression = option("inline") "switch" "(" Expression ")" "{" many(SwitchProng) "}"
+SwitchExpression = "switch" "(" Expression ")" "{" many(SwitchProng) "}"
 
 SwitchProng = (list(SwitchItem, ",") | "else") "=>" option("|" option("*") Symbol "|") Expression ","
 
@@ -91,9 +91,9 @@ Defer = option("%" | "?") "defer" Expression
 
 IfExpression = IfVarExpression | IfBoolExpression
 
-IfBoolExpression = option("inline") "if" "(" Expression ")" Expression option(Else)
+IfBoolExpression = "if" "(" Expression ")" Expression option(Else)
 
-IfVarExpression = option("inline") "if" "(" ("const" | "var") option("*") Symbol option(":" TypeExpr) "?=" Expression ")" Expression Option(Else)
+IfVarExpression = "if" "(" ("const" | "var") option("*") Symbol option(":" TypeExpr) "?=" Expression ")" Expression Option(Else)
 
 Else = "else" Expression
 
src/all_types.hpp
@@ -509,7 +509,6 @@ struct AstNodeIfBoolExpr {
     AstNode *condition;
     AstNode *then_block;
     AstNode *else_node; // null, block node, or other if expr node
-    bool is_inline;
 };
 
 struct AstNodeIfVarExpr {
@@ -517,7 +516,6 @@ struct AstNodeIfVarExpr {
     AstNode *then_block;
     AstNode *else_node; // null, block node, or other if expr node
     bool var_is_ptr;
-    bool is_inline;
 };
 
 struct AstNodeWhileExpr {
@@ -539,7 +537,6 @@ struct AstNodeForExpr {
 struct AstNodeSwitchExpr {
     AstNode *expr;
     ZigList<AstNode *> prongs;
-    bool is_inline;
 };
 
 struct AstNodeSwitchProng {
@@ -677,11 +674,9 @@ struct AstNodeBoolLiteral {
 };
 
 struct AstNodeBreakExpr {
-    bool is_inline; // TODO
 };
 
 struct AstNodeContinueExpr {
-    bool is_inline; // TODO
 };
 
 struct AstNodeArrayType {
src/ast_render.cpp
@@ -844,14 +844,12 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
             }
         case NodeTypeBreak:
             {
-                const char *inline_str = node->data.break_expr.is_inline ? "inline " : "";
-                fprintf(ar->f, "%sbreak", inline_str);
+                fprintf(ar->f, "break");
                 break;
             }
         case NodeTypeContinue:
             {
-                const char *inline_str = node->data.continue_expr.is_inline ? "inline " : "";
-                fprintf(ar->f, "%scontinue", inline_str);
+                fprintf(ar->f, "continue");
                 break;
             }
         case NodeTypeSliceExpr:
src/ir.cpp
@@ -4148,7 +4148,7 @@ static IrInstruction *ir_gen_if_bool_expr(IrBuilder *irb, Scope *scope, AstNode
         return condition;
 
     IrInstruction *is_comptime;
-    if (ir_should_inline(irb->exec, scope) || node->data.if_bool_expr.is_inline) {
+    if (ir_should_inline(irb->exec, scope)) {
         is_comptime = ir_build_const_bool(irb, scope, node, true);
     } else {
         is_comptime = ir_build_test_comptime(irb, scope, node, condition);
@@ -4695,7 +4695,7 @@ static IrInstruction *ir_gen_if_var_expr(IrBuilder *irb, Scope *scope, AstNode *
     IrBasicBlock *endif_block = ir_build_basic_block(irb, scope, "MaybeEndIf");
 
     IrInstruction *is_comptime;
-    if (ir_should_inline(irb->exec, scope) || node->data.if_var_expr.is_inline) {
+    if (ir_should_inline(irb->exec, scope)) {
         is_comptime = ir_build_const_bool(irb, scope, node, true);
     } else {
         is_comptime = ir_build_test_comptime(irb, scope, node, is_non_null);
@@ -4807,7 +4807,7 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode *
     ZigList<IrInstructionSwitchBrCase> cases = {0};
 
     IrInstruction *is_comptime;
-    if (ir_should_inline(irb->exec, scope) || node->data.switch_expr.is_inline) {
+    if (ir_should_inline(irb->exec, scope)) {
         is_comptime = ir_build_const_bool(irb, scope, node, true);
     } else {
         is_comptime = ir_build_test_comptime(irb, scope, node, target_value);
@@ -5002,7 +5002,7 @@ static IrInstruction *ir_gen_break(IrBuilder *irb, Scope *scope, AstNode *node)
     LoopStackItem *loop_stack_item = &irb->loop_stack.last();
 
     IrInstruction *is_comptime;
-    if (ir_should_inline(irb->exec, scope) || node->data.break_expr.is_inline) {
+    if (ir_should_inline(irb->exec, scope)) {
         is_comptime = ir_build_const_bool(irb, scope, node, true);
     } else {
         is_comptime = loop_stack_item->is_comptime;
@@ -5025,7 +5025,7 @@ static IrInstruction *ir_gen_continue(IrBuilder *irb, Scope *scope, AstNode *nod
     LoopStackItem *loop_stack_item = &irb->loop_stack.last();
 
     IrInstruction *is_comptime;
-    if (ir_should_inline(irb->exec, scope) || node->data.continue_expr.is_inline) {
+    if (ir_should_inline(irb->exec, scope)) {
         is_comptime = ir_build_const_bool(irb, scope, node, true);
     } else {
         is_comptime = loop_stack_item->is_comptime;
src/parser.cpp
@@ -1313,30 +1313,17 @@ static AstNode *ast_parse_else(ParseContext *pc, size_t *token_index, bool manda
 
 /*
 IfExpression : IfVarExpression | IfBoolExpression
-IfBoolExpression = option("inline") "if" "(" Expression ")" Expression option(Else)
-IfVarExpression = option("inline") "if" "(" ("const" | "var") option("*") Symbol option(":" TypeExpr) "?=" Expression ")" Expression Option(Else)
+IfBoolExpression = "if" "(" Expression ")" Expression option(Else)
+IfVarExpression = "if" "(" ("const" | "var") option("*") Symbol option(":" TypeExpr) "?=" Expression ")" Expression Option(Else)
 */
 static AstNode *ast_parse_if_expr(ParseContext *pc, size_t *token_index, bool mandatory) {
-    Token *first_token = &pc->tokens->at(*token_index);
-    Token *if_tok;
+    Token *if_token = &pc->tokens->at(*token_index);
 
-    bool is_inline;
-    if (first_token->id == TokenIdKeywordInline) {
-        if_tok = &pc->tokens->at(*token_index + 1);
-        if (if_tok->id == TokenIdKeywordIf) {
-            is_inline = true;
-            *token_index += 2;
-        } else if (mandatory) {
-            ast_expect_token(pc, if_tok, TokenIdKeywordIf);
-        } else {
-            return nullptr;
-        }
-    } else if (first_token->id == TokenIdKeywordIf) {
-        if_tok = first_token;
-        is_inline = false;
+    if (if_token->id == TokenIdKeywordIf) {
         *token_index += 1;
     } else if (mandatory) {
-        ast_expect_token(pc, first_token, TokenIdKeywordIf);
+        ast_expect_token(pc, if_token, TokenIdKeywordIf);
+        zig_unreachable();
     } else {
         return nullptr;
     }
@@ -1345,8 +1332,7 @@ static AstNode *ast_parse_if_expr(ParseContext *pc, size_t *token_index, bool ma
 
     Token *token = &pc->tokens->at(*token_index);
     if (token->id == TokenIdKeywordConst || token->id == TokenIdKeywordVar) {
-        AstNode *node = ast_create_node(pc, NodeTypeIfVarExpr, if_tok);
-        node->data.if_var_expr.is_inline = is_inline;
+        AstNode *node = ast_create_node(pc, NodeTypeIfVarExpr, if_token);
         node->data.if_var_expr.var_decl.is_const = (token->id == TokenIdKeywordConst);
         *token_index += 1;
 
@@ -1383,8 +1369,7 @@ static AstNode *ast_parse_if_expr(ParseContext *pc, size_t *token_index, bool ma
 
         return node;
     } else {
-        AstNode *node = ast_create_node(pc, NodeTypeIfBoolExpr, if_tok);
-        node->data.if_bool_expr.is_inline = is_inline;
+        AstNode *node = ast_create_node(pc, NodeTypeIfBoolExpr, if_token);
         node->data.if_bool_expr.condition = ast_parse_expression(pc, token_index, true);
         ast_eat_token(pc, token_index, TokenIdRParen);
         node->data.if_bool_expr.then_block = ast_parse_expression(pc, token_index, true);
@@ -1700,38 +1685,22 @@ static AstNode *ast_parse_for_expr(ParseContext *pc, size_t *token_index, bool m
 }
 
 /*
-SwitchExpression = option("inline") "switch" "(" Expression ")" "{" many(SwitchProng) "}"
+SwitchExpression = "switch" "(" Expression ")" "{" many(SwitchProng) "}"
 SwitchProng = (list(SwitchItem, ",") | "else") "=>" option("|" option("*") Symbol "|") Expression ","
 SwitchItem : Expression | (Expression "..." Expression)
 */
 static AstNode *ast_parse_switch_expr(ParseContext *pc, size_t *token_index, bool mandatory) {
-    Token *first_token = &pc->tokens->at(*token_index);
-    Token *switch_token;
-    bool is_inline;
-    if (first_token->id == TokenIdKeywordInline) {
-        is_inline = true;
-        switch_token = &pc->tokens->at(*token_index + 1);
-        if (switch_token->id == TokenIdKeywordSwitch) {
-            *token_index += 2;
-        } else if (mandatory) {
-            ast_expect_token(pc, first_token, TokenIdKeywordSwitch);
-            zig_unreachable();
-        } else {
-            return nullptr;
-        }
-    } else if (first_token->id == TokenIdKeywordSwitch) {
-        is_inline = false;
-        switch_token = first_token;
+    Token *switch_token = &pc->tokens->at(*token_index);
+    if (switch_token->id == TokenIdKeywordSwitch) {
         *token_index += 1;
     } else if (mandatory) {
-        ast_expect_token(pc, first_token, TokenIdKeywordSwitch);
+        ast_expect_token(pc, switch_token, TokenIdKeywordSwitch);
         zig_unreachable();
     } else {
         return nullptr;
     }
 
     AstNode *node = ast_create_node(pc, NodeTypeSwitchExpr, switch_token);
-    node->data.switch_expr.is_inline = is_inline;
 
     ast_eat_token(pc, token_index, TokenIdLParen);
     node->data.switch_expr.expr = ast_parse_expression(pc, token_index, true);
std/io.zig
@@ -150,7 +150,7 @@ pub const OutStream = struct {
                 @compileError("Incomplete format string: " ++ format);
             }
         }
-        inline if (start_index < format.len) {
+        if (start_index < format.len) {
             %return self.write(format[start_index...format.len]);
         }
         %return self.flush();
test/cases/switch.zig
@@ -33,18 +33,21 @@ fn testSwitchWithAllRanges(x: u32, y: u32) -> u32 {
     }
 }
 
-fn inlineSwitch() {
+fn implicitComptimeSwitch() {
     @setFnTest(this);
 
     const x = 3 + 4;
-    const result = inline switch (x) {
+    const result = switch (x) {
         3 => 10,
         4 => 11,
         5, 6 => 12,
         7, 8 => 13,
         else => 14,
     };
-    assert(result + 1 == 14);
+
+    comptime {
+        assert(result + 1 == 14);
+    }
 }
 
 fn switchOnEnum() {