Skip to content

RLS for bitwise not operator ~ #25497

@silversquirl

Description

@silversquirl

This is a proposal to have the ~ operator propagate its result type to its operand.
My main motivation for proposing this is the following footgun:

const MyStruct = struct {
    x: u32,
};

// somewhere far away
const foo: MyStruct = .{ .x = ~@as(u32, 0) };
std.debug.assert(~foo.x == 0);

If the type of the x field is changed to u64, the assert will begin failing. In many cases, there is no such assert, and instead the code silently breaks in ways that may be difficult to detect.
Currently, to reliably get the desired behaviour, one must write code like this:

const foo: MyStruct = .{ .x = ~@as(@FieldType(MyStruct, "x"), 0) };

Which is pretty difficult to read. With the proposed change, the snippet could be written like this instead:

const foo: MyStruct = .{ .x = ~0 };

Breaking

This is unfortunately a breaking change, as illustrated by this example:

const x: u8 = 0;
const y: u16 = ~x;
// prior to this change, y == 0x00ff
// after this change, y == 0xffff

I personally think both of these behaviours are equally confusing, but at least with the proposed change you have all the type information you need in one place, and don't have to go look at the type of x.

Metadata

Metadata

Assignees

No one assigned

    Labels

    breakingImplementing this issue could cause existing code to no longer compile or have different behavior.proposalThis issue suggests modifications. If it also has the "accepted" label then it is planned.

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions