Skip to content

std.fmt: disallow implicitly formatting optional and error values #11753

@ghost

Description

On Discord we've discussed and agreed to that it is currently too easy to accidentally pass an optional value (?T) to a format specifier like {s}. It is a real footgun and reminds me a lot to undefined that you can find on JavaScript websites in many places because the developer forgot to handle it. We don't want Zig to be like that. It shouldn't happily print null like that.

@InKryption had the idea of only allowing an optional type to be formatted if there is ? before the specifier type, so for {s} it would be {?s}.

Then @MasterQ32 asked about error unions and I proposed for example {!?s} to format anyerror!?[]const u8. I think this syntax looks really neat and it's consistent with the way the types look.

Here's what cipharius had to say:

That would be definitely more intuitive, as I previously also expected a type error, since in other contexts Zig is pretty strict about type inference.

So the proposal is to change std.fmt formatting such that in a format string

  • {t} can only format T,
  • {?t} can only format ?T (and T as that coerces to it),
  • {!?t} can only format anyerror!?T.

where t is the respective specifier type. This affects all specifier types except for any which will retain current behavior.

CC @InKryption @viriuwu @MasterQ32

Metadata

Metadata

Assignees

No one assigned

    Labels

    breakingImplementing this issue could cause existing code to no longer compile or have different behavior.enhancementSolving this issue will likely involve adding new logic or components to the codebase.standard libraryThis issue involves writing Zig code for the standard library.

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions