Re: [PATCH 1/3] scripts/qapi: enum with conditional first item must be optional

Paolo Bonzini <[email protected]>
Newsgroups org.nongnu.qemu-devel
Message-ID <CABgObfbOVY5mpyhxQHOCvVDZkOHgTK=SmJ-gQ3A6_4Ywhhew_Q@mail.gmail.com>
On Thu, Aug 6, 2026 at 9:01 AM Markus Armbruster <[email protected]> wrote:
> >                Qcow2CompressionType could grow one in case zlib option
> > becomes mandatory.
>
> Do you mean "becomes optional?"
>
> Note that @zlib can't become optional without a compatibility break,
> because @compression-type defaults to it in BlockdevCreateOptionsQcow2.
>
> Moreover, Qcow2CompressionType needs members, because @compression-type
> is mandatory in ImageInfoSpecificQCow2.
>
> [...]
>
> > BlockExportType is the most potentially problematic, because it does
> > not make sense to have 'none' there.
>
> BlockExportType also needs members, because BlockExportOptions and
> BlockExportInfo have a mandatory member @type of BlockExportType.

That would only mean you can't construct a valid one; but it would be
dead code, not an error.

> Joking aside, I wouldn't call it a feature, because "feature" implies
> "good for something".  "Bug" implies "has some undesirable effect".  If
> we volunteer for the mission "don't let the programmer specify useless
> interfaces", then this is a bug.  If we go "you're asking for rope, have
> some" instead, it's not.

There's some advantage in avoiding #ifdefs of this kind:

#if defined CONFIG_FOO1 || defined CONFIG_FOO2 || defined CONFIG_FOO3
#define CONFIG_FOO_AVAILABLE
#endif

and let other stuff compile; sometimes even if you cannot rely on dead
code elimination of some sort (which could be *another* language
problem).

But as you said, this was indeed a bit of an excursion into the weeds.

> >> * Forbid empty enums [PATCH 2].  They are allowed simply because I never
> >>   found a compelling reason to forbid them.  Yes, they're useless, but
> >>   users can figure that out without the QAPI generator insisting.
> >>
> >>   Does forbidding them help Rust?
> >
> > Somewhat; I cannot generate Default::default() for them.  It would be
> > easy enough to skip generation of that method, but you'd still get a
> > Rust compilation error if you put them in a struct.
> >
> > IMO this is telling us that empty enums should indeed fail to compile
> > even earlier, in the QAPI schema generator.
> >
> > Empty enum types cannot be created, and neither can any structs or
> > commands they contain.  There's simply no way to have code that refers
> > to them, unless they're wrapped in something else that lets the code
> > pretend they can exist: for example you can make a field optional and
> > write "None" for it.
> >
> > With conditionally empty enums, this at least makes sense as a concept; on the other hand I just don't see the point in unconditionally empty enums, even if they're optional, so I left them out.
>
> If forbidding empty enums makes Rust generation simpler or easier,
> that's a compelling reason, isn't it?
>
> You should mention the Rust reason(s) in the commit message then.

Rust can live with it.  I'm just taking a clue from the language.

> I might have banned conditional first members from the start if I had
> thought out things back then.

Ok, then let's do it.

Paolo
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.