D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 17445 - [REG2.073.0] Disagreement between 'static assert' and 'static if'
Summary: [REG2.073.0] Disagreement between 'static assert' and 'static if'
Status: RESOLVED FIXED
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D2
Hardware: All All
: P1 regression
Assignee: No Owner
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2017-05-27 11:47 UTC by Dario Schiavon
Modified: 2018-11-29 14:46 UTC (History)
3 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description Dario Schiavon 2017-05-27 11:47:56 UTC
Using DMD32 v2.074.0.

struct MyStruct
{
    static assert(is(typeof(this = this))); // Here it passes.
	
    static if (!is(typeof(this = this)))
        static assert(0); // But here it fails.
}

If the is-expression was true in the assertion, how can it be false in the static-if condition? Notwithstanding the fact that, AFAIK, 'this' in this context (outside of a member function) shouldn't be defined.

It compiles without errors with LDC2 v1.1.1 (which is based on DMD v2.071.2).

The reason I wrote this code is I need to check whether the postblit constructor is defined (or alternatively opAssign) before I define a member function that makes use of it.
Comment 1 Dario Schiavon 2017-05-27 12:05:08 UTC
See also https://issues.dlang.org/show_bug.cgi?id=17446 for a similar issue, which however is also present on LDC2 (so it can't actually be the same issue).
Comment 2 Stanislav Blinov 2017-05-27 22:10:42 UTC
There are isCopyable and isAssignable traits in std.traits.
Or you can roll your own:

enum bool isCopyable(T) = is(typeof(() { T* a, b; *a = *b; }));

using pointers in case e.g. the default ctor is disabled.
Comment 3 Stanislav Blinov 2017-05-27 22:13:29 UTC
Sorry, that was isAssignable.
isCopyable would be:

enum bool isCopyable(T) = is(typeof(() { T* a; T b = *a; }));
Comment 4 Dario Schiavon 2017-05-28 14:05:21 UTC
Stanislav, thanks for the tip. I knew about isAssignable but I had somehow missed isCopyable, which is exactly what I needed.

However, I still cannot make my code work because of the bug shown here. isAssignable only gives the right answer as long as I don't try to use it as a static-if condition.

For example:

enum bool isCopyable(T) = is(typeof(() { T* a; T b = *a; }));

struct MyStruct
{
    enum result = isCopyable!MyStruct;
	pragma(msg, result);
    //static if (result) {}
}

This code (with the static-if commented out) correctly prints true. But if I leave the static-if in the struct's body, it prints false (DMD 2.074.0).

If the static-if is moved outside of the struct's body, or if the condition doesn't involve the struct's name, then everything works as expected - but that's not what I need.
Comment 5 Dario Schiavon 2017-05-28 14:27:02 UTC
I guess I can speculate about the reason for this behavior. What I'm doing, is making a copiability test on a type that hasn't been completely defined yet. As long as there's no static-if depending on the answer, the answer can be given. Otherwise, the code inserted by the static-if might cause the answer to change, leading to a paradox.

Of course I had something else in mind when I wrote that code. I expected the answer to be based only on the code written so far, and I didn't intend the static-if to produce a paradox. But I guess it would be difficult for the compiler to prove that no paradox happens.

If all of this is correct, than it would certainly be better that the compiler emit an error message and stop the compilation, rather than give an answer that is surely 100% wrong.
Comment 6 Vladimir Panteleev 2017-07-02 01:08:29 UTC
This appears to be a regression.

Introduced in https://github.com/dlang/dmd/pull/6388
Comment 7 Vladimir Panteleev 2017-07-02 11:16:08 UTC
(In reply to Vladimir Panteleev from comment #6)
> Introduced in https://github.com/dlang/dmd/pull/6388

Specifically:

https://github.com/dlang/dmd/pull/5972 (PR to scope branch)
Commit 62be2fbda0a09e1a5dd1fa6024f81c165057d386
Comment 8 RazvanN 2018-11-29 14:46:44 UTC
Fixed by: https://github.com/dlang/dmd/pull/8993