Feature request: auto-infer the type when pushing to an array of structs

Given a struct like this:

struct Set {
    uint256 x;
    uint256 y;
    uint256 expected;
}

It is possible to initialize an instance using a key-value mapping, like this:

Set mySet = Set({ x: 1, y: 2, expected: 3 });

Which is really nice.

Now, suppose that you have an array of structs, defined in the storage of a contract:

contract Foo {
    Set[] internal sets;
}

To append an element to the array, we can do this:

sets.push(Set({ x: 1, y: 2, expected: 3 }));

Here’s my feature request - what if you could do the above without the Set(...) wrapper? What if you could instead write it like this:

sets.push({ x: 1, y: 2, expected: 3 });

The compiler should be able to parse the {} object, since the compiler knows the type of the array items (always Set).

The main advantage of enabling this would be enhanced readability (due to fewer parantheses).

4 Likes

Personally am in favour of anything that reduces verbosity, this is fairly bread and butter in most languages I am aware of!

1 Like

I like the idea and it would be pretty convenient. So this would basically be inline struct syntax analogous to inline arrays we have already. I’m not sure if it makes sense to introduce something like this in isolation though.

Currently we have virtually no type inference based on context. The type is determined by the expression itself, which is why for example you cannot assign [1, 2, 3] to uint[3] (the type of the literal is uint8[3]). Similarly you cannot assign an overloaded function to a function pointer, even though the compiler should theoretically be able choose the right overload based on how it’s used.

And I guess implicit conversions are a valid alternative here. For example in the PR implementing dynamic inline arrays we’re adding an implicit conversion between string and bytes literals in inline arrays to make things smoother.

Still, we’ll need some type inference to make generics usable in practice so that’s on the table. But it needs to be considered with that feature in mind.

Another stumbling block we hit with inline arrays is that the generated code is horribly inefficient and the optimizer is not yet good enough at making it neater. The workaround are artificial limits on how big the literals can be. I think that adding struct literals to the mix might make this worse - unless implemented in a very simplistic way, basically as a “macro” expansion into struct constructor call.

All in all, this is definitely worth considering as a part of the language in some form. There are obstacles in the short term but ultimately they should be solvable.

1 Like

Thanks for considering this!

On second thoughts, I agree with you. If you do introduce this feature, it would make most sense to enable in all cases, not just for pushing to arrays.