Skip to content

Compiler error using array concatenation with inferred types #4417

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
jeffkdev opened this issue Feb 9, 2020 · 4 comments
Closed

Compiler error using array concatenation with inferred types #4417

jeffkdev opened this issue Feb 9, 2020 · 4 comments
Labels
bug Observed behavior contradicts documented or intended behavior stage1 The process of building from source via WebAssembly and the C backend.
Milestone

Comments

@jeffkdev
Copy link

jeffkdev commented Feb 9, 2020

Minimal test. Printed error: assertion failed. This is a bug in the Zig compiler.

pub fn main() void {
    const works: [4]f32 = .{1,2,3,4};
    const compiler_bug: [4]f32 = .{1,2} ++ .{3,4};
}

I am not 100% sure if the second line is supposed to be compilable, but minimally needs some sort of compiler error.

But assuming the compiler_bug line is correct, then below I added some slightly more complex test cases that would make sense if they worked as well:

const StructWithDefault = struct {
    value: f32 = 42,
};
const SomeStruct = struct {
    array: [4]StructWithDefault,
};

pub fn main() void {
    // Ok #1: Array element type inferred
    const value0 = SomeStruct{ .array = [_]StructWithDefault{.{}} ++ [_]StructWithDefault{undefined} ** 3 };
    // Ok #2: Array type inferred from defined elements
    const value1 = SomeStruct{ .array = .{ StructWithDefault{}, StructWithDefault{}, StructWithDefault{}, StructWithDefault{} } };
    // Ok #3: Array type and element type inferred
    const value2 = SomeStruct{ .array = .{ .{}, .{}, .{}, .{} } };
    // error #1: error: expected array, found 'struct:14:4'2 (Define element type, remove array type definition)
    const value3 = SomeStruct{ .array = .{StructWithDefault{}} ++ [_]StructWithDefault{undefined} ** 3 };
    // error #2: error: expected array, found 'struct:16:42' (Remove element type and array type in first arg)
    const value4 = SomeStruct{ .array = .{.{}} ++ [_]StructWithDefault{undefined} ** 3 };
    // error #3: error: expected array, found 'struct:18:52' (Remove element type and array type in both args)
    const value5 = SomeStruct{ .array = .{.{}} ++ .{undefined} ** 3 };
    // error #4: assertion failed. This is a bug in the Zig compiler.
    const value6 = SomeStruct{ .array = .{ .{}, .{}, } ++ .{.{}, .{} }} ;
}

My actual use case involves serializing an inline array (fixed max length, variable number of elements)
to zig code where I only want to define the elements that are actually populated and leave the rest undefined. Explicitly defining the array type like in Ok #1 let me workaround this for now.

0.5.0+b55bc5e

@LemonBoy
Copy link
Contributor

LemonBoy commented Feb 9, 2020

Duplicate of #3979!

@jeffkdev
Copy link
Author

jeffkdev commented Feb 9, 2020

Thanks. Closing this one. Will add the more complex test case to the original.

@jeffkdev
Copy link
Author

This was initially closed as a duplicate, but #3979 didn't fix all the cases above this when it was closed. I didn't find another open issue that covered these.

Shorter example with just the lines that aren't working:

const StructWithDefault = struct {
    value: f32 = 42,
};
const SomeStruct = struct {
    array: [4]StructWithDefault,
};

pub fn main() void {
    // error #1
    const value3 = SomeStruct{ .array = .{StructWithDefault{}} ++ [_]StructWithDefault{undefined} ** 3 };
    // error #2
    const value4 = SomeStruct{ .array = .{.{}} ++ [_]StructWithDefault{undefined} ** 3 };
}

error 1

.\test.zig:10:42: error: expected array, found 'struct:10:42'
    const value3 = SomeStruct{ .array = .{StructWithDefault{}} ++ [_]StructWithDefault{undefined} ** 3 };
                                         ^
.\test.zig:10:64: note: referenced here
    const value3 = SomeStruct{ .array = .{StructWithDefault{}} ++ [_]StructWithDefault{undefined} ** 3 };

error 2

.\test.zig:12:42: error: expected array, found 'struct:12:42'
    const value4 = SomeStruct{ .array = .{.{}} ++ [_]StructWithDefault{undefined} ** 3 };
                                         ^
.\test.zig:12:48: note: referenced here
    const value4 = SomeStruct{ .array = .{.{}} ++ [_]StructWithDefault{undefined} ** 3 };
                                               ^

Both errors can be worked around by adding the array type first: .array = [_]StructWithDefault.

Zig version: 0.9.0-dev.70+a3f7a48d9

@jeffkdev jeffkdev reopened this Jun 15, 2021
@nektro
Copy link
Contributor

nektro commented Jul 14, 2021

not sure if this is in scope for type inference

@Vexu Vexu added bug Observed behavior contradicts documented or intended behavior stage1 The process of building from source via WebAssembly and the C backend. labels Aug 6, 2021
@Vexu Vexu added this to the 0.10.0 milestone Aug 6, 2021
Vexu added a commit to Vexu/zig that referenced this issue Dec 31, 2022
Vexu added a commit to Vexu/zig that referenced this issue Dec 31, 2022
@andrewrk andrewrk modified the milestones: 0.12.0, 0.11.0 Jan 1, 2023
TUSF pushed a commit to TUSF/zig that referenced this issue May 9, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Observed behavior contradicts documented or intended behavior stage1 The process of building from source via WebAssembly and the C backend.
Projects
None yet
Development

No branches or pull requests

5 participants