Commit c06a61e9bf

Andrew Kelley <superjoe30@gmail.com>
2018-09-13 22:34:33
remove `this`. add `@This()`.
closes #1283
1 parent 7c3636a
doc/langref.html.in
@@ -478,13 +478,9 @@ pub fn main() void {
           <td><code>undefined</code></td>
           <td>used to leave a value unspecified</td>
         </tr>
-        <tr>
-          <td><code>this</code></td>
-          <td>refers to the thing in immediate scope</td>
-        </tr>
       </table>
       </div>
-      {#see_also|Optionals|this#}
+      {#see_also|Optionals#}
       {#header_close#}
       {#header_open|String Literals#}
       {#code_begin|test#}
@@ -4186,11 +4182,6 @@ fn foo() void {}
       {#code_end#}
       {#header_close#}
 
-      {#header_open|this#}
-      <p>TODO: example of this referring to Self struct</p>
-      <p>TODO: example of this referring to recursion function</p>
-      <p>TODO: example of this referring to basic block for @setRuntimeSafety</p>
-      {#header_close#}
       {#header_open|comptime#}
       <p>
       Zig places importance on the concept of whether an expression is known at compile-time.
@@ -7744,7 +7735,7 @@ ArrayType : "[" option(Expression) "]" option("align" "(" Expression option(":"
 
 GroupedExpression = "(" Expression ")"
 
-KeywordLiteral = "true" | "false" | "null" | "undefined" | "error" | "this" | "unreachable" | "suspend"
+KeywordLiteral = "true" | "false" | "null" | "undefined" | "error" | "unreachable" | "suspend"
 
 ErrorSetDecl = "error" "{" list(Symbol, ",") "}"
 
src/all_types.hpp
@@ -283,7 +283,6 @@ struct ConstExprValue {
         ConstArrayValue x_array;
         ConstPtrValue x_ptr;
         ImportTableEntry *x_import;
-        Scope *x_block;
         ConstArgTuple x_arg_tuple;
 
         // populated if special == ConstValSpecialRuntime
@@ -413,7 +412,6 @@ enum NodeType {
     NodeTypeBoolLiteral,
     NodeTypeNullLiteral,
     NodeTypeUndefinedLiteral,
-    NodeTypeThisLiteral,
     NodeTypeUnreachable,
     NodeTypeIfBoolExpr,
     NodeTypeWhileExpr,
@@ -1205,7 +1203,6 @@ enum ZigTypeId {
     ZigTypeIdUnion,
     ZigTypeIdFn,
     ZigTypeIdNamespace,
-    ZigTypeIdBlock,
     ZigTypeIdBoundFn,
     ZigTypeIdArgTuple,
     ZigTypeIdOpaque,
@@ -1413,6 +1410,7 @@ enum BuiltinFnId {
     BuiltinFnIdSetEvalBranchQuota,
     BuiltinFnIdAlignCast,
     BuiltinFnIdOpaqueType,
+    BuiltinFnIdThis,
     BuiltinFnIdSetAlignStack,
     BuiltinFnIdArgType,
     BuiltinFnIdExport,
src/analyze.cpp
@@ -246,7 +246,6 @@ AstNode *type_decl_node(ZigType *type_entry) {
         case ZigTypeIdErrorSet:
         case ZigTypeIdFn:
         case ZigTypeIdNamespace:
-        case ZigTypeIdBlock:
         case ZigTypeIdBoundFn:
         case ZigTypeIdArgTuple:
         case ZigTypeIdPromise:
@@ -284,7 +283,6 @@ bool type_is_complete(ZigType *type_entry) {
         case ZigTypeIdErrorSet:
         case ZigTypeIdFn:
         case ZigTypeIdNamespace:
-        case ZigTypeIdBlock:
         case ZigTypeIdBoundFn:
         case ZigTypeIdArgTuple:
         case ZigTypeIdPromise:
@@ -320,7 +318,6 @@ bool type_has_zero_bits_known(ZigType *type_entry) {
         case ZigTypeIdErrorSet:
         case ZigTypeIdFn:
         case ZigTypeIdNamespace:
-        case ZigTypeIdBlock:
         case ZigTypeIdBoundFn:
         case ZigTypeIdArgTuple:
         case ZigTypeIdOpaque:
@@ -1414,7 +1411,6 @@ static bool type_allowed_in_packed_struct(ZigType *type_entry) {
         case ZigTypeIdErrorUnion:
         case ZigTypeIdErrorSet:
         case ZigTypeIdNamespace:
-        case ZigTypeIdBlock:
         case ZigTypeIdBoundFn:
         case ZigTypeIdArgTuple:
         case ZigTypeIdOpaque:
@@ -1455,7 +1451,6 @@ static bool type_allowed_in_extern(CodeGen *g, ZigType *type_entry) {
         case ZigTypeIdErrorUnion:
         case ZigTypeIdErrorSet:
         case ZigTypeIdNamespace:
-        case ZigTypeIdBlock:
         case ZigTypeIdBoundFn:
         case ZigTypeIdArgTuple:
         case ZigTypeIdPromise:
@@ -1613,7 +1608,6 @@ static ZigType *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *child_sc
             case ZigTypeIdComptimeFloat:
             case ZigTypeIdComptimeInt:
             case ZigTypeIdNamespace:
-            case ZigTypeIdBlock:
             case ZigTypeIdBoundFn:
             case ZigTypeIdMetaType:
             case ZigTypeIdVoid:
@@ -1703,7 +1697,6 @@ static ZigType *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *child_sc
         case ZigTypeIdComptimeFloat:
         case ZigTypeIdComptimeInt:
         case ZigTypeIdNamespace:
-        case ZigTypeIdBlock:
         case ZigTypeIdBoundFn:
         case ZigTypeIdMetaType:
         case ZigTypeIdUnreachable:
@@ -3437,7 +3430,6 @@ void scan_decls(CodeGen *g, ScopeDecls *decls_scope, AstNode *node) {
         case NodeTypeBoolLiteral:
         case NodeTypeNullLiteral:
         case NodeTypeUndefinedLiteral:
-        case NodeTypeThisLiteral:
         case NodeTypeSymbol:
         case NodeTypePrefixOpExpr:
         case NodeTypePointerType:
@@ -3497,7 +3489,6 @@ ZigType *validate_var_type(CodeGen *g, AstNode *source_node, ZigType *type_entry
         case ZigTypeIdUnreachable:
         case ZigTypeIdUndefined:
         case ZigTypeIdNull:
-        case ZigTypeIdBlock:
         case ZigTypeIdArgTuple:
         case ZigTypeIdOpaque:
             add_node_error(g, source_node, buf_sprintf("variable of type '%s' not allowed",
@@ -3798,34 +3789,6 @@ ZigFn *scope_fn_entry(Scope *scope) {
     return nullptr;
 }
 
-ZigFn *scope_get_fn_if_root(Scope *scope) {
-    assert(scope);
-    scope = scope->parent;
-    while (scope) {
-        switch (scope->id) {
-            case ScopeIdBlock:
-                return nullptr;
-            case ScopeIdDecls:
-            case ScopeIdDefer:
-            case ScopeIdDeferExpr:
-            case ScopeIdVarDecl:
-            case ScopeIdCImport:
-            case ScopeIdLoop:
-            case ScopeIdSuspend:
-            case ScopeIdCompTime:
-            case ScopeIdCoroPrelude:
-            case ScopeIdRuntime:
-                scope = scope->parent;
-                continue;
-            case ScopeIdFnDef:
-                ScopeFnDef *fn_scope = (ScopeFnDef *)scope;
-                return fn_scope->fn_entry;
-        }
-        zig_unreachable();
-    }
-    return nullptr;
-}
-
 TypeEnumField *find_enum_type_field(ZigType *enum_type, Buf *name) {
     assert(enum_type->id == ZigTypeIdEnum);
     if (enum_type->data.enumeration.src_field_count == 0)
@@ -3907,7 +3870,6 @@ static bool is_container(ZigType *type_entry) {
         case ZigTypeIdErrorSet:
         case ZigTypeIdFn:
         case ZigTypeIdNamespace:
-        case ZigTypeIdBlock:
         case ZigTypeIdBoundFn:
         case ZigTypeIdArgTuple:
         case ZigTypeIdOpaque:
@@ -3966,7 +3928,6 @@ void resolve_container_type(CodeGen *g, ZigType *type_entry) {
         case ZigTypeIdErrorSet:
         case ZigTypeIdFn:
         case ZigTypeIdNamespace:
-        case ZigTypeIdBlock:
         case ZigTypeIdBoundFn:
         case ZigTypeIdInvalid:
         case ZigTypeIdArgTuple:
@@ -4427,7 +4388,6 @@ bool handle_is_ptr(ZigType *type_entry) {
         case ZigTypeIdUndefined:
         case ZigTypeIdNull:
         case ZigTypeIdNamespace:
-        case ZigTypeIdBlock:
         case ZigTypeIdBoundFn:
         case ZigTypeIdArgTuple:
         case ZigTypeIdOpaque:
@@ -4842,8 +4802,6 @@ static uint32_t hash_const_val(ConstExprValue *const_val) {
             return const_val->data.x_err_set->value ^ 2630160122;
         case ZigTypeIdNamespace:
             return hash_ptr(const_val->data.x_import);
-        case ZigTypeIdBlock:
-            return hash_ptr(const_val->data.x_block);
         case ZigTypeIdBoundFn:
         case ZigTypeIdInvalid:
         case ZigTypeIdUnreachable:
@@ -4904,7 +4862,6 @@ static bool can_mutate_comptime_var_state(ConstExprValue *value) {
         case ZigTypeIdNamespace:
         case ZigTypeIdBoundFn:
         case ZigTypeIdFn:
-        case ZigTypeIdBlock:
         case ZigTypeIdOpaque:
         case ZigTypeIdPromise:
         case ZigTypeIdErrorSet:
@@ -4971,7 +4928,6 @@ static bool return_type_is_cacheable(ZigType *return_type) {
         case ZigTypeIdNamespace:
         case ZigTypeIdBoundFn:
         case ZigTypeIdFn:
-        case ZigTypeIdBlock:
         case ZigTypeIdOpaque:
         case ZigTypeIdPromise:
         case ZigTypeIdErrorSet:
@@ -5083,7 +5039,6 @@ bool type_requires_comptime(ZigType *type_entry) {
         case ZigTypeIdNull:
         case ZigTypeIdMetaType:
         case ZigTypeIdNamespace:
-        case ZigTypeIdBlock:
         case ZigTypeIdBoundFn:
         case ZigTypeIdArgTuple:
             return true;
@@ -5615,8 +5570,6 @@ bool const_values_equal(ConstExprValue *a, ConstExprValue *b) {
             zig_panic("TODO");
         case ZigTypeIdNamespace:
             return a->data.x_import == b->data.x_import;
-        case ZigTypeIdBlock:
-            return a->data.x_block == b->data.x_block;
         case ZigTypeIdArgTuple:
             return a->data.x_arg_tuple.start_index == b->data.x_arg_tuple.start_index &&
                    a->data.x_arg_tuple.end_index == b->data.x_arg_tuple.end_index;
@@ -5795,12 +5748,6 @@ void render_const_value(CodeGen *g, Buf *buf, ConstExprValue *const_val) {
             }
         case ZigTypeIdPointer:
             return render_const_val_ptr(g, buf, const_val, type_entry);
-        case ZigTypeIdBlock:
-            {
-                AstNode *node = const_val->data.x_block->source_node;
-                buf_appendf(buf, "(scope:%" ZIG_PRI_usize ":%" ZIG_PRI_usize ")", node->line + 1, node->column + 1);
-                return;
-            }
         case ZigTypeIdArray:
             {
                 ZigType *child_type = type_entry->data.array.child_type;
@@ -5980,7 +5927,6 @@ uint32_t type_id_hash(TypeId x) {
         case ZigTypeIdUnion:
         case ZigTypeIdFn:
         case ZigTypeIdNamespace:
-        case ZigTypeIdBlock:
         case ZigTypeIdBoundFn:
         case ZigTypeIdArgTuple:
         case ZigTypeIdPromise:
@@ -6027,7 +5973,6 @@ bool type_id_eql(TypeId a, TypeId b) {
         case ZigTypeIdUnion:
         case ZigTypeIdFn:
         case ZigTypeIdNamespace:
-        case ZigTypeIdBlock:
         case ZigTypeIdBoundFn:
         case ZigTypeIdArgTuple:
         case ZigTypeIdOpaque:
@@ -6153,7 +6098,6 @@ static const ZigTypeId all_type_ids[] = {
     ZigTypeIdUnion,
     ZigTypeIdFn,
     ZigTypeIdNamespace,
-    ZigTypeIdBlock,
     ZigTypeIdBoundFn,
     ZigTypeIdArgTuple,
     ZigTypeIdOpaque,
@@ -6215,16 +6159,14 @@ size_t type_id_index(ZigType *entry) {
             return 18;
         case ZigTypeIdNamespace:
             return 19;
-        case ZigTypeIdBlock:
-            return 20;
         case ZigTypeIdBoundFn:
-            return 21;
+            return 20;
         case ZigTypeIdArgTuple:
-            return 22;
+            return 21;
         case ZigTypeIdOpaque:
-            return 23;
+            return 22;
         case ZigTypeIdPromise:
-            return 24;
+            return 23;
     }
     zig_unreachable();
 }
@@ -6273,8 +6215,6 @@ const char *type_id_name(ZigTypeId id) {
             return "Fn";
         case ZigTypeIdNamespace:
             return "Namespace";
-        case ZigTypeIdBlock:
-            return "Block";
         case ZigTypeIdBoundFn:
             return "BoundFn";
         case ZigTypeIdArgTuple:
src/analyze.hpp
@@ -87,7 +87,6 @@ ZigFn *create_fn(AstNode *proto_node);
 ZigFn *create_fn_raw(FnInline inline_value, GlobalLinkageId linkage);
 void init_fn_type_id(FnTypeId *fn_type_id, AstNode *proto_node, size_t param_count_alloc);
 AstNode *get_param_decl_node(ZigFn *fn_entry, size_t index);
-ZigFn *scope_get_fn_if_root(Scope *scope);
 bool type_requires_comptime(ZigType *type_entry);
 Error ATTRIBUTE_MUST_USE ensure_complete_type(CodeGen *g, ZigType *type_entry);
 Error ATTRIBUTE_MUST_USE type_ensure_zero_bits_known(CodeGen *g, ZigType *type_entry);
src/ast_render.cpp
@@ -193,8 +193,6 @@ static const char *node_type_str(NodeType node_type) {
             return "NullLiteral";
         case NodeTypeUndefinedLiteral:
             return "UndefinedLiteral";
-        case NodeTypeThisLiteral:
-            return "ThisLiteral";
         case NodeTypeIfBoolExpr:
             return "IfBoolExpr";
         case NodeTypeWhileExpr:
@@ -897,11 +895,6 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
                 }
                 break;
             }
-        case NodeTypeThisLiteral:
-            {
-                fprintf(ar->f, "this");
-                break;
-            }
         case NodeTypeBoolLiteral:
             {
                 const char *bool_str = node->data.bool_literal.value ? "true" : "false";
src/codegen.cpp
@@ -5479,7 +5479,6 @@ static LLVMValueRef pack_const_int(CodeGen *g, LLVMTypeRef big_int_type_ref, Con
         case ZigTypeIdErrorUnion:
         case ZigTypeIdErrorSet:
         case ZigTypeIdNamespace:
-        case ZigTypeIdBlock:
         case ZigTypeIdBoundFn:
         case ZigTypeIdArgTuple:
         case ZigTypeIdVoid:
@@ -5954,7 +5953,6 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val, const c
         case ZigTypeIdUndefined:
         case ZigTypeIdNull:
         case ZigTypeIdNamespace:
-        case ZigTypeIdBlock:
         case ZigTypeIdBoundFn:
         case ZigTypeIdArgTuple:
         case ZigTypeIdOpaque:
@@ -6477,12 +6475,6 @@ static void define_builtin_types(CodeGen *g) {
         entry->zero_bits = true;
         g->builtin_types.entry_namespace = entry;
     }
-    {
-        ZigType *entry = new_type_table_entry(ZigTypeIdBlock);
-        buf_init_from_str(&entry->name, "(block)");
-        entry->zero_bits = true;
-        g->builtin_types.entry_block = entry;
-    }
     {
         ZigType *entry = new_type_table_entry(ZigTypeIdComptimeFloat);
         buf_init_from_str(&entry->name, "comptime_float");
@@ -6763,6 +6755,7 @@ static void define_builtin_fns(CodeGen *g) {
     create_builtin_fn(g, BuiltinFnIdErrSetCast, "errSetCast", 2);
     create_builtin_fn(g, BuiltinFnIdToBytes, "sliceToBytes", 1);
     create_builtin_fn(g, BuiltinFnIdFromBytes, "bytesToSlice", 2);
+    create_builtin_fn(g, BuiltinFnIdThis, "This", 0);
 }
 
 static const char *bool_to_str(bool b) {
@@ -6944,7 +6937,6 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
             "    Union: Union,\n"
             "    Fn: Fn,\n"
             "    Namespace: void,\n"
-            "    Block: void,\n"
             "    BoundFn: Fn,\n"
             "    ArgTuple: void,\n"
             "    Opaque: void,\n"
@@ -7589,7 +7581,6 @@ static void prepend_c_type_to_decl_list(CodeGen *g, GenH *gen_h, ZigType *type_e
         case ZigTypeIdUndefined:
         case ZigTypeIdNull:
         case ZigTypeIdNamespace:
-        case ZigTypeIdBlock:
         case ZigTypeIdBoundFn:
         case ZigTypeIdArgTuple:
         case ZigTypeIdErrorUnion:
@@ -7768,7 +7759,6 @@ static void get_c_type(CodeGen *g, GenH *gen_h, ZigType *type_entry, Buf *out_bu
         case ZigTypeIdMetaType:
         case ZigTypeIdBoundFn:
         case ZigTypeIdNamespace:
-        case ZigTypeIdBlock:
         case ZigTypeIdComptimeFloat:
         case ZigTypeIdComptimeInt:
         case ZigTypeIdUndefined:
@@ -7921,7 +7911,6 @@ static void gen_h_file(CodeGen *g) {
             case ZigTypeIdErrorUnion:
             case ZigTypeIdErrorSet:
             case ZigTypeIdNamespace:
-            case ZigTypeIdBlock:
             case ZigTypeIdBoundFn:
             case ZigTypeIdArgTuple:
             case ZigTypeIdOptional:
src/ir.cpp
@@ -1029,12 +1029,6 @@ static IrInstruction *ir_create_const_fn(IrBuilder *irb, Scope *scope, AstNode *
     return &const_instruction->base;
 }
 
-static IrInstruction *ir_build_const_fn(IrBuilder *irb, Scope *scope, AstNode *source_node, ZigFn *fn_entry) {
-    IrInstruction *instruction = ir_create_const_fn(irb, scope, source_node, fn_entry);
-    ir_instruction_append(irb->current_basic_block, instruction);
-    return instruction;
-}
-
 static IrInstruction *ir_build_const_import(IrBuilder *irb, Scope *scope, AstNode *source_node, ImportTableEntry *import) {
     IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, source_node);
     const_instruction->base.value.type = irb->codegen->builtin_types.entry_namespace;
@@ -1043,16 +1037,6 @@ static IrInstruction *ir_build_const_import(IrBuilder *irb, Scope *scope, AstNod
     return &const_instruction->base;
 }
 
-static IrInstruction *ir_build_const_scope(IrBuilder *irb, Scope *parent_scope, AstNode *source_node,
-        Scope *target_scope)
-{
-    IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, parent_scope, source_node);
-    const_instruction->base.value.type = irb->codegen->builtin_types.entry_block;
-    const_instruction->base.value.special = ConstValSpecialStatic;
-    const_instruction->base.value.data.x_block = target_scope;
-    return &const_instruction->base;
-}
-
 static IrInstruction *ir_build_const_bool(IrBuilder *irb, Scope *scope, AstNode *source_node, bool value) {
     IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, source_node);
     const_instruction->base.value.type = irb->codegen->builtin_types.entry_bool;
@@ -3892,6 +3876,21 @@ static IrInstruction *ir_gen_overflow_op(IrBuilder *irb, Scope *scope, AstNode *
     return ir_build_overflow_op(irb, scope, node, op, type_value, op1, op2, result_ptr, nullptr);
 }
 
+static IrInstruction *ir_gen_this(IrBuilder *irb, Scope *orig_scope, AstNode *node) {
+    for (Scope *it_scope = orig_scope; it_scope != nullptr; it_scope = it_scope->parent) {
+        if (it_scope->id == ScopeIdDecls) {
+            ScopeDecls *decls_scope = (ScopeDecls *)it_scope;
+            ZigType *container_type = decls_scope->container_type;
+            if (container_type != nullptr) {
+                return ir_build_const_type(irb, orig_scope, node, container_type);
+            } else {
+                return ir_build_const_import(irb, orig_scope, node, decls_scope->import);
+            }
+        }
+    }
+    zig_unreachable();
+}
+
 static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval) {
     assert(node->type == NodeTypeFnCallExpr);
 
@@ -4830,6 +4829,11 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
                 IrInstruction *opaque_type = ir_build_opaque_type(irb, scope, node);
                 return ir_lval_wrap(irb, scope, opaque_type, lval);
             }
+        case BuiltinFnIdThis:
+            {
+                IrInstruction *this_inst = ir_gen_this(irb, scope, node);
+                return ir_lval_wrap(irb, scope, this_inst, lval);
+            }
         case BuiltinFnIdSetAlignStack:
             {
                 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
@@ -5681,33 +5685,6 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo
     return ir_build_phi(irb, parent_scope, node, incoming_blocks.length, incoming_blocks.items, incoming_values.items);
 }
 
-static IrInstruction *ir_gen_this_literal(IrBuilder *irb, Scope *scope, AstNode *node) {
-    assert(node->type == NodeTypeThisLiteral);
-
-    if (!scope->parent)
-        return ir_build_const_import(irb, scope, node, node->owner);
-
-    ZigFn *fn_entry = scope_get_fn_if_root(scope);
-    if (fn_entry)
-        return ir_build_const_fn(irb, scope, node, fn_entry);
-
-    while (scope->id != ScopeIdBlock && scope->id != ScopeIdDecls) {
-        scope = scope->parent;
-    }
-
-    if (scope->id == ScopeIdDecls) {
-        ScopeDecls *decls_scope = (ScopeDecls *)scope;
-        ZigType *container_type = decls_scope->container_type;
-        assert(container_type);
-        return ir_build_const_type(irb, scope, node, container_type);
-    }
-
-    if (scope->id == ScopeIdBlock)
-        return ir_build_const_scope(irb, scope, node, scope);
-
-    zig_unreachable();
-}
-
 static IrInstruction *ir_gen_bool_literal(IrBuilder *irb, Scope *scope, AstNode *node) {
     assert(node->type == NodeTypeBoolLiteral);
     return ir_build_const_bool(irb, scope, node, node->data.bool_literal.value);
@@ -7285,8 +7262,6 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop
 
             return ir_build_load_ptr(irb, scope, node, unwrapped_ptr);
         }
-        case NodeTypeThisLiteral:
-            return ir_lval_wrap(irb, scope, ir_gen_this_literal(irb, scope, node), lval);
         case NodeTypeBoolLiteral:
             return ir_lval_wrap(irb, scope, ir_gen_bool_literal(irb, scope, node), lval);
         case NodeTypeArrayType:
@@ -11621,7 +11596,6 @@ static ZigType *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp *bin_op
         case ZigTypeIdFn:
         case ZigTypeIdOpaque:
         case ZigTypeIdNamespace:
-        case ZigTypeIdBlock:
         case ZigTypeIdBoundFn:
         case ZigTypeIdArgTuple:
         case ZigTypeIdPromise:
@@ -12822,7 +12796,6 @@ static ZigType *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructionExpor
                 case ZigTypeIdErrorUnion:
                 case ZigTypeIdErrorSet:
                 case ZigTypeIdNamespace:
-                case ZigTypeIdBlock:
                 case ZigTypeIdBoundFn:
                 case ZigTypeIdArgTuple:
                 case ZigTypeIdOpaque:
@@ -12847,7 +12820,6 @@ static ZigType *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructionExpor
         case ZigTypeIdErrorSet:
             zig_panic("TODO export const value of type %s", buf_ptr(&target->value.type->name));
         case ZigTypeIdNamespace:
-        case ZigTypeIdBlock:
         case ZigTypeIdBoundFn:
         case ZigTypeIdArgTuple:
         case ZigTypeIdOpaque:
@@ -13905,7 +13877,6 @@ static ZigType *ir_analyze_maybe(IrAnalyze *ira, IrInstructionUnOp *un_op_instru
         case ZigTypeIdUnion:
         case ZigTypeIdFn:
         case ZigTypeIdNamespace:
-        case ZigTypeIdBlock:
         case ZigTypeIdBoundFn:
         case ZigTypeIdArgTuple:
         case ZigTypeIdPromise:
@@ -15263,7 +15234,6 @@ static ZigType *ir_analyze_instruction_typeof(IrAnalyze *ira, IrInstructionTypeO
         case ZigTypeIdUndefined:
         case ZigTypeIdNull:
         case ZigTypeIdNamespace:
-        case ZigTypeIdBlock:
         case ZigTypeIdBoundFn:
         case ZigTypeIdMetaType:
         case ZigTypeIdVoid:
@@ -15516,7 +15486,6 @@ static ZigType *ir_analyze_instruction_slice_type(IrAnalyze *ira,
         case ZigTypeIdUnreachable:
         case ZigTypeIdUndefined:
         case ZigTypeIdNull:
-        case ZigTypeIdBlock:
         case ZigTypeIdArgTuple:
         case ZigTypeIdOpaque:
             ir_add_error_node(ira, slice_type_instruction->base.source_node,
@@ -15627,7 +15596,6 @@ static ZigType *ir_analyze_instruction_array_type(IrAnalyze *ira,
         case ZigTypeIdUnreachable:
         case ZigTypeIdUndefined:
         case ZigTypeIdNull:
-        case ZigTypeIdBlock:
         case ZigTypeIdArgTuple:
         case ZigTypeIdOpaque:
             ir_add_error_node(ira, array_type_instruction->base.source_node,
@@ -15698,7 +15666,6 @@ static ZigType *ir_analyze_instruction_size_of(IrAnalyze *ira,
         case ZigTypeIdUnreachable:
         case ZigTypeIdUndefined:
         case ZigTypeIdNull:
-        case ZigTypeIdBlock:
         case ZigTypeIdComptimeFloat:
         case ZigTypeIdComptimeInt:
         case ZigTypeIdBoundFn:
@@ -16184,7 +16151,6 @@ static ZigType *ir_analyze_instruction_switch_target(IrAnalyze *ira,
         case ZigTypeIdUndefined:
         case ZigTypeIdNull:
         case ZigTypeIdOptional:
-        case ZigTypeIdBlock:
         case ZigTypeIdBoundFn:
         case ZigTypeIdArgTuple:
         case ZigTypeIdOpaque:
@@ -16705,7 +16671,6 @@ static ZigType *ir_analyze_min_max(IrAnalyze *ira, IrInstruction *source_instruc
         case ZigTypeIdUnion:
         case ZigTypeIdFn:
         case ZigTypeIdNamespace:
-        case ZigTypeIdBlock:
         case ZigTypeIdBoundFn:
         case ZigTypeIdArgTuple:
         case ZigTypeIdOpaque:
@@ -17368,7 +17333,6 @@ static Error ir_make_type_info_value(IrAnalyze *ira, ZigType *type_entry, ConstE
         case ZigTypeIdUndefined:
         case ZigTypeIdNull:
         case ZigTypeIdNamespace:
-        case ZigTypeIdBlock:
         case ZigTypeIdArgTuple:
         case ZigTypeIdOpaque:
             *out = nullptr;
@@ -19341,7 +19305,6 @@ static ZigType *ir_analyze_instruction_align_of(IrAnalyze *ira, IrInstructionAli
         case ZigTypeIdUndefined:
         case ZigTypeIdNull:
         case ZigTypeIdNamespace:
-        case ZigTypeIdBlock:
         case ZigTypeIdBoundFn:
         case ZigTypeIdArgTuple:
         case ZigTypeIdVoid:
@@ -20102,7 +20065,6 @@ static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue
         case ZigTypeIdBoundFn:
         case ZigTypeIdArgTuple:
         case ZigTypeIdNamespace:
-        case ZigTypeIdBlock:
         case ZigTypeIdUnreachable:
         case ZigTypeIdComptimeFloat:
         case ZigTypeIdComptimeInt:
@@ -20169,7 +20131,6 @@ static void buf_read_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue
         case ZigTypeIdBoundFn:
         case ZigTypeIdArgTuple:
         case ZigTypeIdNamespace:
-        case ZigTypeIdBlock:
         case ZigTypeIdUnreachable:
         case ZigTypeIdComptimeFloat:
         case ZigTypeIdComptimeInt:
@@ -20249,7 +20210,6 @@ static ZigType *ir_analyze_instruction_bit_cast(IrAnalyze *ira, IrInstructionBit
         case ZigTypeIdBoundFn:
         case ZigTypeIdArgTuple:
         case ZigTypeIdNamespace:
-        case ZigTypeIdBlock:
         case ZigTypeIdUnreachable:
         case ZigTypeIdComptimeFloat:
         case ZigTypeIdComptimeInt:
@@ -20275,7 +20235,6 @@ static ZigType *ir_analyze_instruction_bit_cast(IrAnalyze *ira, IrInstructionBit
         case ZigTypeIdBoundFn:
         case ZigTypeIdArgTuple:
         case ZigTypeIdNamespace:
-        case ZigTypeIdBlock:
         case ZigTypeIdUnreachable:
         case ZigTypeIdComptimeFloat:
         case ZigTypeIdComptimeInt:
src/parser.cpp
@@ -700,7 +700,7 @@ static AstNode *ast_parse_comptime_expr(ParseContext *pc, size_t *token_index, b
 
 /*
 PrimaryExpression = Integer | Float | String | CharLiteral | KeywordLiteral | GroupedExpression | BlockExpression(BlockOrExpression) | Symbol | ("@" Symbol FnCallExpression) | ArrayType | FnProto | AsmExpression | ContainerDecl | ("continue" option(":" Symbol)) | ErrorSetDecl | PromiseType
-KeywordLiteral = "true" | "false" | "null" | "undefined" | "error" | "this" | "unreachable" | "suspend"
+KeywordLiteral = "true" | "false" | "null" | "undefined" | "error" | "unreachable" | "suspend"
 ErrorSetDecl = "error" "{" list(Symbol, ",") "}"
 */
 static AstNode *ast_parse_primary_expr(ParseContext *pc, size_t *token_index, bool mandatory) {
@@ -756,10 +756,6 @@ static AstNode *ast_parse_primary_expr(ParseContext *pc, size_t *token_index, bo
         AstNode *node = ast_create_node(pc, NodeTypeUndefinedLiteral, token);
         *token_index += 1;
         return node;
-    } else if (token->id == TokenIdKeywordThis) {
-        AstNode *node = ast_create_node(pc, NodeTypeThisLiteral, token);
-        *token_index += 1;
-        return node;
     } else if (token->id == TokenIdKeywordUnreachable) {
         AstNode *node = ast_create_node(pc, NodeTypeUnreachable, token);
         *token_index += 1;
@@ -3021,9 +3017,6 @@ void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *cont
         case NodeTypeUndefinedLiteral:
             // none
             break;
-        case NodeTypeThisLiteral:
-            // none
-            break;
         case NodeTypeIfBoolExpr:
             visit_field(&node->data.if_bool_expr.condition, visit, context);
             visit_field(&node->data.if_bool_expr.then_block, visit, context);
src/tokenizer.cpp
@@ -146,7 +146,6 @@ static const struct ZigKeyword zig_keywords[] = {
     {"suspend", TokenIdKeywordSuspend},
     {"switch", TokenIdKeywordSwitch},
     {"test", TokenIdKeywordTest},
-    {"this", TokenIdKeywordThis},
     {"true", TokenIdKeywordTrue},
     {"try", TokenIdKeywordTry},
     {"undefined", TokenIdKeywordUndefined},
@@ -1588,7 +1587,6 @@ const char * token_name(TokenId id) {
         case TokenIdKeywordStruct: return "struct";
         case TokenIdKeywordSwitch: return "switch";
         case TokenIdKeywordTest: return "test";
-        case TokenIdKeywordThis: return "this";
         case TokenIdKeywordTrue: return "true";
         case TokenIdKeywordTry: return "try";
         case TokenIdKeywordUndefined: return "undefined";
src/tokenizer.hpp
@@ -87,7 +87,6 @@ enum TokenId {
     TokenIdKeywordSuspend,
     TokenIdKeywordSwitch,
     TokenIdKeywordTest,
-    TokenIdKeywordThis,
     TokenIdKeywordTrue,
     TokenIdKeywordTry,
     TokenIdKeywordUndefined,
src-self-hosted/type.zig
@@ -40,7 +40,6 @@ pub const Type = struct {
             Id.Enum => @fieldParentPtr(Enum, "base", base).destroy(comp),
             Id.Union => @fieldParentPtr(Union, "base", base).destroy(comp),
             Id.Namespace => @fieldParentPtr(Namespace, "base", base).destroy(comp),
-            Id.Block => @fieldParentPtr(Block, "base", base).destroy(comp),
             Id.BoundFn => @fieldParentPtr(BoundFn, "base", base).destroy(comp),
             Id.ArgTuple => @fieldParentPtr(ArgTuple, "base", base).destroy(comp),
             Id.Opaque => @fieldParentPtr(Opaque, "base", base).destroy(comp),
@@ -74,7 +73,6 @@ pub const Type = struct {
             Id.Enum => return @fieldParentPtr(Enum, "base", base).getLlvmType(allocator, llvm_context),
             Id.Union => return @fieldParentPtr(Union, "base", base).getLlvmType(allocator, llvm_context),
             Id.Namespace => unreachable,
-            Id.Block => unreachable,
             Id.BoundFn => return @fieldParentPtr(BoundFn, "base", base).getLlvmType(allocator, llvm_context),
             Id.ArgTuple => unreachable,
             Id.Opaque => return @fieldParentPtr(Opaque, "base", base).getLlvmType(allocator, llvm_context),
@@ -90,7 +88,6 @@ pub const Type = struct {
             Id.Undefined,
             Id.Null,
             Id.Namespace,
-            Id.Block,
             Id.BoundFn,
             Id.ArgTuple,
             Id.Opaque,
@@ -124,7 +121,6 @@ pub const Type = struct {
             Id.Undefined,
             Id.Null,
             Id.Namespace,
-            Id.Block,
             Id.BoundFn,
             Id.ArgTuple,
             Id.Opaque,
@@ -1012,14 +1008,6 @@ pub const Type = struct {
         }
     };
 
-    pub const Block = struct {
-        base: Type,
-
-        pub fn destroy(self: *Block, comp: *Compilation) void {
-            comp.gpa().destroy(self);
-        }
-    };
-
     pub const BoundFn = struct {
         base: Type,
 
std/atomic/int.zig
@@ -6,7 +6,7 @@ pub fn Int(comptime T: type) type {
     return struct {
         unprotected_value: T,
 
-        pub const Self = this;
+        pub const Self = @This();
 
         pub fn init(init_val: T) Self {
             return Self{ .unprotected_value = init_val };
std/atomic/queue.zig
@@ -12,7 +12,7 @@ pub fn Queue(comptime T: type) type {
         tail: ?*Node,
         mutex: std.Mutex,
 
-        pub const Self = this;
+        pub const Self = @This();
         pub const Node = std.LinkedList(T).Node;
 
         pub fn init() Self {
std/atomic/stack.zig
@@ -9,7 +9,7 @@ pub fn Stack(comptime T: type) type {
         root: ?*Node,
         lock: u8,
 
-        pub const Self = this;
+        pub const Self = @This();
 
         pub const Node = struct {
             next: ?*Node,
std/crypto/blake2.zig
@@ -33,7 +33,7 @@ pub const Blake2s256 = Blake2s(256);
 
 fn Blake2s(comptime out_len: usize) type {
     return struct {
-        const Self = this;
+        const Self = @This();
         const block_length = 64;
         const digest_length = out_len / 8;
 
@@ -266,7 +266,7 @@ pub const Blake2b512 = Blake2b(512);
 
 fn Blake2b(comptime out_len: usize) type {
     return struct {
-        const Self = this;
+        const Self = @This();
         const block_length = 128;
         const digest_length = out_len / 8;
 
std/crypto/hmac.zig
@@ -9,7 +9,7 @@ pub const HmacSha256 = Hmac(crypto.Sha256);
 
 pub fn Hmac(comptime Hash: type) type {
     return struct {
-        const Self = this;
+        const Self = @This();
         pub const mac_length = Hash.digest_length;
         pub const minimum_key_length = 0;
 
std/crypto/md5.zig
@@ -28,7 +28,7 @@ fn Rp(a: usize, b: usize, c: usize, d: usize, k: usize, s: u32, t: u32) RoundPar
 }
 
 pub const Md5 = struct {
-    const Self = this;
+    const Self = @This();
     const block_length = 64;
     const digest_length = 16;
 
std/crypto/poly1305.zig
@@ -10,7 +10,7 @@ const readInt = std.mem.readInt;
 const writeInt = std.mem.writeInt;
 
 pub const Poly1305 = struct {
-    const Self = this;
+    const Self = @This();
 
     pub const mac_length = 16;
     pub const minimum_key_length = 32;
std/crypto/sha1.zig
@@ -25,7 +25,7 @@ fn Rp(a: usize, b: usize, c: usize, d: usize, e: usize, i: u32) RoundParam {
 }
 
 pub const Sha1 = struct {
-    const Self = this;
+    const Self = @This();
     const block_length = 64;
     const digest_length = 20;
 
std/crypto/sha2.zig
@@ -77,7 +77,7 @@ pub const Sha256 = Sha2_32(Sha256Params);
 
 fn Sha2_32(comptime params: Sha2Params32) type {
     return struct {
-        const Self = this;
+        const Self = @This();
         const block_length = 64;
         const digest_length = params.out_len / 8;
 
@@ -418,7 +418,7 @@ pub const Sha512 = Sha2_64(Sha512Params);
 
 fn Sha2_64(comptime params: Sha2Params64) type {
     return struct {
-        const Self = this;
+        const Self = @This();
         const block_length = 128;
         const digest_length = params.out_len / 8;
 
std/crypto/sha3.zig
@@ -12,7 +12,7 @@ pub const Sha3_512 = Keccak(512, 0x06);
 
 fn Keccak(comptime bits: usize, comptime delim: u8) type {
     return struct {
-        const Self = this;
+        const Self = @This();
         const block_length = 200;
         const digest_length = bits / 8;
 
std/event/channel.zig
@@ -25,7 +25,7 @@ pub fn Channel(comptime T: type) type {
         buffer_index: usize,
         buffer_len: usize,
 
-        const SelfChannel = this;
+        const SelfChannel = @This();
         const GetNode = struct {
             tick_node: *Loop.NextTickNode,
             data: Data,
std/event/fs.zig
@@ -724,7 +724,7 @@ pub fn Watch(comptime V: type) type {
 
         const FileToHandle = std.AutoHashMap([]const u8, promise);
 
-        const Self = this;
+        const Self = @This();
 
         pub const Event = struct {
             id: Id,
std/event/future.zig
@@ -21,7 +21,7 @@ pub fn Future(comptime T: type) type {
         /// 2 - finished
         available: u8,
 
-        const Self = this;
+        const Self = @This();
         const Queue = std.atomic.Queue(promise);
 
         pub fn init(loop: *Loop) Self {
std/event/group.zig
@@ -13,7 +13,7 @@ pub fn Group(comptime ReturnType: type) type {
         alloc_stack: Stack,
         lock: Lock,
 
-        const Self = this;
+        const Self = @This();
 
         const Error = switch (@typeInfo(ReturnType)) {
             builtin.TypeId.ErrorUnion => |payload| payload.error_set,
std/event/locked.zig
@@ -10,7 +10,7 @@ pub fn Locked(comptime T: type) type {
         lock: Lock,
         private_data: T,
 
-        const Self = this;
+        const Self = @This();
 
         pub const HeldLock = struct {
             value: *T,
std/event/rwlocked.zig
@@ -10,7 +10,7 @@ pub fn RwLocked(comptime T: type) type {
         lock: RwLock,
         locked_data: T,
 
-        const Self = this;
+        const Self = @This();
 
         pub const HeldReadLock = struct {
             value: *const T,
std/event/tcp.zig
@@ -132,7 +132,7 @@ test "listen on a port, send bytes, receive bytes" {
     const MyServer = struct {
         tcp_server: Server,
 
-        const Self = this;
+        const Self = @This();
         async<*mem.Allocator> fn handler(tcp_server: *Server, _addr: *const std.net.Address, _socket: *const std.os.File) void {
             const self = @fieldParentPtr(Self, "tcp_server", tcp_server);
             var socket = _socket.*; // TODO https://github.com/ziglang/zig/issues/733
std/fmt/index.zig
@@ -1183,7 +1183,7 @@ test "fmt.format" {
     //custom type format
     {
         const Vec2 = struct {
-            const SelfType = this;
+            const SelfType = @This();
             x: f32,
             y: f32,
 
std/hash/crc.zig
@@ -20,7 +20,7 @@ pub const Crc32 = Crc32WithPoly(Polynomial.IEEE);
 // slicing-by-8 crc32 implementation.
 pub fn Crc32WithPoly(comptime poly: u32) type {
     return struct {
-        const Self = this;
+        const Self = @This();
         const lookup_tables = comptime block: {
             @setEvalBranchQuota(20000);
             var tables: [8][256]u32 = undefined;
@@ -117,7 +117,7 @@ test "crc32 castagnoli" {
 // half-byte lookup table implementation.
 pub fn Crc32SmallWithPoly(comptime poly: u32) type {
     return struct {
-        const Self = this;
+        const Self = @This();
         const lookup_table = comptime block: {
             var table: [16]u32 = undefined;
 
std/hash/fnv.zig
@@ -13,7 +13,7 @@ pub const Fnv1a_128 = Fnv1a(u128, 0x1000000000000000000013b, 0x6c62272e07bb01426
 
 fn Fnv1a(comptime T: type, comptime prime: T, comptime offset: T) type {
     return struct {
-        const Self = this;
+        const Self = @This();
 
         value: T,
 
std/hash/siphash.zig
@@ -25,7 +25,7 @@ fn SipHash(comptime T: type, comptime c_rounds: usize, comptime d_rounds: usize)
     debug.assert(c_rounds > 0 and d_rounds > 0);
 
     return struct {
-        const Self = this;
+        const Self = @This();
         const digest_size = 64;
         const block_size = 64;
 
std/math/complex/index.zig
@@ -25,7 +25,7 @@ pub const tan = @import("tan.zig").tan;
 
 pub fn Complex(comptime T: type) type {
     return struct {
-        const Self = this;
+        const Self = @This();
 
         re: T,
         im: T,
std/os/index.zig
@@ -6,7 +6,7 @@ const is_posix = switch (builtin.os) {
     builtin.Os.linux, builtin.Os.macosx => true,
     else => false,
 };
-const os = this;
+const os = @This();
 
 test "std.os" {
     _ = @import("child_process.zig");
std/zig/ast.zig
@@ -231,7 +231,7 @@ pub const Error = union(enum) {
 
     fn SingleTokenError(comptime msg: []const u8) type {
         return struct {
-            const ThisError = this;
+            const ThisError = @This();
 
             token: TokenIndex,
 
@@ -244,7 +244,7 @@ pub const Error = union(enum) {
 
     fn SimpleError(comptime msg: []const u8) type {
         return struct {
-            const ThisError = this;
+            const ThisError = @This();
 
             token: TokenIndex,
 
std/zig/parser_test.zig
@@ -1354,7 +1354,7 @@ test "zig fmt: indexing" {
 test "zig fmt: struct declaration" {
     try testCanonical(
         \\const S = struct {
-        \\    const Self = this;
+        \\    const Self = @This();
         \\    f1: u8,
         \\    pub f3: u8,
         \\
std/zig/render.zig
@@ -20,7 +20,7 @@ pub fn render(allocator: *mem.Allocator, stream: var, tree: *ast.Tree) (@typeOf(
 
     // make a passthrough stream that checks whether something changed
     const MyStream = struct {
-        const MyStream = this;
+        const MyStream = @This();
         const StreamError = @typeOf(stream).Child.Error;
         const Stream = std.io.OutStream(StreamError);
 
std/array_list.zig
@@ -11,7 +11,7 @@ pub fn ArrayList(comptime T: type) type {
 
 pub fn AlignedArrayList(comptime T: type, comptime A: u29) type {
     return struct {
-        const Self = this;
+        const Self = @This();
 
         /// Use toSlice instead of slicing this directly, because if you don't
         /// specify the end position of the slice, this will potentially give
std/build.zig
@@ -1890,7 +1890,7 @@ const InstallArtifactStep = struct {
     artifact: *LibExeObjStep,
     dest_file: []const u8,
 
-    const Self = this;
+    const Self = @This();
 
     pub fn create(builder: *Builder, artifact: *LibExeObjStep) *Self {
         const dest_dir = switch (artifact.kind) {
std/hash_map.zig
@@ -22,7 +22,7 @@ pub fn HashMap(comptime K: type, comptime V: type, comptime hash: fn (key: K) u3
         // this is used to detect bugs where a hashtable is edited while an iterator is running.
         modification_count: debug_u32,
 
-        const Self = this;
+        const Self = @This();
 
         pub const KV = struct {
             key: K,
@@ -472,7 +472,6 @@ pub fn autoHash(key: var, comptime rng: *std.rand.Random, comptime HashInt: type
         builtin.TypeId.Promise, builtin.TypeId.Fn => return autoHash(@ptrToInt(key), rng),
 
         builtin.TypeId.Namespace,
-        builtin.TypeId.Block,
         builtin.TypeId.BoundFn,
         builtin.TypeId.ComptimeFloat,
         builtin.TypeId.ComptimeInt,
@@ -517,7 +516,6 @@ pub fn autoEql(a: var, b: @typeOf(a)) bool {
         builtin.TypeId.ComptimeFloat,
         builtin.TypeId.ComptimeInt,
         builtin.TypeId.Namespace,
-        builtin.TypeId.Block,
         builtin.TypeId.Promise,
         builtin.TypeId.Enum,
         builtin.TypeId.BoundFn,
std/heap.zig
@@ -385,7 +385,7 @@ pub fn stackFallback(comptime size: usize, fallback_allocator: *Allocator) Stack
 
 pub fn StackFallbackAllocator(comptime size: usize) type {
     return struct {
-        const Self = this;
+        const Self = @This();
 
         buffer: [size]u8,
         allocator: Allocator,
std/io.zig
@@ -76,7 +76,7 @@ pub const FileOutStream = struct {
 
 pub fn InStream(comptime ReadError: type) type {
     return struct {
-        const Self = this;
+        const Self = @This();
         pub const Error = ReadError;
 
         /// Return the number of bytes read. If the number read is smaller than buf.len, it
@@ -218,7 +218,7 @@ pub fn InStream(comptime ReadError: type) type {
 
 pub fn OutStream(comptime WriteError: type) type {
     return struct {
-        const Self = this;
+        const Self = @This();
         pub const Error = WriteError;
 
         writeFn: fn (self: *Self, bytes: []const u8) Error!void,
@@ -291,7 +291,7 @@ pub fn BufferedInStream(comptime Error: type) type {
 
 pub fn BufferedInStreamCustom(comptime buffer_size: usize, comptime Error: type) type {
     return struct {
-        const Self = this;
+        const Self = @This();
         const Stream = InStream(Error);
 
         pub stream: Stream,
@@ -361,7 +361,7 @@ pub fn BufferedInStreamCustom(comptime buffer_size: usize, comptime Error: type)
 /// This makes look-ahead style parsing much easier.
 pub fn PeekStream(comptime buffer_size: usize, comptime InStreamError: type) type {
     return struct {
-        const Self = this;
+        const Self = @This();
         pub const Error = InStreamError;
         pub const Stream = InStream(Error);
 
@@ -424,7 +424,7 @@ pub fn PeekStream(comptime buffer_size: usize, comptime InStreamError: type) typ
 }
 
 pub const SliceInStream = struct {
-    const Self = this;
+    const Self = @This();
     pub const Error = error{};
     pub const Stream = InStream(Error);
 
@@ -505,7 +505,7 @@ pub fn BufferedOutStream(comptime Error: type) type {
 
 pub fn BufferedOutStreamCustom(comptime buffer_size: usize, comptime OutStreamError: type) type {
     return struct {
-        const Self = this;
+        const Self = @This();
         pub const Stream = OutStream(Error);
         pub const Error = OutStreamError;
 
std/lazy_init.zig
@@ -18,7 +18,7 @@ fn LazyInit(comptime T: type) type {
         state: u8, // TODO make this an enum
         data: Data,
 
-        const Self = this;
+        const Self = @This();
 
         // TODO this isn't working for void, investigate and then remove this special case
         const Data = if (@sizeOf(T) == 0) u8 else T;
std/linked_list.zig
@@ -7,7 +7,7 @@ const Allocator = mem.Allocator;
 /// Generic doubly linked list.
 pub fn LinkedList(comptime T: type) type {
     return struct {
-        const Self = this;
+        const Self = @This();
 
         /// Node inside the linked list wrapping the actual data.
         pub const Node = struct {
std/mem.zig
@@ -3,7 +3,7 @@ const debug = std.debug;
 const assert = debug.assert;
 const math = std.math;
 const builtin = @import("builtin");
-const mem = this;
+const mem = @This();
 
 pub const Allocator = struct {
     pub const Error = error{OutOfMemory};
std/net.zig
@@ -1,7 +1,7 @@
 const std = @import("index.zig");
 const builtin = @import("builtin");
 const assert = std.debug.assert;
-const net = this;
+const net = @This();
 const posix = std.os.posix;
 const mem = std.mem;
 
std/segmented_list.zig
@@ -75,7 +75,7 @@ const Allocator = std.mem.Allocator;
 /// size is small. `prealloc_item_count` must be 0, or a power of 2.
 pub fn SegmentedList(comptime T: type, comptime prealloc_item_count: usize) type {
     return struct {
-        const Self = this;
+        const Self = @This();
         const prealloc_exp = blk: {
             // we don't use the prealloc_exp constant when prealloc_item_count is 0.
             assert(prealloc_item_count != 0);
test/cases/cast.zig
@@ -64,7 +64,7 @@ test "implicitly cast a container to a const pointer of it" {
 
 fn Struct(comptime T: type) type {
     return struct {
-        const Self = this;
+        const Self = @This();
         x: T,
 
         fn pointer(self: *const Self) Self {
@@ -106,7 +106,7 @@ const Enum = enum {
 
 test "implicitly cast indirect pointer to maybe-indirect pointer" {
     const S = struct {
-        const Self = this;
+        const Self = @This();
         x: u8,
         fn constConst(p: *const *const Self) u8 {
             return p.*.x;
test/cases/eval.zig
@@ -628,7 +628,7 @@ test "call method with comptime pass-by-non-copying-value self parameter" {
     const S = struct {
         a: u8,
 
-        fn b(comptime s: this) u8 {
+        fn b(comptime s: @This()) u8 {
             return s.a;
         }
     };
test/cases/misc.zig
@@ -510,9 +510,6 @@ test "@typeId" {
         assert(@typeId(AUnion) == Tid.Union);
         assert(@typeId(fn () void) == Tid.Fn);
         assert(@typeId(@typeOf(builtin)) == Tid.Namespace);
-        assert(@typeId(@typeOf(x: {
-            break :x this;
-        })) == Tid.Block);
         // TODO bound fn
         // TODO arg tuple
         // TODO opaque
test/cases/reflection.zig
@@ -1,6 +1,6 @@
 const assert = @import("std").debug.assert;
 const mem = @import("std").mem;
-const reflection = this;
+const reflection = @This();
 
 test "reflection: array, pointer, optional, error union type child" {
     comptime {
test/cases/struct.zig
@@ -423,10 +423,10 @@ fn alloc(comptime T: type) []T {
 
 test "call method with mutable reference to struct with no fields" {
     const S = struct {
-        fn doC(s: *const this) bool {
+        fn doC(s: *const @This()) bool {
             return true;
         }
-        fn do(s: *this) bool {
+        fn do(s: *@This()) bool {
             return true;
         }
     };
test/cases/this.zig
@@ -1,10 +1,10 @@
 const assert = @import("std").debug.assert;
 
-const module = this;
+const module = @This();
 
 fn Point(comptime T: type) type {
     return struct {
-        const Self = this;
+        const Self = @This();
         x: T,
         y: T,
 
@@ -19,11 +19,6 @@ fn add(x: i32, y: i32) i32 {
     return x + y;
 }
 
-fn factorial(x: i32) i32 {
-    const selfFn = this;
-    return if (x == 0) 1 else x * selfFn(x - 1);
-}
-
 test "this refer to module call private fn" {
     assert(module.add(1, 2) == 3);
 }
@@ -37,7 +32,3 @@ test "this refer to container" {
     assert(pt.x == 13);
     assert(pt.y == 35);
 }
-
-test "this refer to fn" {
-    assert(factorial(5) == 120);
-}
test/cases/type_info.zig
@@ -166,7 +166,7 @@ fn testUnion() void {
     assert(TypeId(typeinfo_info) == TypeId.Union);
     assert(typeinfo_info.Union.layout == TypeInfo.ContainerLayout.Auto);
     assert(typeinfo_info.Union.tag_type.? == TypeId);
-    assert(typeinfo_info.Union.fields.len == 25);
+    assert(typeinfo_info.Union.fields.len == 24);
     assert(typeinfo_info.Union.fields[4].enum_field != null);
     assert(typeinfo_info.Union.fields[4].enum_field.?.value == 4);
     assert(typeinfo_info.Union.fields[4].field_type == @typeOf(@typeInfo(u8).Int));
@@ -217,7 +217,7 @@ fn testStruct() void {
 }
 
 const TestStruct = packed struct {
-    const Self = this;
+    const Self = @This();
 
     fieldA: usize,
     fieldB: void,
test/compile_errors.zig
@@ -3813,11 +3813,11 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
         \\    return struct {
         \\        b: B(),
         \\
-        \\        const Self = this;
+        \\        const Self = @This();
         \\
         \\        fn B() type {
         \\            return struct {
-        \\                const Self = this;
+        \\                const Self = @This();
         \\            };
         \\        }
         \\    };
@@ -4314,12 +4314,11 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
         \\   var a = undefined;
         \\   var b = 1;
         \\   var c = 1.0;
-        \\   var d = this;
-        \\   var e = null;
-        \\   var f = opaque.*;
-        \\   var g = i32;
-        \\   var h = @import("std",);
-        \\   var i = (Foo {}).bar;
+        \\   var d = null;
+        \\   var e = opaque.*;
+        \\   var f = i32;
+        \\   var g = @import("std",);
+        \\   var h = (Foo {}).bar;
         \\
         \\   var z: noreturn = return;
         \\}
@@ -4332,13 +4331,12 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
         ".tmp_source.zig:7:4: error: variable of type '(undefined)' must be const or comptime",
         ".tmp_source.zig:8:4: error: variable of type 'comptime_int' must be const or comptime",
         ".tmp_source.zig:9:4: error: variable of type 'comptime_float' must be const or comptime",
-        ".tmp_source.zig:10:4: error: variable of type '(block)' must be const or comptime",
-        ".tmp_source.zig:11:4: error: variable of type '(null)' must be const or comptime",
-        ".tmp_source.zig:12:4: error: variable of type 'Opaque' not allowed",
-        ".tmp_source.zig:13:4: error: variable of type 'type' must be const or comptime",
-        ".tmp_source.zig:14:4: error: variable of type '(namespace)' must be const or comptime",
-        ".tmp_source.zig:15:4: error: variable of type '(bound fn(*const Foo) void)' must be const or comptime",
-        ".tmp_source.zig:17:4: error: unreachable code",
+        ".tmp_source.zig:10:4: error: variable of type '(null)' must be const or comptime",
+        ".tmp_source.zig:11:4: error: variable of type 'Opaque' not allowed",
+        ".tmp_source.zig:12:4: error: variable of type 'type' must be const or comptime",
+        ".tmp_source.zig:13:4: error: variable of type '(namespace)' must be const or comptime",
+        ".tmp_source.zig:14:4: error: variable of type '(bound fn(*const Foo) void)' must be const or comptime",
+        ".tmp_source.zig:16:4: error: unreachable code",
     );
 
     cases.add(