static if (is(typeof(Z))) {} else {static assert(0, "first time");}
deprecated int Z;
static if (is(typeof(Z))) {} else {static assert(0, "second time lucky");}
----------
crash.d(5): Error: static assert "second time lucky"
It should assert the first time.
This is another gagging bug, related to bug 4269, but the problem isn't an invalid type. Here, the first typeof doesn't check deprecation.
Comment #1 by smjg — 2012-02-11T16:21:47Z
I'm not sure what's meant to happen here. Z still exists, even if it's deprecated. But by deprecating it, we are basically telling the compiler to treat it as if it doesn't exist.
This is a difficult case, because to treat deprecated stuff as nonexistent in IsExpressions causes the program to compile and behave differently depending on whether the compiler switch to enable deprecated features is switched on or not.
If the correct behaviour is given anywhere in the spec, I haven't managed to find it.
Comment #2 by bugzilla — 2012-02-12T11:25:33Z
Deprecation is most definitely not about declarations not existing. It is about being an error to reference them.
For example,
deprecated void foo(int);
void foo(long);
...
foo(0); // error, foo(int) is deprecated
rather than selecting foo(long), which it would if foo(int) "disappeared".
IOW, deprecation checking is done *after* symbol resolution, not before.
Comment #3 by timon.gehr — 2012-02-12T11:36:25Z
I think both static if conditions should fail to compile because they reference a deprecated symbol. In other words, error gagging should not apply to deprecation errors. It should be impossible for 'deprecated' to silently change the behavior of a program.
Comment #4 by smjg — 2012-02-12T12:46:45Z
I've started a thread on the newsgroup about this whole topic.
"Thoughts about deprecation"
http://tinyurl.com/832hhqj
Comment #5 by clugdbug — 2012-02-16T12:28:46Z
> Deprecation is most definitely not about declarations not existing. It is about being an error to reference them.
Right, but is(typeof(X)) isn't a check if X exists, even though a popular idiom is to use it for that purpose. Rather, it asks what type X has. And I think that has to be considered as referencing X, and is therefore an error.
If it's not an error, it has to be able to provide a type, and that's a problem:
static if (is(typeof(Z) M)) {
M we_are_relying_on_a_deprecated_variable;
}
deprecated int Z;
But it turns out that this bug has nothing to do with is().
alias typeof(Z) Q1; // compiles
deprecated int Z;
alias typeof(Z) Q2; // doesn't compile
In fact, it seems it doesn't even require deprecated:
alias typeof(Z1) Q1;
pragma(msg, Q1.stringof); // int
const int Z1;
alias typeof(Z1) R1;
pragma(msg, R1.stringof); // const(int)
and yet if you write const (int) Z1; it displays const(int) in both cases.
Comment #6 by razvan.nitu1305 — 2019-05-24T09:57:39Z
Hello all, I come from the future where accessing deprecated symbols is not an error. Now, deprecations are issued for both accesses of Z and no assert is triggered, which is the correct behavior. Closing as invalid.