__traits(compiles) is true with warnings as errors
bauss
jj_1337 at live.dk
Thu Oct 14 11:08:24 UTC 2021
On Thursday, 14 October 2021 at 05:41:01 UTC, Tejas wrote:
> On Wednesday, 13 October 2021 at 17:58:23 UTC, Jonathan Levi
> wrote:
>> When dmd is passed the "-w" tag, it "treats warnings as
>> errors" but not with the "__traits(compiles)" expression. Is
>> this the intended action?
>>
>> This code should compile even with "-w", but it does not.
>>
>> int i;
>> static if (__traits(compiles,i += 5.2))
>> i += 5.2;
>>
>>
>> `pragma(msg, __traits(compiles,i += 5.2))` is `true`, even
>> though it will stop the compiler.
>>
>> My specific use case, where I am hindered by this, is with a
>> guarded template function akin to this:
>>
>> void fun(T,U)(ref T a, const U b)
>> if (__traits(compiles, a += b))
>> {
>> a += b;
>> }
>>
>> I think this is a bug. The Docs for __traits compiles state
>> "Returns a bool true if all of the arguments compile . . ."
>> which is not holding true.
>
> But it _is_ compiling, just with a warning.
>
> If you wish to force the code to compile, you can manually cast
> it to prevent the compiler from erroring out:
> ```d
>
> void main(){
> int i;
> static if (__traits(compiles,i += 5.2))
> i += cast(int)5.2;
> }
> ```
>
> Or in general:
>
> ```d
> void fun(T,U)(ref T a, const U b)
> if (__traits(compiles, a += b))
> {
> a += cast(T)b;
> }
> ```
>
> It seems the `__traits(compiles, ..)` feature was designed to
> operate independent of the command line flags passed to the D
> compiler.
>
> I don't know if that's a bug or not though; best wait for
> someone more experienced to chime in.
__traits(compiles) just checks whether the arguments given are
semantically correct. The given arguments in the example of OP
are technically semantically correct and that's why it returns
true.
What could be useful is a new trait (to not break existing code)
like __traits(warning, ...) which does the same as
__traits(compiles) but also checks whether the arguments would
cause a warning by the compiler. OR __traits(compiles, ..., true)
where true means aggressive (warnings as error) and false or
nothing means the default behavior we have today.
The default behavior can't or shouldn't change as existing code
that relies on it could break and the problem here is that the
failure could be silent as you don't get an error message unless
your specific use-case relies on the arguments compiling, but in
a lot of cases it's used optionally to create branching.
More information about the Digitalmars-d-learn
mailing list