diff --git a/src/ir.cpp b/src/ir.cpp index bc16cef56114..50b34faa4339 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -20247,6 +20247,21 @@ static IrInstruction *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstruc buf_ptr(&container_type->name))); return ira->codegen->invalid_instruction; } + } else if (container_type->id == ZigTypeIdVector) { + if (buf_eql_str(field_name, "len")) { + bool ptr_is_const = true; + bool ptr_is_volatile = false; + return ir_get_const_ptr(ira, &field_ptr_instruction->base, + create_const_unsigned_negative(ira->codegen->builtin_types.entry_num_lit_int, + container_type->data.vector.len, false), + ira->codegen->builtin_types.entry_num_lit_int, + ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); + } else { + ir_add_error(ira, &field_ptr_instruction->base, + buf_sprintf("type '%s' has no member called '%s'", + buf_ptr(&container_type->name), buf_ptr(field_name))); + return ira->codegen->invalid_instruction; + } } else if (container_type->id == ZigTypeIdMetaType) { ZigValue *container_ptr_val = ir_resolve_const(ira, container_ptr, UndefBad); if (!container_ptr_val) @@ -20263,9 +20278,24 @@ static IrInstruction *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstruc } ZigType *child_type = child_val->data.x_type; - if (type_is_invalid(child_type)) { + if (type_is_invalid(child_type)) return ira->codegen->invalid_instruction; - } else if (is_container(child_type)) { + + if (child_type->id == ZigTypeIdVector) { + if (buf_eql_str(field_name, "len")) { + bool ptr_is_const = true; + bool ptr_is_volatile = false; + return ir_get_const_ptr(ira, &field_ptr_instruction->base, + create_const_unsigned_negative(ira->codegen->builtin_types.entry_num_lit_int, + child_type->data.vector.len, false), + ira->codegen->builtin_types.entry_num_lit_int, + ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); + } + child_type = child_type->data.vector.elem_type; + // Fall through for field access of vector element meta types + } + + if (is_container(child_type)) { if (child_type->id == ZigTypeIdEnum) { if ((err = type_resolve(ira->codegen, child_type, ResolveStatusSizeKnown))) return ira->codegen->invalid_instruction; diff --git a/test/stage1/behavior/vector.zig b/test/stage1/behavior/vector.zig index 338f24d8062b..cadea3f35d13 100644 --- a/test/stage1/behavior/vector.zig +++ b/test/stage1/behavior/vector.zig @@ -250,3 +250,29 @@ test "initialize vector which is a struct field" { S.doTheTest(); comptime S.doTheTest(); } + +test "vector member field access" { + const S = struct { + fn doTheTest() void { + const q: @Vector(4, u32) = undefined; + expect(q.len == 4); + const v = @Vector(4, i32); + expect(v.len == 4); + expect(v.bit_count == 32); + expect(v.is_signed == true); + const k = @Vector(2, bool); + expect(k.len == 2); + const x = @Vector(3, f32); + expect(x.len == 3); + expect(x.bit_count == 32); + const z = @Vector(3, *align(4) u32); + expect(z.len == 3); + expect(z.Child == u32); + // FIXME is this confusing? However vector alignment requirements are entirely + // dependant on their size, and can be gotten with @alignOf(). + expect(z.alignment == 4); + } + }; + S.doTheTest(); + comptime S.doTheTest(); +} \ No newline at end of file