Commit c6ace9720c

Andrew Kelley <superjoe30@gmail.com>
2016-12-01 19:55:56
rename BlockContext to Scope
1 parent eb5693d
src/all_types.hpp
@@ -19,7 +19,7 @@
 struct AstNode;
 struct ImportTableEntry;
 struct FnTableEntry;
-struct BlockContext;
+struct Scope;
 struct TypeTableEntry;
 struct VariableTableEntry;
 struct ErrorTableEntry;
@@ -115,7 +115,7 @@ struct ConstExprValue {
         ConstArrayValue x_array;
         ConstPtrValue x_ptr;
         ImportTableEntry *x_import;
-        BlockContext *x_block;
+        Scope *x_block;
     } data;
 };
 
@@ -252,7 +252,7 @@ struct AstNodeFnDef {
     // populated by semantic analyzer
     TypeTableEntry *implicit_return_type;
     // the first child block context
-    BlockContext *block_context;
+    Scope *scope;
 };
 
 struct AstNodeFnDecl {
@@ -274,11 +274,11 @@ struct AstNodeBlock {
 
     // populated by semantic analyzer
     // this one is the scope that the block itself introduces
-    BlockContext *child_block;
+    Scope *child_block;
     // this is the innermost scope created by defers and var decls.
     // you can follow its parents up to child_block. it will equal
     // child_block if there are no defers or var decls in the block.
-    BlockContext *nested_block;
+    Scope *nested_block;
 };
 
 enum ReturnKind {
@@ -300,7 +300,7 @@ struct AstNodeDefer {
     // populated by semantic analyzer:
     size_t index_in_block;
     LLVMBasicBlockRef basic_block;
-    BlockContext *child_block;
+    Scope *child_block;
 };
 
 struct AstNodeVariableDeclaration {
@@ -638,7 +638,7 @@ struct AstNodeStructDecl {
     ZigList<AstNode *> decls;
 
     // populated by semantic analyzer
-    BlockContext *block_context;
+    Scope *scope;
     TypeTableEntry *type_entry;
     TypeTableEntry *generic_fn_type;
     bool skip;
@@ -762,7 +762,7 @@ struct AstNode {
     ImportTableEntry *owner;
     // the context in which this expression/node is evaluated.
     // for blocks, this points to the containing scope, not the block's own scope for its children.
-    BlockContext *block_context;
+    Scope *scope;
     union {
         AstNodeRoot root;
         AstNodeFnDef fn_def;
@@ -884,7 +884,7 @@ struct TypeTableEntryStruct {
     uint64_t size_bytes;
     bool is_invalid; // true if any fields are invalid
     bool is_slice;
-    BlockContext *block_context;
+    Scope *scope;
 
     // set this flag temporarily to detect infinite loops
     bool embedded_in_current;
@@ -910,7 +910,7 @@ struct TypeTableEntryEnum {
     TypeTableEntry *tag_type;
     TypeTableEntry *union_type;
 
-    BlockContext *block_context;
+    Scope *scope;
 
     // set this flag temporarily to detect infinite loops
     bool embedded_in_current;
@@ -926,7 +926,7 @@ struct TypeTableEntryUnion {
     TypeStructField *fields;
     uint64_t size_bytes;
     bool is_invalid; // true if any fields are invalid
-    BlockContext *block_context;
+    Scope *scope;
 
     // set this flag temporarily to detect infinite loops
     bool embedded_in_current;
@@ -1044,7 +1044,7 @@ struct ImportTableEntry {
     ZigLLVMDIFile *di_file;
     Buf *source_code;
     ZigList<size_t> *line_offsets;
-    BlockContext *block_context;
+    Scope *scope;
     AstNode *c_import_node;
     bool any_imports_failed;
 
@@ -1071,7 +1071,7 @@ struct FnTableEntry {
     AstNode *fn_def_node;
     ImportTableEntry *import_entry;
     // Required to be a pre-order traversal of the AST. (parents must come before children)
-    ZigList<BlockContext *> all_block_contexts;
+    ZigList<Scope *> all_block_contexts;
     Buf symbol_name;
     TypeTableEntry *type_entry; // function type
     bool internal_linkage;
@@ -1310,7 +1310,7 @@ struct VariableTableEntry {
     ZigLLVMDILocalVariable *di_loc_var;
     size_t src_arg_index;
     size_t gen_arg_index;
-    BlockContext *block_context;
+    Scope *scope;
     LLVMValueRef param_value_ref;
     bool force_depends_on_compile_var;
     ImportTableEntry *import;
@@ -1331,7 +1331,7 @@ struct LabelTableEntry {
     bool used;
 };
 
-struct BlockContext {
+struct Scope {
     AstNode *node;
 
     // any variables that are introduced by this scope
@@ -1343,7 +1343,7 @@ struct BlockContext {
     FnTableEntry *fn_entry;
 
     // if the block has a parent, this is it
-    BlockContext *parent;
+    Scope *parent;
 
     // if break or continue is valid in this context, this is the loop node that
     // it would pertain to
src/analyze.cpp
@@ -115,26 +115,26 @@ TypeTableEntry *new_type_table_entry(TypeTableEntryId id) {
     return entry;
 }
 
-static BlockContext **get_container_block_context_ptr(TypeTableEntry *type_entry) {
+static Scope **get_container_block_context_ptr(TypeTableEntry *type_entry) {
     if (type_entry->id == TypeTableEntryIdStruct) {
-        return &type_entry->data.structure.block_context;
+        return &type_entry->data.structure.scope;
     } else if (type_entry->id == TypeTableEntryIdEnum) {
-        return &type_entry->data.enumeration.block_context;
+        return &type_entry->data.enumeration.scope;
     } else if (type_entry->id == TypeTableEntryIdUnion) {
-        return &type_entry->data.unionation.block_context;
+        return &type_entry->data.unionation.scope;
     }
     zig_unreachable();
 }
 
-BlockContext *get_container_block_context(TypeTableEntry *type_entry) {
+Scope *get_container_block_context(TypeTableEntry *type_entry) {
     return *get_container_block_context_ptr(type_entry);
 }
 
 static TypeTableEntry *new_container_type_entry(TypeTableEntryId id, AstNode *source_node,
-        BlockContext *parent_context)
+        Scope *parent_context)
 {
     TypeTableEntry *entry = new_type_table_entry(id);
-    *get_container_block_context_ptr(entry) = new_block_context(source_node, parent_context);
+    *get_container_block_context_ptr(entry) = new_scope(source_node, parent_context);
     return entry;
 }
 
@@ -766,7 +766,7 @@ static TypeTableEntryId container_to_type(ContainerKind kind) {
     zig_unreachable();
 }
 
-TypeTableEntry *get_partial_container_type(CodeGen *g, ImportTableEntry *import, BlockContext *context,
+TypeTableEntry *get_partial_container_type(CodeGen *g, ImportTableEntry *import, Scope *context,
         ContainerKind kind, AstNode *decl_node, const char *name)
 {
     TypeTableEntryId type_id = container_to_type(kind);
@@ -805,7 +805,7 @@ TypeTableEntry *get_underlying_type(TypeTableEntry *type_entry) {
     }
 }
 
-static IrInstruction *analyze_const_value(CodeGen *g, BlockContext *scope, AstNode *node,
+static IrInstruction *analyze_const_value(CodeGen *g, Scope *scope, AstNode *node,
         TypeTableEntry *expected_type)
 {
     IrExecutable ir_executable = {0};
@@ -844,7 +844,7 @@ static IrInstruction *analyze_const_value(CodeGen *g, BlockContext *scope, AstNo
     return result;
 }
 
-static TypeTableEntry *analyze_type_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,
+static TypeTableEntry *analyze_type_expr(CodeGen *g, ImportTableEntry *import, Scope *context,
         AstNode *node)
 {
     IrInstruction *result = analyze_const_value(g, context, node, g->builtin_types.entry_type);
@@ -861,7 +861,7 @@ static bool fn_wants_full_static_eval(FnTableEntry *fn_table_entry) {
 }
 
 // fn_table_entry is populated if and only if there is a function definition for this prototype
-static TypeTableEntry *analyze_fn_proto_type(CodeGen *g, ImportTableEntry *import, BlockContext *context,
+static TypeTableEntry *analyze_fn_proto_type(CodeGen *g, ImportTableEntry *import, Scope *context,
         TypeTableEntry *expected_type, AstNode *node, bool is_naked, bool is_cold, FnTableEntry *fn_table_entry)
 {
     assert(node->type == NodeTypeFnProto);
@@ -1022,7 +1022,7 @@ static TypeTableEntry *analyze_fn_proto_type(CodeGen *g, ImportTableEntry *impor
 }
 
 static void resolve_function_proto(CodeGen *g, AstNode *node, FnTableEntry *fn_table_entry,
-        ImportTableEntry *import, BlockContext *containing_context)
+        ImportTableEntry *import, Scope *containing_context)
 {
     assert(node->type == NodeTypeFnProto);
     AstNodeFnProto *fn_proto = &node->data.fn_proto;
@@ -1060,8 +1060,8 @@ static void resolve_function_proto(CodeGen *g, AstNode *node, FnTableEntry *fn_t
     }
 
     if (fn_table_entry->fn_def_node) {
-        BlockContext *context = new_block_context(fn_table_entry->fn_def_node, containing_context);
-        fn_table_entry->fn_def_node->data.fn_def.block_context = context;
+        Scope *context = new_scope(fn_table_entry->fn_def_node, containing_context);
+        fn_table_entry->fn_def_node->data.fn_def.scope = context;
     }
 
     if (!fn_wants_full_static_eval(fn_table_entry)) {
@@ -1109,7 +1109,7 @@ static void resolve_function_proto(CodeGen *g, AstNode *node, FnTableEntry *fn_t
                 fn_type->di_type, fn_table_entry->internal_linkage,
                 is_definition, scope_line, flags, is_optimized, nullptr);
 
-            fn_table_entry->fn_def_node->data.fn_def.block_context->di_scope = ZigLLVMSubprogramToScope(subprogram);
+            fn_table_entry->fn_def_node->data.fn_def.scope->di_scope = ZigLLVMSubprogramToScope(subprogram);
             ZigLLVMFnSetSubprogram(fn_table_entry->fn_value, subprogram);
         }
     }
@@ -1151,7 +1151,7 @@ static void resolve_enum_type(CodeGen *g, ImportTableEntry *import, TypeTableEnt
     uint64_t biggest_align_in_bits = 0;
     uint64_t biggest_union_member_size_in_bits = 0;
 
-    BlockContext *context = enum_type->data.enumeration.block_context;
+    Scope *context = enum_type->data.enumeration.scope;
 
     // set temporary flag
     enum_type->data.enumeration.embedded_in_current = true;
@@ -1337,7 +1337,7 @@ static void resolve_struct_type(CodeGen *g, ImportTableEntry *import, TypeTableE
     // this field should be set to true only during the recursive calls to resolve_struct_type
     struct_type->data.structure.embedded_in_current = true;
 
-    BlockContext *context = struct_type->data.structure.block_context;
+    Scope *context = struct_type->data.structure.scope;
 
     size_t gen_field_index = 0;
     for (size_t i = 0; i < field_count; i += 1) {
@@ -1463,7 +1463,7 @@ static bool get_is_generic_fn(AstNode *proto_node) {
 }
 
 static void preview_fn_proto_instance(CodeGen *g, ImportTableEntry *import, AstNode *proto_node,
-        BlockContext *containing_context)
+        Scope *containing_context)
 {
     assert(proto_node->type == NodeTypeFnProto);
 
@@ -1546,7 +1546,7 @@ static void preview_fn_proto_instance(CodeGen *g, ImportTableEntry *import, AstN
     }
 }
 
-static void add_top_level_decl(CodeGen *g, ImportTableEntry *import, BlockContext *block_context,
+static void add_top_level_decl(CodeGen *g, ImportTableEntry *import, Scope *scope,
         AstNode *node, Buf *name)
 {
     assert(import);
@@ -1562,19 +1562,19 @@ static void add_top_level_decl(CodeGen *g, ImportTableEntry *import, BlockContex
         g->resolve_queue.append(node);
     }
 
-    node->block_context = block_context;
+    node->scope = scope;
 
-    auto entry = block_context->decl_table.maybe_get(name);
+    auto entry = scope->decl_table.maybe_get(name);
     if (entry) {
         AstNode *other_decl_node = entry->value;
         ErrorMsg *msg = add_node_error(g, node, buf_sprintf("redefinition of '%s'", buf_ptr(name)));
         add_error_note(g, msg, other_decl_node, buf_sprintf("previous definition is here"));
     } else {
-        block_context->decl_table.put(name, node);
+        scope->decl_table.put(name, node);
     }
 }
 
-static void scan_struct_decl(CodeGen *g, ImportTableEntry *import, BlockContext *context, AstNode *node) {
+static void scan_struct_decl(CodeGen *g, ImportTableEntry *import, Scope *context, AstNode *node) {
     assert(node->type == NodeTypeContainerDecl);
 
     if (node->data.struct_decl.type_entry) {
@@ -1591,7 +1591,7 @@ static void scan_struct_decl(CodeGen *g, ImportTableEntry *import, BlockContext
     for (size_t i = 0; i < node->data.struct_decl.decls.length; i += 1) {
         AstNode *child_node = node->data.struct_decl.decls.at(i);
         get_as_top_level_decl(child_node)->parent_decl = node;
-        BlockContext *child_context = get_container_block_context(container_type);
+        Scope *child_context = get_container_block_context(container_type);
         scan_decls(g, import, child_context, child_node);
     }
 }
@@ -1644,7 +1644,7 @@ static void preview_error_value_decl(CodeGen *g, AstNode *node) {
     node->data.error_value_decl.top_level_decl.resolution = TldResolutionOk;
 }
 
-void scan_decls(CodeGen *g, ImportTableEntry *import, BlockContext *context, AstNode *node) {
+void scan_decls(CodeGen *g, ImportTableEntry *import, Scope *context, AstNode *node) {
     switch (node->type) {
         case NodeTypeRoot:
             for (size_t i = 0; i < import->root->data.root.top_level_decls.length; i += 1) {
@@ -1695,7 +1695,7 @@ void scan_decls(CodeGen *g, ImportTableEntry *import, BlockContext *context, Ast
             {
                 TopLevelDecl *tld = get_as_top_level_decl(node);
                 tld->import = import;
-                node->block_context = context;
+                node->scope = context;
                 g->use_queue.append(node);
                 tld->import->use_decls.append(node);
                 break;
@@ -1817,12 +1817,12 @@ TypeTableEntry *validate_var_type(CodeGen *g, AstNode *source_node, TypeTableEnt
 // Set name to nullptr to make the variable anonymous (not visible to programmer).
 // TODO merge with definition of add_local_var in ir.cpp
 static VariableTableEntry *add_local_var_shadowable(CodeGen *g, AstNode *source_node, ImportTableEntry *import,
-        BlockContext *context, Buf *name, TypeTableEntry *type_entry, bool is_const, AstNode *val_node,
+        Scope *context, Buf *name, TypeTableEntry *type_entry, bool is_const, AstNode *val_node,
         bool shadowable)
 {
     VariableTableEntry *variable_entry = allocate<VariableTableEntry>(1);
     variable_entry->type = type_entry;
-    variable_entry->block_context = context;
+    variable_entry->scope = context;
     variable_entry->import = import;
     variable_entry->shadowable = shadowable;
     variable_entry->mem_slot_index = SIZE_MAX;
@@ -1875,7 +1875,7 @@ static VariableTableEntry *add_local_var_shadowable(CodeGen *g, AstNode *source_
 }
 
 static VariableTableEntry *add_local_var(CodeGen *g, AstNode *source_node, ImportTableEntry *import,
-        BlockContext *context, Buf *name, TypeTableEntry *type_entry, bool is_const, AstNode *val_node)
+        Scope *context, Buf *name, TypeTableEntry *type_entry, bool is_const, AstNode *val_node)
 {
     return add_local_var_shadowable(g, source_node, import, context, name, type_entry, is_const, val_node, false);
 }
@@ -1884,7 +1884,7 @@ static void resolve_var_decl(CodeGen *g, ImportTableEntry *import, AstNode *node
     assert(node->type == NodeTypeVariableDeclaration);
 
     AstNodeVariableDeclaration *var_decl = &node->data.variable_declaration;
-    BlockContext *scope = node->block_context;
+    Scope *scope = node->scope;
     bool is_const = var_decl->is_const;
     bool is_export = (var_decl->top_level_decl.visib_mod == VisibModExport);
     bool is_extern = var_decl->is_extern;
@@ -1963,7 +1963,7 @@ void resolve_top_level_decl(CodeGen *g, AstNode *node, bool pointer_only) {
 
     switch (node->type) {
         case NodeTypeFnProto:
-            preview_fn_proto_instance(g, import, node, node->block_context);
+            preview_fn_proto_instance(g, import, node, node->scope);
             break;
         case NodeTypeContainerDecl:
             resolve_struct_decl(g, import, node);
@@ -1980,7 +1980,7 @@ void resolve_top_level_decl(CodeGen *g, AstNode *node, bool pointer_only) {
                 if (node->data.type_decl.override_type) {
                     entry = node->data.type_decl.override_type;
                 } else {
-                    TypeTableEntry *child_type = analyze_type_expr(g, import, import->block_context, type_node);
+                    TypeTableEntry *child_type = analyze_type_expr(g, import, import->scope, type_node);
                     if (child_type->id == TypeTableEntryIdInvalid) {
                         entry = child_type;
                     } else {
@@ -2170,8 +2170,8 @@ bool types_match_const_cast_only(TypeTableEntry *expected_type, TypeTableEntry *
     return false;
 }
 
-BlockContext *new_block_context(AstNode *node, BlockContext *parent) {
-    BlockContext *context = allocate<BlockContext>(1);
+Scope *new_scope(AstNode *node, Scope *parent) {
+    Scope *context = allocate<Scope>(1);
     context->node = node;
     context->parent = parent;
     context->decl_table.init(1);
@@ -2197,7 +2197,7 @@ BlockContext *new_block_context(AstNode *node, BlockContext *parent) {
     return context;
 }
 
-AstNode *find_decl(BlockContext *context, Buf *name) {
+AstNode *find_decl(Scope *context, Buf *name) {
     while (context) {
         auto entry = context->decl_table.maybe_get(name);
         if (entry) {
@@ -2208,8 +2208,8 @@ AstNode *find_decl(BlockContext *context, Buf *name) {
     return nullptr;
 }
 
-VariableTableEntry *find_variable(CodeGen *g, BlockContext *orig_context, Buf *name) {
-    BlockContext *context = orig_context;
+VariableTableEntry *find_variable(CodeGen *g, Scope *orig_context, Buf *name) {
+    Scope *context = orig_context;
     while (context) {
         auto entry = context->var_table.maybe_get(name);
         if (entry) {
@@ -2355,7 +2355,7 @@ static void analyze_fn_body(CodeGen *g, FnTableEntry *fn_table_entry) {
     }
     fn_table_entry->anal_state = FnAnalStateProbing;
 
-    BlockContext *context = node->data.fn_def.block_context;
+    Scope *context = node->data.fn_def.scope;
 
     TypeTableEntry *fn_type = fn_table_entry->type_entry;
     FnTypeId *fn_type_id = &fn_type->data.fn.fn_type_id;
@@ -2456,7 +2456,7 @@ static void add_symbols_from_import(CodeGen *g, AstNode *src_use_node, AstNode *
             continue;
         }
         if (target_tld->visib_mod != VisibModPrivate) {
-            auto existing_entry = tld->import->block_context->decl_table.maybe_get(target_tld->name);
+            auto existing_entry = tld->import->scope->decl_table.maybe_get(target_tld->name);
             if (existing_entry) {
                 AstNode *existing_decl = existing_entry->value;
                 if (existing_decl != decl_node) {
@@ -2467,7 +2467,7 @@ static void add_symbols_from_import(CodeGen *g, AstNode *src_use_node, AstNode *
                     add_error_note(g, msg, decl_node, buf_sprintf("imported definition here"));
                 }
             } else {
-                tld->import->block_context->decl_table.put(target_tld->name, decl_node);
+                tld->import->scope->decl_table.put(target_tld->name, decl_node);
             }
         }
     }
@@ -2494,7 +2494,7 @@ void preview_use_decl(CodeGen *g, AstNode *node) {
     assert(node->type == NodeTypeUse);
     TopLevelDecl *tld = get_as_top_level_decl(node);
 
-    IrInstruction *result = analyze_const_value(g, tld->import->block_context, node->data.use.expr,
+    IrInstruction *result = analyze_const_value(g, tld->import->scope, node->data.use.expr,
             g->builtin_types.entry_namespace);
     if (result->type_entry->id == TypeTableEntryIdInvalid)
         tld->import->any_imports_failed = true;
@@ -2553,8 +2553,8 @@ ImportTableEntry *add_source_file(CodeGen *g, PackageTableEntry *package,
     g->import_table.put(abs_full_path, import_entry);
     g->import_queue.append(import_entry);
 
-    import_entry->block_context = new_block_context(import_entry->root, nullptr);
-    import_entry->block_context->di_scope = ZigLLVMFileToScope(import_entry->di_file);
+    import_entry->scope = new_scope(import_entry->root, nullptr);
+    import_entry->scope->di_scope = ZigLLVMFileToScope(import_entry->di_file);
 
 
     assert(import_entry->root->type == NodeTypeRoot);
@@ -2581,7 +2581,7 @@ ImportTableEntry *add_source_file(CodeGen *g, PackageTableEntry *package,
 void semantic_analyze(CodeGen *g) {
     for (; g->import_queue_index < g->import_queue.length; g->import_queue_index += 1) {
         ImportTableEntry *import = g->import_queue.at(g->import_queue_index);
-        scan_decls(g, import, import->block_context, import->root);
+        scan_decls(g, import, import->scope, import->root);
     }
 
     for (; g->use_queue_index < g->use_queue.length; g->use_queue_index += 1) {
src/analyze.hpp
@@ -15,7 +15,7 @@ ErrorMsg *add_node_error(CodeGen *g, AstNode *node, Buf *msg);
 ErrorMsg *add_error_note(CodeGen *g, ErrorMsg *parent_msg, AstNode *node, Buf *msg);
 TypeTableEntry *new_type_table_entry(TypeTableEntryId id);
 TypeTableEntry *get_pointer_to_type(CodeGen *g, TypeTableEntry *child_type, bool is_const);
-BlockContext *new_block_context(AstNode *node, BlockContext *parent);
+Scope *new_scope(AstNode *node, Scope *parent);
 bool is_node_void_expr(AstNode *node);
 uint64_t type_size(CodeGen *g, TypeTableEntry *type_entry);
 TypeTableEntry **get_int_type_ptr(CodeGen *g, bool is_signed, size_t size_in_bits);
@@ -27,7 +27,7 @@ TypeTableEntry *get_fn_type(CodeGen *g, FnTypeId *fn_type_id, bool gen_debug_inf
 TypeTableEntry *get_maybe_type(CodeGen *g, TypeTableEntry *child_type);
 TypeTableEntry *get_array_type(CodeGen *g, TypeTableEntry *child_type, uint64_t array_size);
 TypeTableEntry *get_slice_type(CodeGen *g, TypeTableEntry *child_type, bool is_const);
-TypeTableEntry *get_partial_container_type(CodeGen *g, ImportTableEntry *import, BlockContext *context,
+TypeTableEntry *get_partial_container_type(CodeGen *g, ImportTableEntry *import, Scope *context,
         ContainerKind kind, AstNode *decl_node, const char *name);
 TypeTableEntry *get_smallest_unsigned_int_type(CodeGen *g, uint64_t x);
 TypeTableEntry *get_error_type(CodeGen *g, TypeTableEntry *child_type);
@@ -49,8 +49,8 @@ AstNode *first_executing_node(AstNode *node);
 
 // TODO move these over, these used to be static
 bool types_match_const_cast_only(TypeTableEntry *expected_type, TypeTableEntry *actual_type);
-VariableTableEntry *find_variable(CodeGen *g, BlockContext *orig_context, Buf *name);
-AstNode *find_decl(BlockContext *context, Buf *name);
+VariableTableEntry *find_variable(CodeGen *g, Scope *orig_context, Buf *name);
+AstNode *find_decl(Scope *context, Buf *name);
 void resolve_top_level_decl(CodeGen *g, AstNode *node, bool pointer_only);
 TopLevelDecl *get_as_top_level_decl(AstNode *node);
 bool type_is_codegen_pointer(TypeTableEntry *type);
@@ -59,10 +59,10 @@ TypeTableEntry *container_ref_type(TypeTableEntry *type_entry);
 bool type_is_complete(TypeTableEntry *type_entry);
 void resolve_container_type(CodeGen *g, TypeTableEntry *type_entry);
 TypeStructField *find_struct_type_field(TypeTableEntry *type_entry, Buf *name);
-BlockContext *get_container_block_context(TypeTableEntry *type_entry);
+Scope *get_container_block_context(TypeTableEntry *type_entry);
 TypeEnumField *find_enum_type_field(TypeTableEntry *enum_type, Buf *name);
 bool is_container_ref(TypeTableEntry *type_entry);
-void scan_decls(CodeGen *g, ImportTableEntry *import, BlockContext *context, AstNode *node);
+void scan_decls(CodeGen *g, ImportTableEntry *import, Scope *context, AstNode *node);
 void preview_use_decl(CodeGen *g, AstNode *node);
 void resolve_use_decl(CodeGen *g, AstNode *node);
 
src/codegen.cpp
@@ -228,8 +228,8 @@ static void render_const_val(CodeGen *g, TypeTableEntry *type_entry, ConstExprVa
 static void render_const_val_global(CodeGen *g, TypeTableEntry *type_entry, ConstExprValue *const_val);
 
 static void set_debug_source_node(CodeGen *g, AstNode *node) {
-    assert(node->block_context);
-    ZigLLVMSetCurrentDebugLocation(g->builder, node->line + 1, node->column + 1, node->block_context->di_scope);
+    assert(node->scope);
+    ZigLLVMSetCurrentDebugLocation(g->builder, node->line + 1, node->column + 1, node->scope->di_scope);
 }
 
 static void clear_debug_source_node(CodeGen *g) {
@@ -312,7 +312,7 @@ static LLVMValueRef get_handle_value(CodeGen *g, LLVMValueRef ptr, TypeTableEntr
     }
 }
 
-static bool want_debug_safety_recursive(CodeGen *g, BlockContext *context) {
+static bool want_debug_safety_recursive(CodeGen *g, Scope *context) {
     if (context->safety_set_node || !context->parent) {
         return !context->safety_off;
     }
@@ -325,7 +325,7 @@ static bool want_debug_safety(CodeGen *g, AstNode *node) {
     if (g->is_release_build) {
         return false;
     }
-    return want_debug_safety_recursive(g, node->block_context);
+    return want_debug_safety_recursive(g, node->scope);
 }
 
 static bool ir_want_debug_safety(CodeGen *g, IrInstruction *instruction) {
@@ -558,10 +558,10 @@ static LLVMValueRef gen_assign_raw(CodeGen *g, AstNode *source_node,
 }
 
 static void gen_var_debug_decl(CodeGen *g, VariableTableEntry *var) {
-    BlockContext *block_context = var->block_context;
+    Scope *scope = var->scope;
     AstNode *source_node = var->decl_node;
     ZigLLVMDILocation *debug_loc = ZigLLVMGetDebugLoc(source_node->line + 1, source_node->column + 1,
-            block_context->di_scope);
+            scope->di_scope);
     ZigLLVMInsertDeclareAtEnd(g->dbuilder, var->value_ref, var->di_loc_var, debug_loc,
             LLVMGetInsertBlock(g->builder));
 }
@@ -2134,7 +2134,7 @@ static void gen_global_var(CodeGen *g, VariableTableEntry *var, LLVMValueRef ini
     assert(type_entry);
     bool is_local_to_unit = true;
     ZigLLVMCreateGlobalVariable(g->dbuilder,
-        var->block_context->di_scope, buf_ptr(&var->name),
+        var->scope->di_scope, buf_ptr(&var->name),
         buf_ptr(&var->name), var->import->di_file, var->decl_node->line + 1,
         type_entry->di_type, is_local_to_unit, init_val);
 }
@@ -2332,15 +2332,15 @@ static void do_code_gen(CodeGen *g) {
 
         // Set up debug info for blocks
         for (size_t bc_i = 0; bc_i < fn_table_entry->all_block_contexts.length; bc_i += 1) {
-            BlockContext *block_context = fn_table_entry->all_block_contexts.at(bc_i);
+            Scope *scope = fn_table_entry->all_block_contexts.at(bc_i);
 
-            if (!block_context->di_scope) {
+            if (!scope->di_scope) {
                 ZigLLVMDILexicalBlock *di_block = ZigLLVMCreateLexicalBlock(g->dbuilder,
-                    block_context->parent->di_scope,
+                    scope->parent->di_scope,
                     import->di_file,
-                    block_context->node->line + 1,
-                    block_context->node->column + 1);
-                block_context->di_scope = ZigLLVMLexicalBlockToScope(di_block);
+                    scope->node->line + 1,
+                    scope->node->column + 1);
+                scope->di_scope = ZigLLVMLexicalBlockToScope(di_block);
             }
 
 
@@ -2383,7 +2383,7 @@ static void do_code_gen(CodeGen *g) {
             if (var->is_inline)
                 continue;
 
-            if (var->block_context->node->type == NodeTypeFnDef) {
+            if (var->scope->node->type == NodeTypeFnDef) {
                 assert(var->gen_arg_index != SIZE_MAX);
                 TypeTableEntry *gen_type;
                 if (handle_is_ptr(var->type)) {
@@ -2395,7 +2395,7 @@ static void do_code_gen(CodeGen *g) {
                     unsigned align_bytes = ZigLLVMGetPrefTypeAlignment(g->target_data_ref, var->type->type_ref);
                     LLVMSetAlignment(var->value_ref, align_bytes);
                 }
-                var->di_loc_var = ZigLLVMCreateParameterVariable(g->dbuilder, var->block_context->di_scope,
+                var->di_loc_var = ZigLLVMCreateParameterVariable(g->dbuilder, var->scope->di_scope,
                         buf_ptr(&var->name), import->di_file, var->decl_node->line + 1,
                         gen_type->di_type, !g->strip_debug_symbols, 0, var->gen_arg_index + 1);
 
@@ -2406,7 +2406,7 @@ static void do_code_gen(CodeGen *g) {
                 unsigned align_bytes = ZigLLVMGetPrefTypeAlignment(g->target_data_ref, var->type->type_ref);
                 LLVMSetAlignment(var->value_ref, align_bytes);
 
-                var->di_loc_var = ZigLLVMCreateAutoVariable(g->dbuilder, var->block_context->di_scope,
+                var->di_loc_var = ZigLLVMCreateAutoVariable(g->dbuilder, var->scope->di_scope,
                         buf_ptr(&var->name), import->di_file, var->decl_node->line + 1,
                         var->type->di_type, !g->strip_debug_symbols, 0);
             }
src/ir.cpp
@@ -31,8 +31,8 @@ struct IrAnalyze {
     IrBasicBlock *const_predecessor_bb;
 };
 
-static IrInstruction *ir_gen_node(IrBuilder *irb, AstNode *node, BlockContext *scope);
-static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, BlockContext *block_context,
+static IrInstruction *ir_gen_node(IrBuilder *irb, AstNode *node, Scope *scope);
+static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, Scope *scope,
         LValPurpose lval);
 static TypeTableEntry *ir_analyze_instruction(IrAnalyze *ira, IrInstruction *instruction);
 
@@ -451,7 +451,7 @@ static IrInstruction *ir_build_const_import(IrBuilder *irb, AstNode *source_node
     return &const_instruction->base;
 }
 
-static IrInstruction *ir_build_const_scope(IrBuilder *irb, AstNode *source_node, BlockContext *scope) {
+static IrInstruction *ir_build_const_scope(IrBuilder *irb, AstNode *source_node, Scope *scope) {
     IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, source_node);
     const_instruction->base.type_entry = irb->codegen->builtin_types.entry_block;
     const_instruction->base.static_value.special = ConstValSpecialStatic;
@@ -1211,7 +1211,7 @@ static IrInstruction *ir_build_ref_from(IrBuilder *irb, IrInstruction *old_instr
     return new_instruction;
 }
 
-static void ir_gen_defers_for_block(IrBuilder *irb, BlockContext *inner_block, BlockContext *outer_block,
+static void ir_gen_defers_for_block(IrBuilder *irb, Scope *inner_block, Scope *outer_block,
         bool gen_error_defers, bool gen_maybe_defers)
 {
     while (inner_block != outer_block) {
@@ -1221,7 +1221,7 @@ static void ir_gen_defers_for_block(IrBuilder *irb, BlockContext *inner_block, B
             (gen_maybe_defers && inner_block->node->data.defer.kind == ReturnKindMaybe)))
         {
             AstNode *defer_expr_node = inner_block->node->data.defer.expr;
-            ir_gen_node(irb, defer_expr_node, defer_expr_node->block_context);
+            ir_gen_node(irb, defer_expr_node, defer_expr_node->scope);
         }
         inner_block = inner_block->parent;
     }
@@ -1230,7 +1230,7 @@ static void ir_gen_defers_for_block(IrBuilder *irb, BlockContext *inner_block, B
 static IrInstruction *ir_gen_return(IrBuilder *irb, AstNode *node) {
     assert(node->type == NodeTypeReturnExpr);
 
-    BlockContext *scope = node->block_context;
+    Scope *scope = node->scope;
 
     if (!scope->fn_entry) {
         add_node_error(irb->codegen, node, buf_sprintf("return expression outside function definition"));
@@ -1264,11 +1264,11 @@ static void ir_set_cursor_at_end(IrBuilder *irb, IrBasicBlock *basic_block) {
     irb->current_basic_block = basic_block;
 }
 
-static VariableTableEntry *add_local_var(CodeGen *codegen, AstNode *node, BlockContext *scope,
+static VariableTableEntry *add_local_var(CodeGen *codegen, AstNode *node, Scope *scope,
         Buf *name, bool src_is_const, bool gen_is_const, bool is_shadowable, bool is_inline)
 {
     VariableTableEntry *variable_entry = allocate<VariableTableEntry>(1);
-    variable_entry->block_context = scope;
+    variable_entry->scope = scope;
     variable_entry->import = node->owner;
     variable_entry->shadowable = is_shadowable;
     variable_entry->mem_slot_index = SIZE_MAX;
@@ -1316,7 +1316,7 @@ static VariableTableEntry *add_local_var(CodeGen *codegen, AstNode *node, BlockC
 }
 
 // Set name to nullptr to make the variable anonymous (not visible to programmer).
-static VariableTableEntry *ir_add_local_var(IrBuilder *irb, AstNode *node, BlockContext *scope, Buf *name,
+static VariableTableEntry *ir_add_local_var(IrBuilder *irb, AstNode *node, Scope *scope, Buf *name,
         bool src_is_const, bool gen_is_const, bool is_shadowable, bool is_inline)
 {
     VariableTableEntry *var = add_local_var(irb->codegen, node, scope, name,
@@ -1329,41 +1329,41 @@ static VariableTableEntry *ir_add_local_var(IrBuilder *irb, AstNode *node, Block
 static IrInstruction *ir_gen_block(IrBuilder *irb, AstNode *block_node) {
     assert(block_node->type == NodeTypeBlock);
 
-    BlockContext *parent_context = block_node->block_context;
-    BlockContext *outer_block_context = new_block_context(block_node, parent_context);
-    BlockContext *child_context = outer_block_context;
+    Scope *parent_scope = block_node->scope;
+    Scope *outer_block_scope = new_scope(block_node, parent_scope);
+    Scope *child_scope = outer_block_scope;
 
     IrInstruction *return_value = nullptr;
     for (size_t i = 0; i < block_node->data.block.statements.length; i += 1) {
         AstNode *statement_node = block_node->data.block.statements.at(i);
-        return_value = ir_gen_node(irb, statement_node, child_context);
+        return_value = ir_gen_node(irb, statement_node, child_scope);
         if (statement_node->type == NodeTypeDefer && return_value != irb->codegen->invalid_instruction) {
             // defer starts a new block context
-            child_context = statement_node->data.defer.child_block;
-            assert(child_context);
+            child_scope = statement_node->data.defer.child_block;
+            assert(child_scope);
         }
     }
 
     if (!return_value)
         return_value = ir_build_const_void(irb, block_node);
 
-    ir_gen_defers_for_block(irb, child_context, outer_block_context, false, false);
+    ir_gen_defers_for_block(irb, child_scope, outer_block_scope, false, false);
 
     return return_value;
 }
 
 static IrInstruction *ir_gen_bin_op_id(IrBuilder *irb, AstNode *node, IrBinOp op_id) {
-    IrInstruction *op1 = ir_gen_node(irb, node->data.bin_op_expr.op1, node->block_context);
-    IrInstruction *op2 = ir_gen_node(irb, node->data.bin_op_expr.op2, node->block_context);
+    IrInstruction *op1 = ir_gen_node(irb, node->data.bin_op_expr.op1, node->scope);
+    IrInstruction *op2 = ir_gen_node(irb, node->data.bin_op_expr.op2, node->scope);
     return ir_build_bin_op(irb, node, op_id, op1, op2);
 }
 
 static IrInstruction *ir_gen_assign(IrBuilder *irb, AstNode *node) {
-    IrInstruction *lvalue = ir_gen_node_extra(irb, node->data.bin_op_expr.op1, node->block_context, LValPurposeAssign);
+    IrInstruction *lvalue = ir_gen_node_extra(irb, node->data.bin_op_expr.op1, node->scope, LValPurposeAssign);
     if (lvalue == irb->codegen->invalid_instruction)
         return lvalue;
 
-    IrInstruction *rvalue = ir_gen_node(irb, node->data.bin_op_expr.op2, node->block_context);
+    IrInstruction *rvalue = ir_gen_node(irb, node->data.bin_op_expr.op2, node->scope);
     if (rvalue == irb->codegen->invalid_instruction)
         return rvalue;
 
@@ -1372,11 +1372,11 @@ static IrInstruction *ir_gen_assign(IrBuilder *irb, AstNode *node) {
 }
 
 static IrInstruction *ir_gen_assign_op(IrBuilder *irb, AstNode *node, IrBinOp op_id) {
-    IrInstruction *lvalue = ir_gen_node_extra(irb, node->data.bin_op_expr.op1, node->block_context, LValPurposeAssign);
+    IrInstruction *lvalue = ir_gen_node_extra(irb, node->data.bin_op_expr.op1, node->scope, LValPurposeAssign);
     if (lvalue == irb->codegen->invalid_instruction)
         return lvalue;
     IrInstruction *op1 = ir_build_load_ptr(irb, node->data.bin_op_expr.op1, lvalue);
-    IrInstruction *op2 = ir_gen_node(irb, node->data.bin_op_expr.op2, node->block_context);
+    IrInstruction *op2 = ir_gen_node(irb, node->data.bin_op_expr.op2, node->scope);
     if (op2 == irb->codegen->invalid_instruction)
         return op2;
     IrInstruction *result = ir_build_bin_op(irb, node, op_id, op1, op2);
@@ -1498,7 +1498,7 @@ static IrInstruction *ir_gen_null_literal(IrBuilder *irb, AstNode *node) {
 }
 
 static IrInstruction *ir_gen_decl_ref(IrBuilder *irb, AstNode *source_node, AstNode *decl_node,
-        LValPurpose lval, BlockContext *scope)
+        LValPurpose lval, Scope *scope)
 {
     resolve_top_level_decl(irb->codegen, decl_node, lval != LValPurposeNone);
     TopLevelDecl *tld = get_as_top_level_decl(decl_node);
@@ -1565,7 +1565,7 @@ static IrInstruction *ir_gen_symbol(IrBuilder *irb, AstNode *node, LValPurpose l
         }
     }
 
-    VariableTableEntry *var = find_variable(irb->codegen, node->block_context, variable_name);
+    VariableTableEntry *var = find_variable(irb->codegen, node->scope, variable_name);
     if (var) {
         IrInstruction *var_ptr = ir_build_var_ptr(irb, node, var);
         if (lval != LValPurposeNone)
@@ -1574,9 +1574,9 @@ static IrInstruction *ir_gen_symbol(IrBuilder *irb, AstNode *node, LValPurpose l
             return ir_build_load_ptr(irb, node, var_ptr);
     }
 
-    AstNode *decl_node = find_decl(node->block_context, variable_name);
+    AstNode *decl_node = find_decl(node->scope, variable_name);
     if (decl_node)
-        return ir_gen_decl_ref(irb, node, decl_node, lval, node->block_context);
+        return ir_gen_decl_ref(irb, node, decl_node, lval, node->scope);
 
     if (node->owner->any_imports_failed) {
         // skip the error message since we had a failing import in this file
@@ -1592,13 +1592,13 @@ static IrInstruction *ir_gen_array_access(IrBuilder *irb, AstNode *node, LValPur
     assert(node->type == NodeTypeArrayAccessExpr);
 
     AstNode *array_ref_node = node->data.array_access_expr.array_ref_expr;
-    IrInstruction *array_ref_instruction = ir_gen_node_extra(irb, array_ref_node, node->block_context,
+    IrInstruction *array_ref_instruction = ir_gen_node_extra(irb, array_ref_node, node->scope,
             LValPurposeAddressOf);
     if (array_ref_instruction == irb->codegen->invalid_instruction)
         return array_ref_instruction;
 
     AstNode *subscript_node = node->data.array_access_expr.subscript;
-    IrInstruction *subscript_instruction = ir_gen_node(irb, subscript_node, node->block_context);
+    IrInstruction *subscript_instruction = ir_gen_node(irb, subscript_node, node->scope);
     if (subscript_instruction == irb->codegen->invalid_instruction)
         return subscript_instruction;
 
@@ -1616,7 +1616,7 @@ static IrInstruction *ir_gen_field_access(IrBuilder *irb, AstNode *node, LValPur
     AstNode *container_ref_node = node->data.field_access_expr.struct_expr;
     Buf *field_name = node->data.field_access_expr.field_name;
 
-    IrInstruction *container_ref_instruction = ir_gen_node_extra(irb, container_ref_node, node->block_context,
+    IrInstruction *container_ref_instruction = ir_gen_node_extra(irb, container_ref_node, node->scope,
             LValPurposeAddressOf);
     if (container_ref_instruction == irb->codegen->invalid_instruction)
         return container_ref_instruction;
@@ -1661,7 +1661,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, AstNode *node) {
         case BuiltinFnIdTypeof:
             {
                 AstNode *arg_node = node->data.fn_call_expr.params.at(0);
-                IrInstruction *arg = ir_gen_node(irb, arg_node, node->block_context);
+                IrInstruction *arg = ir_gen_node(irb, arg_node, node->scope);
                 if (arg == irb->codegen->invalid_instruction)
                     return arg;
                 return ir_build_typeof(irb, node, arg);
@@ -1669,12 +1669,12 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, AstNode *node) {
         case BuiltinFnIdSetFnTest:
             {
                 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
-                IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, node->block_context);
+                IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, node->scope);
                 if (arg0_value == irb->codegen->invalid_instruction)
                     return arg0_value;
 
                 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
-                IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, node->block_context);
+                IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, node->scope);
                 if (arg1_value == irb->codegen->invalid_instruction)
                     return arg1_value;
 
@@ -1683,12 +1683,12 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, AstNode *node) {
         case BuiltinFnIdSetFnVisible:
             {
                 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
-                IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, node->block_context);
+                IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, node->scope);
                 if (arg0_value == irb->codegen->invalid_instruction)
                     return arg0_value;
 
                 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
-                IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, node->block_context);
+                IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, node->scope);
                 if (arg1_value == irb->codegen->invalid_instruction)
                     return arg1_value;
 
@@ -1697,12 +1697,12 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, AstNode *node) {
         case BuiltinFnIdSetDebugSafety:
             {
                 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
-                IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, node->block_context);
+                IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, node->scope);
                 if (arg0_value == irb->codegen->invalid_instruction)
                     return arg0_value;
 
                 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
-                IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, node->block_context);
+                IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, node->scope);
                 if (arg1_value == irb->codegen->invalid_instruction)
                     return arg1_value;
 
@@ -1711,7 +1711,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, AstNode *node) {
         case BuiltinFnIdCompileVar:
             {
                 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
-                IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, node->block_context);
+                IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, node->scope);
                 if (arg0_value == irb->codegen->invalid_instruction)
                     return arg0_value;
 
@@ -1720,7 +1720,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, AstNode *node) {
         case BuiltinFnIdSizeof:
             {
                 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
-                IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, node->block_context);
+                IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, node->scope);
                 if (arg0_value == irb->codegen->invalid_instruction)
                     return arg0_value;
 
@@ -1729,7 +1729,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, AstNode *node) {
         case BuiltinFnIdCtz:
             {
                 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
-                IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, node->block_context);
+                IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, node->scope);
                 if (arg0_value == irb->codegen->invalid_instruction)
                     return arg0_value;
 
@@ -1738,7 +1738,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, AstNode *node) {
         case BuiltinFnIdClz:
             {
                 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
-                IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, node->block_context);
+                IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, node->scope);
                 if (arg0_value == irb->codegen->invalid_instruction)
                     return arg0_value;
 
@@ -1747,7 +1747,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, AstNode *node) {
         case BuiltinFnIdStaticEval:
             {
                 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
-                IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, node->block_context);
+                IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, node->scope);
                 if (arg0_value == irb->codegen->invalid_instruction)
                     return arg0_value;
 
@@ -1756,11 +1756,11 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, AstNode *node) {
         case BuiltinFnIdImport:
             {
                 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
-                IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, node->block_context);
+                IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, node->scope);
                 if (arg0_value == irb->codegen->invalid_instruction)
                     return arg0_value;
 
-                if (node->block_context->fn_entry) {
+                if (node->scope->fn_entry) {
                     add_node_error(irb->codegen, node, buf_sprintf("import valid only at top level scope"));
                     return irb->codegen->invalid_instruction;
                 }
@@ -1805,7 +1805,7 @@ static IrInstruction *ir_gen_fn_call(IrBuilder *irb, AstNode *node) {
         return ir_gen_builtin_fn_call(irb, node);
 
     AstNode *fn_ref_node = node->data.fn_call_expr.fn_ref_expr;
-    IrInstruction *fn_ref = ir_gen_node(irb, fn_ref_node, node->block_context);
+    IrInstruction *fn_ref = ir_gen_node(irb, fn_ref_node, node->scope);
     if (fn_ref == irb->codegen->invalid_instruction)
         return fn_ref;
 
@@ -1813,7 +1813,7 @@ static IrInstruction *ir_gen_fn_call(IrBuilder *irb, AstNode *node) {
     IrInstruction **args = allocate<IrInstruction*>(arg_count);
     for (size_t i = 0; i < arg_count; i += 1) {
         AstNode *arg_node = node->data.fn_call_expr.params.at(i);
-        args[i] = ir_gen_node(irb, arg_node, node->block_context);
+        args[i] = ir_gen_node(irb, arg_node, node->scope);
     }
 
     return ir_build_call(irb, node, nullptr, fn_ref, arg_count, args);
@@ -1822,7 +1822,7 @@ static IrInstruction *ir_gen_fn_call(IrBuilder *irb, AstNode *node) {
 static IrInstruction *ir_gen_if_bool_expr(IrBuilder *irb, AstNode *node) {
     assert(node->type == NodeTypeIfBoolExpr);
 
-    IrInstruction *condition = ir_gen_node(irb, node->data.if_bool_expr.condition, node->block_context);
+    IrInstruction *condition = ir_gen_node(irb, node->data.if_bool_expr.condition, node->scope);
     if (condition == irb->codegen->invalid_instruction)
         return condition;
 
@@ -1837,7 +1837,7 @@ static IrInstruction *ir_gen_if_bool_expr(IrBuilder *irb, AstNode *node) {
     ir_build_cond_br(irb, condition->source_node, condition, then_block, else_block, is_inline);
 
     ir_set_cursor_at_end(irb, then_block);
-    IrInstruction *then_expr_result = ir_gen_node(irb, then_node, node->block_context);
+    IrInstruction *then_expr_result = ir_gen_node(irb, then_node, node->scope);
     if (then_expr_result == irb->codegen->invalid_instruction)
         return then_expr_result;
     IrBasicBlock *after_then_block = irb->current_basic_block;
@@ -1846,7 +1846,7 @@ static IrInstruction *ir_gen_if_bool_expr(IrBuilder *irb, AstNode *node) {
     ir_set_cursor_at_end(irb, else_block);
     IrInstruction *else_expr_result;
     if (else_node) {
-        else_expr_result = ir_gen_node(irb, else_node, node->block_context);
+        else_expr_result = ir_gen_node(irb, else_node, node->scope);
         if (else_expr_result == irb->codegen->invalid_instruction)
             return else_expr_result;
     } else {
@@ -1870,7 +1870,7 @@ static IrInstruction *ir_gen_prefix_op_id_lval(IrBuilder *irb, AstNode *node, Ir
     assert(node->type == NodeTypePrefixOpExpr);
     AstNode *expr_node = node->data.prefix_op_expr.primary_expr;
 
-    IrInstruction *value = ir_gen_node_extra(irb, expr_node, node->block_context, lval);
+    IrInstruction *value = ir_gen_node_extra(irb, expr_node, node->scope, lval);
     if (value == irb->codegen->invalid_instruction)
         return value;
 
@@ -1887,7 +1887,7 @@ static IrInstruction *ir_gen_prefix_op_id(IrBuilder *irb, AstNode *node, IrUnOp
 
 static IrInstruction *ir_gen_prefix_op_unwrap_maybe(IrBuilder *irb, AstNode *node, LValPurpose lval) {
     AstNode *expr = node->data.prefix_op_expr.primary_expr;
-    IrInstruction *value = ir_gen_node_extra(irb, expr, node->block_context, LValPurposeAddressOf);
+    IrInstruction *value = ir_gen_node_extra(irb, expr, node->scope, LValPurposeAddressOf);
     if (value == irb->codegen->invalid_instruction)
         return value;
 
@@ -1938,7 +1938,7 @@ static IrInstruction *ir_gen_container_init_expr(IrBuilder *irb, AstNode *node)
     AstNodeContainerInitExpr *container_init_expr = &node->data.container_init_expr;
     ContainerInitKind kind = container_init_expr->kind;
 
-    IrInstruction *container_type = ir_gen_node(irb, container_init_expr->type, node->block_context);
+    IrInstruction *container_type = ir_gen_node(irb, container_init_expr->type, node->scope);
     if (container_type == irb->codegen->invalid_instruction)
         return container_type;
 
@@ -1951,7 +1951,7 @@ static IrInstruction *ir_gen_container_init_expr(IrBuilder *irb, AstNode *node)
 
             Buf *name = entry_node->data.struct_val_field.name;
             AstNode *expr_node = entry_node->data.struct_val_field.expr;
-            IrInstruction *expr_value = ir_gen_node(irb, expr_node, node->block_context);
+            IrInstruction *expr_value = ir_gen_node(irb, expr_node, node->scope);
             if (expr_value == irb->codegen->invalid_instruction)
                 return expr_value;
 
@@ -1965,7 +1965,7 @@ static IrInstruction *ir_gen_container_init_expr(IrBuilder *irb, AstNode *node)
         IrInstruction **values = allocate<IrInstruction *>(item_count);
         for (size_t i = 0; i < item_count; i += 1) {
             AstNode *expr_node = container_init_expr->entries.at(i);
-            IrInstruction *expr_value = ir_gen_node(irb, expr_node, node->block_context);
+            IrInstruction *expr_value = ir_gen_node(irb, expr_node, node->scope);
             if (expr_value == irb->codegen->invalid_instruction)
                 return expr_value;
 
@@ -1984,14 +1984,14 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, AstNode *node) {
 
     IrInstruction *type_instruction;
     if (variable_declaration->type != nullptr) {
-        type_instruction = ir_gen_node(irb, variable_declaration->type, node->block_context);
+        type_instruction = ir_gen_node(irb, variable_declaration->type, node->scope);
         if (type_instruction == irb->codegen->invalid_instruction)
             return type_instruction;
     } else {
         type_instruction = nullptr;
     }
 
-    IrInstruction *init_value = ir_gen_node(irb, variable_declaration->expr, node->block_context);
+    IrInstruction *init_value = ir_gen_node(irb, variable_declaration->expr, node->scope);
     if (init_value == irb->codegen->invalid_instruction)
         return init_value;
 
@@ -1999,7 +1999,7 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, AstNode *node) {
     bool is_const = variable_declaration->is_const;
     bool is_extern = variable_declaration->is_extern;
     bool is_inline = ir_should_inline(irb) || variable_declaration->is_inline;
-    VariableTableEntry *var = ir_add_local_var(irb, node, node->block_context,
+    VariableTableEntry *var = ir_add_local_var(irb, node, node->scope,
             variable_declaration->symbol, is_const, is_const, is_shadowable, is_inline);
 
     if (!is_extern && !variable_declaration->expr) {
@@ -2027,19 +2027,19 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, AstNode *node) {
 
     if (continue_expr_node) {
         ir_set_cursor_at_end(irb, continue_block);
-        ir_gen_node(irb, continue_expr_node, node->block_context);
+        ir_gen_node(irb, continue_expr_node, node->scope);
         ir_build_br(irb, node, cond_block, is_inline);
     }
 
     ir_set_cursor_at_end(irb, cond_block);
-    IrInstruction *cond_val = ir_gen_node(irb, node->data.while_expr.condition, node->block_context);
+    IrInstruction *cond_val = ir_gen_node(irb, node->data.while_expr.condition, node->scope);
     ir_build_cond_br(irb, node->data.while_expr.condition, cond_val, body_block, end_block, is_inline);
 
     ir_set_cursor_at_end(irb, body_block);
 
     irb->break_block_stack.append(end_block);
     irb->continue_block_stack.append(continue_block);
-    ir_gen_node(irb, node->data.while_expr.body, node->block_context);
+    ir_gen_node(irb, node->data.while_expr.body, node->scope);
     irb->break_block_stack.pop();
     irb->continue_block_stack.pop();
 
@@ -2052,7 +2052,7 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, AstNode *node) {
 static IrInstruction *ir_gen_for_expr(IrBuilder *irb, AstNode *node) {
     assert(node->type == NodeTypeForExpr);
 
-    BlockContext *parent_scope = node->block_context;
+    Scope *parent_scope = node->scope;
 
     AstNode *array_node = node->data.for_expr.array_expr;
     AstNode *elem_node = node->data.for_expr.elem_node;
@@ -2079,9 +2079,9 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, AstNode *node) {
     }
     bool is_inline = ir_should_inline(irb) || node->data.for_expr.is_inline;
 
-    BlockContext *child_scope = new_block_context(node, parent_scope);
+    Scope *child_scope = new_scope(node, parent_scope);
     child_scope->parent_loop_node = node;
-    elem_node->block_context = child_scope;
+    elem_node->scope = child_scope;
 
     // TODO make it an error to write to element variable or i variable.
     Buf *elem_var_name = elem_node->data.symbol_expr.symbol;
@@ -2095,7 +2095,7 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, AstNode *node) {
     if (index_node) {
         index_var_source_node = index_node;
         Buf *index_var_name = index_node->data.symbol_expr.symbol;
-        index_node->block_context = child_scope;
+        index_node->scope = child_scope;
         node->data.for_expr.index_var = ir_add_local_var(irb, index_node, child_scope, index_var_name,
                 true, false, false, is_inline);
     } else {
@@ -2154,7 +2154,7 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, AstNode *node) {
 static IrInstruction *ir_gen_this_literal(IrBuilder *irb, AstNode *node) {
     assert(node->type == NodeTypeThisLiteral);
 
-    BlockContext *scope = node->block_context;
+    Scope *scope = node->scope;
 
     if (!scope->parent)
         return ir_build_const_import(irb, node, node->owner);
@@ -2205,18 +2205,18 @@ static IrInstruction *ir_gen_array_type(IrBuilder *irb, AstNode *node) {
             return irb->codegen->invalid_instruction;
         }
 
-        IrInstruction *size_value = ir_gen_node(irb, size_node, node->block_context);
+        IrInstruction *size_value = ir_gen_node(irb, size_node, node->scope);
         if (size_value == irb->codegen->invalid_instruction)
             return size_value;
 
-        IrInstruction *child_type = ir_gen_node(irb, child_type_node, node->block_context);
+        IrInstruction *child_type = ir_gen_node(irb, child_type_node, node->scope);
         if (child_type == irb->codegen->invalid_instruction)
             return child_type;
 
         return ir_build_array_type(irb, node, size_value, child_type);
     } else {
         IrInstruction *child_type = ir_gen_node_extra(irb, child_type_node,
-                node->block_context, LValPurposeAddressOf);
+                node->scope, LValPurposeAddressOf);
         if (child_type == irb->codegen->invalid_instruction)
             return child_type;
 
@@ -2246,7 +2246,7 @@ static IrInstruction *ir_gen_asm_expr(IrBuilder *irb, AstNode *node) {
         if (asm_output->return_type) {
             return_count += 1;
 
-            IrInstruction *return_type = ir_gen_node(irb, asm_output->return_type, node->block_context);
+            IrInstruction *return_type = ir_gen_node(irb, asm_output->return_type, node->scope);
             if (return_type == irb->codegen->invalid_instruction)
                 return irb->codegen->invalid_instruction;
             if (return_count > 1) {
@@ -2257,7 +2257,7 @@ static IrInstruction *ir_gen_asm_expr(IrBuilder *irb, AstNode *node) {
             output_types[i] = return_type;
         } else {
             Buf *variable_name = asm_output->variable_name;
-            VariableTableEntry *var = find_variable(irb->codegen, node->block_context, variable_name);
+            VariableTableEntry *var = find_variable(irb->codegen, node->scope, variable_name);
             if (var) {
                 asm_output->variable = var;
             } else {
@@ -2269,7 +2269,7 @@ static IrInstruction *ir_gen_asm_expr(IrBuilder *irb, AstNode *node) {
     }
     for (size_t i = 0; i < node->data.asm_expr.input_list.length; i += 1) {
         AsmInput *asm_input = node->data.asm_expr.input_list.at(i);
-        IrInstruction *input_value = ir_gen_node(irb, asm_input->expr, node->block_context);
+        IrInstruction *input_value = ir_gen_node(irb, asm_input->expr, node->scope);
         if (input_value == irb->codegen->invalid_instruction)
             return irb->codegen->invalid_instruction;
 
@@ -2288,7 +2288,7 @@ static IrInstruction *ir_gen_if_var_expr(IrBuilder *irb, AstNode *node) {
     AstNode *else_node = node->data.if_var_expr.else_node;
     bool var_is_ptr = node->data.if_var_expr.var_is_ptr;
 
-    IrInstruction *expr_value = ir_gen_node_extra(irb, expr_node, node->block_context, LValPurposeAddressOf);
+    IrInstruction *expr_value = ir_gen_node_extra(irb, expr_node, node->scope, LValPurposeAddressOf);
     if (expr_value == irb->codegen->invalid_instruction)
         return expr_value;
 
@@ -2304,11 +2304,11 @@ static IrInstruction *ir_gen_if_var_expr(IrBuilder *irb, AstNode *node) {
     ir_set_cursor_at_end(irb, then_block);
     IrInstruction *var_type = nullptr;
     if (var_decl->type) {
-        var_type = ir_gen_node(irb, var_decl->type, node->block_context);
+        var_type = ir_gen_node(irb, var_decl->type, node->scope);
         if (var_type == irb->codegen->invalid_instruction)
             return irb->codegen->invalid_instruction;
     }
-    BlockContext *child_scope = new_block_context(node, node->block_context);
+    Scope *child_scope = new_scope(node, node->scope);
     bool is_shadowable = false;
     bool is_const = var_decl->is_const;
     VariableTableEntry *var = ir_add_local_var(irb, node, child_scope,
@@ -2325,7 +2325,7 @@ static IrInstruction *ir_gen_if_var_expr(IrBuilder *irb, AstNode *node) {
     ir_set_cursor_at_end(irb, else_block);
     IrInstruction *else_expr_result;
     if (else_node) {
-        else_expr_result = ir_gen_node(irb, else_node, node->block_context);
+        else_expr_result = ir_gen_node(irb, else_node, node->scope);
         if (else_expr_result == irb->codegen->invalid_instruction)
             return else_expr_result;
     } else {
@@ -2354,13 +2354,13 @@ static bool ir_gen_switch_prong_expr(IrBuilder *irb, AstNode *switch_node, AstNo
 
     AstNode *expr_node = prong_node->data.switch_prong.expr;
     AstNode *var_symbol_node = prong_node->data.switch_prong.var_symbol;
-    BlockContext *child_scope;
+    Scope *child_scope;
     if (var_symbol_node) {
         assert(var_symbol_node->type == NodeTypeSymbol);
         Buf *var_name = var_symbol_node->data.symbol_expr.symbol;
         bool var_is_ptr = prong_node->data.switch_prong.var_is_ptr;
 
-        child_scope = new_block_context(switch_node, switch_node->block_context);
+        child_scope = new_scope(switch_node, switch_node->scope);
         bool is_shadowable = false;
         bool is_const = true;
         VariableTableEntry *var = ir_add_local_var(irb, var_symbol_node, child_scope,
@@ -2375,7 +2375,7 @@ static bool ir_gen_switch_prong_expr(IrBuilder *irb, AstNode *switch_node, AstNo
         IrInstruction *var_type = nullptr; // infer the type
         ir_build_var_decl(irb, var_symbol_node, var, var_type, var_value); 
     } else {
-        child_scope = switch_node->block_context;
+        child_scope = switch_node->scope;
     }
 
     IrInstruction *expr_result = ir_gen_node(irb, expr_node, child_scope);
@@ -2391,7 +2391,7 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, AstNode *node) {
     assert(node->type == NodeTypeSwitchExpr);
 
     AstNode *target_node = node->data.switch_expr.expr;
-    IrInstruction *target_value_ptr = ir_gen_node_extra(irb, target_node, node->block_context, LValPurposeAddressOf);
+    IrInstruction *target_value_ptr = ir_gen_node_extra(irb, target_node, node->scope, LValPurposeAddressOf);
     if (target_value_ptr == irb->codegen->invalid_instruction)
         return target_value_ptr;
     IrInstruction *target_value = ir_build_switch_target(irb, node, target_value_ptr);
@@ -2436,15 +2436,15 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, AstNode *node) {
                     AstNode *item_node = prong_node->data.switch_prong.items.at(item_i);
                     last_item_node = item_node;
                     if (item_node->type == NodeTypeSwitchRange) {
-                        item_node->block_context = node->block_context;
+                        item_node->scope = node->scope;
                         AstNode *start_node = item_node->data.switch_range.start;
                         AstNode *end_node = item_node->data.switch_range.end;
 
-                        IrInstruction *start_value = ir_gen_node(irb, start_node, node->block_context);
+                        IrInstruction *start_value = ir_gen_node(irb, start_node, node->scope);
                         if (start_value == irb->codegen->invalid_instruction)
                             return irb->codegen->invalid_instruction;
 
-                        IrInstruction *end_value = ir_gen_node(irb, end_node, node->block_context);
+                        IrInstruction *end_value = ir_gen_node(irb, end_node, node->scope);
                         if (end_value == irb->codegen->invalid_instruction)
                             return irb->codegen->invalid_instruction;
 
@@ -2463,7 +2463,7 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, AstNode *node) {
                             ok_bit = both_ok;
                         }
                     } else {
-                        IrInstruction *item_value = ir_gen_node(irb, item_node, node->block_context);
+                        IrInstruction *item_value = ir_gen_node(irb, item_node, node->scope);
                         if (item_value == irb->codegen->invalid_instruction)
                             return irb->codegen->invalid_instruction;
 
@@ -2500,7 +2500,7 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, AstNode *node) {
                     AstNode *item_node = prong_node->data.switch_prong.items.at(item_i);
                     assert(item_node->type != NodeTypeSwitchRange);
 
-                    IrInstruction *item_value = ir_gen_node(irb, item_node, node->block_context);
+                    IrInstruction *item_value = ir_gen_node(irb, item_node, node->scope);
                     if (item_value == irb->codegen->invalid_instruction)
                         return irb->codegen->invalid_instruction;
 
@@ -2542,8 +2542,8 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, AstNode *node) {
     return ir_build_phi(irb, node, incoming_blocks.length, incoming_blocks.items, incoming_values.items);
 }
 
-static LabelTableEntry *find_label(IrExecutable *exec, BlockContext *orig_context, Buf *name) {
-    BlockContext *context = orig_context;
+static LabelTableEntry *find_label(IrExecutable *exec, Scope *orig_context, Buf *name) {
+    Scope *context = orig_context;
     while (context) {
         auto entry = context->label_table.maybe_get(name);
         if (entry) {
@@ -2564,14 +2564,14 @@ static IrInstruction *ir_gen_label(IrBuilder *irb, AstNode *node) {
     label->bb = label_block;
     irb->exec->all_labels.append(label);
 
-    LabelTableEntry *existing_label = find_label(irb->exec, node->block_context, label_name);
+    LabelTableEntry *existing_label = find_label(irb->exec, node->scope, label_name);
     if (existing_label) {
         ErrorMsg *msg = add_node_error(irb->codegen, node,
             buf_sprintf("duplicate label name '%s'", buf_ptr(label_name)));
         add_error_note(irb->codegen, msg, existing_label->decl_node, buf_sprintf("other label here"));
         return irb->codegen->invalid_instruction;
     } else {
-        node->block_context->label_table.put(label_name, label);
+        node->scope->label_table.put(label_name, label);
     }
 
     bool is_inline = ir_should_inline(irb);
@@ -2607,11 +2607,11 @@ static IrInstruction *ir_gen_type_literal(IrBuilder *irb, AstNode *node) {
     return ir_build_const_type(irb, node, irb->codegen->builtin_types.entry_type);
 }
 
-static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, BlockContext *block_context,
+static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scope,
         LValPurpose lval)
 {
-    assert(block_context);
-    node->block_context = block_context;
+    assert(scope);
+    node->scope = scope;
 
     switch (node->type) {
         case NodeTypeStructValueField:
@@ -2694,15 +2694,15 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, BlockContex
     zig_unreachable();
 }
 
-static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, BlockContext *block_context,
+static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, Scope *scope,
         LValPurpose lval)
 {
-    IrInstruction *result = ir_gen_node_raw(irb, node, block_context, lval);
+    IrInstruction *result = ir_gen_node_raw(irb, node, scope, lval);
     irb->exec->invalid = irb->exec->invalid || (result == irb->codegen->invalid_instruction);
     return result;
 }
 
-static IrInstruction *ir_gen_node(IrBuilder *irb, AstNode *node, BlockContext *scope) {
+static IrInstruction *ir_gen_node(IrBuilder *irb, AstNode *node, Scope *scope) {
     return ir_gen_node_extra(irb, node, scope, LValPurposeNone);
 }
 
@@ -2714,7 +2714,7 @@ static bool ir_goto_pass2(IrBuilder *irb) {
         IrInstruction *old_instruction = *slot;
 
         Buf *label_name = goto_node->data.goto_expr.name;
-        LabelTableEntry *label = find_label(irb->exec, goto_node->block_context, label_name);
+        LabelTableEntry *label = find_label(irb->exec, goto_node->scope, label_name);
         if (!label) {
             add_node_error(irb->codegen, goto_node,
                 buf_sprintf("no label in scope named '%s'", buf_ptr(label_name)));
@@ -2741,7 +2741,7 @@ static bool ir_goto_pass2(IrBuilder *irb) {
     return true;
 }
 
-IrInstruction *ir_gen(CodeGen *codegen, AstNode *node, BlockContext *scope, IrExecutable *ir_executable) {
+IrInstruction *ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_executable) {
     assert(node->owner);
 
     IrBuilder ir_builder = {0};
@@ -2778,7 +2778,7 @@ IrInstruction *ir_gen_fn(CodeGen *codegn, FnTableEntry *fn_entry) {
     assert(fn_def_node->type == NodeTypeFnDef);
 
     AstNode *body_node = fn_def_node->data.fn_def.body;
-    BlockContext *scope = fn_def_node->data.fn_def.block_context;
+    Scope *scope = fn_def_node->data.fn_def.scope;
 
     return ir_gen(codegn, body_node, scope, ir_executable);
 }
@@ -3023,8 +3023,8 @@ static IrInstruction *ir_resolve_cast(IrAnalyze *ira, IrInstruction *source_inst
     } else {
         IrInstruction *result = ir_build_cast(&ira->new_irb, source_instr->source_node, wanted_type, value, cast_op);
         result->type_entry = wanted_type;
-        if (need_alloca && source_instr->source_node->block_context->fn_entry) {
-            source_instr->source_node->block_context->fn_entry->alloca_list.append(result);
+        if (need_alloca && source_instr->source_node->scope->fn_entry) {
+            source_instr->source_node->scope->fn_entry->alloca_list.append(result);
         }
         return result;
     }
@@ -3550,7 +3550,7 @@ static TypeTableEntry *ir_analyze_ref(IrAnalyze *ira, IrInstruction *source_inst
         ir_link_new_instruction(value, source_instruction);
         return ptr_type;
     } else {
-        FnTableEntry *fn_entry = source_instruction->source_node->block_context->fn_entry;
+        FnTableEntry *fn_entry = source_instruction->source_node->scope->fn_entry;
         IrInstruction *new_instruction = ir_build_ref_from(&ira->new_irb, source_instruction, value);
         fn_entry->alloca_list.append(new_instruction);
         return ptr_type;
@@ -4097,7 +4097,7 @@ static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstruc
 
     ir_build_var_decl_from(&ira->new_irb, &decl_var_instruction->base, var, var_type, casted_init_value);
 
-    BlockContext *scope = decl_var_instruction->base.source_node->block_context;
+    Scope *scope = decl_var_instruction->base.source_node->scope;
     if (scope->fn_entry)
         scope->fn_entry->variable_list.append(var);
 
@@ -4201,7 +4201,7 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal
             fn_entry, fn_ref, call_param_count, casted_args);
 
     if (type_has_bits(return_type) && handle_is_ptr(return_type))
-        call_instruction->base.source_node->block_context->fn_entry->alloca_list.append(new_call_instruction);
+        call_instruction->base.source_node->scope->fn_entry->alloca_list.append(new_call_instruction);
 
     return ir_finish_anal(ira, return_type);
 }
@@ -4732,7 +4732,7 @@ static TypeTableEntry *ir_analyze_var_ptr(IrAnalyze *ira, IrInstruction *instruc
         return var->type;
 
     ConstExprValue *mem_slot = nullptr;
-    if (var->block_context->fn_entry) {
+    if (var->scope->fn_entry) {
         // TODO once the analyze code is fully ported over to IR we won't need this SIZE_MAX thing.
         if (var->mem_slot_index != SIZE_MAX)
             mem_slot = &ira->exec_context.mem_slot_list[var->mem_slot_index];
@@ -4879,7 +4879,7 @@ static TypeTableEntry *ir_analyze_container_member_access_inner(IrAnalyze *ira,
     IrInstruction *container_ptr, TypeTableEntry *container_type)
 {
     if (!is_slice(bare_struct_type)) {
-        BlockContext *container_block_context = get_container_block_context(bare_struct_type);
+        Scope *container_block_context = get_container_block_context(bare_struct_type);
         assert(container_block_context);
         auto entry = container_block_context->decl_table.maybe_get(field_name);
         AstNode *fn_decl_node = entry ? entry->value : nullptr;
@@ -5023,7 +5023,7 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru
         } else if (child_type->id == TypeTableEntryIdEnum) {
             zig_panic("TODO enum type field");
         } else if (child_type->id == TypeTableEntryIdStruct) {
-            BlockContext *container_block_context = get_container_block_context(child_type);
+            Scope *container_block_context = get_container_block_context(child_type);
             auto entry = container_block_context->decl_table.maybe_get(field_name);
             AstNode *decl_node = entry ? entry->value : nullptr;
             if (decl_node) {
@@ -5055,7 +5055,7 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru
         ImportTableEntry *namespace_import = namespace_val->data.x_import;
 
         bool depends_on_compile_var = container_ptr->static_value.depends_on_compile_var;
-        AstNode *decl_node = find_decl(namespace_import->block_context, field_name);
+        AstNode *decl_node = find_decl(namespace_import->scope, field_name);
         if (!decl_node) {
             // we must now resolve all the use decls
             for (size_t i = 0; i < namespace_import->use_decls.length; i += 1) {
@@ -5066,7 +5066,7 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru
                 }
                 resolve_use_decl(ira->codegen, use_decl_node);
             }
-            decl_node = find_decl(namespace_import->block_context, field_name);
+            decl_node = find_decl(namespace_import->scope, field_name);
         }
         if (decl_node) {
             TopLevelDecl *tld = get_as_top_level_decl(decl_node);
@@ -5323,19 +5323,19 @@ static TypeTableEntry *ir_analyze_instruction_set_debug_safety(IrAnalyze *ira,
     if (!target_val)
         return ira->codegen->builtin_types.entry_invalid;
 
-    BlockContext *target_context;
+    Scope *target_context;
     if (target_type->id == TypeTableEntryIdBlock) {
         target_context = target_val->data.x_block;
     } else if (target_type->id == TypeTableEntryIdFn) {
-        target_context = target_val->data.x_fn->fn_def_node->data.fn_def.block_context;
+        target_context = target_val->data.x_fn->fn_def_node->data.fn_def.scope;
     } else if (target_type->id == TypeTableEntryIdMetaType) {
         TypeTableEntry *type_arg = target_val->data.x_type;
         if (type_arg->id == TypeTableEntryIdStruct) {
-            target_context = type_arg->data.structure.block_context;
+            target_context = type_arg->data.structure.scope;
         } else if (type_arg->id == TypeTableEntryIdEnum) {
-            target_context = type_arg->data.enumeration.block_context;
+            target_context = type_arg->data.enumeration.scope;
         } else if (type_arg->id == TypeTableEntryIdUnion) {
-            target_context = type_arg->data.unionation.block_context;
+            target_context = type_arg->data.unionation.scope;
         } else {
             add_node_error(ira->codegen, target_instruction->source_node,
                 buf_sprintf("expected scope reference, found type '%s'", buf_ptr(&type_arg->name)));
@@ -5966,7 +5966,7 @@ static TypeTableEntry *ir_analyze_instruction_import(IrAnalyze *ira, IrInstructi
     ImportTableEntry *target_import = add_source_file(ira->codegen, target_package,
             abs_full_path, search_dir, import_target_path, import_code);
 
-    scan_decls(ira->codegen, target_import, target_import->block_context, target_import->root);
+    scan_decls(ira->codegen, target_import, target_import->scope, target_import->root);
 
     ConstExprValue *out_val = ir_build_const_from(ira, &import_instruction->base, depends_on_compile_var);
     out_val->data.x_import = target_import;
@@ -6021,7 +6021,7 @@ static TypeTableEntry *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstru
 
     IrInstructionStructInitField *new_fields = allocate<IrInstructionStructInitField>(actual_field_count);
 
-    FnTableEntry *fn_entry = instruction->source_node->block_context->fn_entry;
+    FnTableEntry *fn_entry = instruction->source_node->scope->fn_entry;
     bool outside_fn = (fn_entry == nullptr);
 
     ConstExprValue const_val = {};
@@ -6124,7 +6124,7 @@ static TypeTableEntry *ir_analyze_instruction_container_init_list(IrAnalyze *ira
         const_val.data.x_array.elements = allocate<ConstExprValue>(elem_count);
         const_val.data.x_array.size = elem_count;
 
-        FnTableEntry *fn_entry = instruction->base.source_node->block_context->fn_entry;
+        FnTableEntry *fn_entry = instruction->base.source_node->scope->fn_entry;
         bool outside_fn = (fn_entry == nullptr);
 
         IrInstruction **new_items = allocate<IrInstruction *>(elem_count);
src/ir.hpp
@@ -10,7 +10,7 @@
 
 #include "all_types.hpp"
 
-IrInstruction *ir_gen(CodeGen *g, AstNode *node, BlockContext *scope, IrExecutable *ir_executable);
+IrInstruction *ir_gen(CodeGen *g, AstNode *node, Scope *scope, IrExecutable *ir_executable);
 IrInstruction *ir_gen_fn(CodeGen *g, FnTableEntry *fn_entry);
 
 TypeTableEntry *ir_analyze(CodeGen *g, IrExecutable *old_executable, IrExecutable *new_executable,
src/parseh.cpp
@@ -817,7 +817,7 @@ static TypeTableEntry *resolve_enum_decl(Context *c, const EnumDecl *enum_decl)
     const EnumDecl *enum_def = enum_decl->getDefinition();
     if (!enum_def) {
         TypeTableEntry *enum_type = get_partial_container_type(c->codegen, c->import,
-                c->import->block_context,
+                c->import->scope,
                 ContainerKindEnum, c->source_node, buf_ptr(full_type_name));
         c->enum_type_table.put(bare_name, enum_type);
         c->decl_table.put(enum_decl, enum_type);
@@ -842,7 +842,7 @@ static TypeTableEntry *resolve_enum_decl(Context *c, const EnumDecl *enum_decl)
 
     if (pure_enum) {
         TypeTableEntry *enum_type = get_partial_container_type(c->codegen, c->import,
-                c->import->block_context,
+                c->import->scope,
                 ContainerKindEnum, c->source_node, buf_ptr(full_type_name));
         c->enum_type_table.put(bare_name, enum_type);
         c->decl_table.put(enum_decl, enum_type);
@@ -1002,7 +1002,7 @@ static TypeTableEntry *resolve_record_decl(Context *c, const RecordDecl *record_
 
 
     TypeTableEntry *struct_type = get_partial_container_type(c->codegen, c->import,
-            c->import->block_context, ContainerKindStruct, c->source_node, buf_ptr(full_type_name));
+            c->import->scope, ContainerKindStruct, c->source_node, buf_ptr(full_type_name));
 
     c->struct_type_table.put(bare_name, struct_type);
     c->decl_table.put(record_decl, struct_type);