Annoying deprecation messages when using EnumMembers with enum that has deprecated members

Jonathan M Davis newsgroup.d at
Tue Oct 8 16:03:20 UTC 2019

On Tuesday, October 8, 2019 5:50:48 AM MDT FeepingCreature via Digitalmars-d 
> On Tuesday, 8 October 2019 at 10:06:18 UTC, Jonathan M Davis
> wrote:
> > A related issue is the -de flag, which arguably is really bad
> > in that it makes it so that is expressions and
> > __traits(compiles, ...) expressions have a different result
> > depending on whether -de is used or not, because -de turns
> > deprecation messages into errors. Meaning that code that
> > compiled just fine before the deprecation may not compile
> > anymore, or it may compile with different behavior.
> I'm gonna argue this :) -de makes sense if one interprets it as
> "generate the code that would result if all deprecated symbols
> were removed." Of course this doesn't quite work right with stuff
> like final switch and enums... but it works with pretty much
> everything else. (?)
> Should __traits(allMembers) ignore deprecated enum members with
> -de? Under this interpretation, it seems that it should.
> And regarding expressions having a different result, well, yes,
> just like they'll have when the deprecated symbol is removed. :)

-de is for those who want to force code in a code base to be updated when a
deprecation message pops up instead of letting it be fixed later. It does
not do exactly the same thing as having the deprecated symbol removed, since
the symbol still exists and still affects stuff like overloading and type
introspection. Yes, an expression which tests whether a piece of code
compiles or not which uses the deprecated symbol will then fail to compile
similar to what it would do once the symbol has been removed, but you could
still get subtle differences like a piece of code that doesn't compile
because of a conflicting symbol which then compiles fine once the deprecated
symbol has actually been removed. So, I'd advise against using -de to see
what the code would do once the symbol was removed. The effect will be
similar, but it won't be the same, and depending on the code involved, the
difference could matter.

All in all though, -de has a lot of the same problems that -w does. Whenever
a compiler flag can change what is and isn't an error, there are going to be
subtle problems - especially when it's possible to have code which compiles
different branches depending on whether a particular piece of code compiles
or not. It's not necessarily the case that it's a problem to use -de or -w,
but there are risks involved.

> Separately: the problem with unittest and deprecations is that a
> "deprecated unittest" results in a deprecated unittest function
> in __traits(getUnitTests), which there's no way to call without
> incurring recursive deprecation all the way to deprecated void
> main. This is arguably wrong - imo deprecated unittest shouldn't
> mean the *test* is deprecated, just that it tests a deprecated
> feature. This can be seen by the fact that D's runtime calls
> deprecated unittests with no warning, -de or otherwise. So you
> should be able to call them from framework code too.

I expect that the problem here has to do with how things get lowered.
Underneath the hood, a unittest block is basically a normal function and
thus is going to tend to follow the same rules that a normal function would.
As such, it would make sense that it would be a problem to have a
non-deprecated function calling a unittest function or that a piece of code
which is introspecting unit test stuff would get deprecation messages due to
deprecated unittest blocks.

I don't know enough of the details about how the unit test stuff works to
say how it should be fixed, but I agree that the current behavior isn't
great for alternate test runners.

- Jonathan M Davis

More information about the Digitalmars-d mailing list