-
-
Notifications
You must be signed in to change notification settings - Fork 610
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
static invariant{} should either work or not be valid syntax #17856
Labels
Comments
razvan.nitu1305 commented on 2018-04-16T12:42:26Z(In reply to FeepingCreature from comment #0)
> Right now, you can define a struct to have a static invariant:
>
> struct S {
> static invariant { assert(false); }
> static void foo() { }
> }
>
> But the invariant will not be checked when calling foo.
>
> Either this should work, or "static invariant {}" should be a syntax error.
Placing static in front of an invariant has no effect on the invariant. The problem with the above code is that the method foo is marked as static:
struct S
{
invariant { (assert (false); }
static void foo() {}
}
void main()
{
S s;
s.foo(); \\ invariant does not get called
}
while :
struct S
{
static invariant { (assert (false); }
void foo() {}
}
void main()
{
S s;
s.foo(); \\ invariant does get called
}
So we can conclude that invariants are not called for static functions. The spec does not mention anything about this so there are 2 possibilities :
1. Invariants were designed only for struct/class instances (in which case the bug report will be closed with a spec update)
2. Invariants should also be called when static methods are called (in which case this should be fixed) |
default_357-line (@FeepingCreature) commented on 2018-04-16T13:43:21ZIn case 1, I maintain that this is a bug - the compiler should not smile-and-nod while silently ignoring syntax that hints at a semantic that does not apply. |
uplink.coder commented on 2018-04-16T14:31:57ZWell invariants cannot apply to static methods since they are only concerned about the object's state.
which by definition cannot be directly touched in static functions.
that's why it's not called.
I don't see that there is a basis to issue a warning. |
razvan.nitu1305 commented on 2018-04-16T14:46:31Z(In reply to uplink.coder from comment #3)
> Well invariants cannot apply to static methods since they are only concerned
> about the object's state.
> which by definition cannot be directly touched in static functions.
> that's why it's not called.
>
> I don't see that there is a basis to issue a warning.
What about object that have static fields? If you have a static function which modify static fields? I would argue that an invariant might want to check whether a static function has modified the state of the object. |
issues.dlang (@jmdavis) commented on 2018-04-16T16:07:00Z(In reply to FeepingCreature from comment #2)
> In case 1, I maintain that this is a bug - the compiler should not
> smile-and-nod while silently ignoring syntax that hints at a semantic that
> does not apply.
The reality of the matter is that the compiler ignores attributes like statict all over the place (e.g. static on most things at module scope is allowed and ignored, and you can do something like put @safe on a member variable without complaint from the compiler). If anything, it's extremely typical for the compiler to ignore attributes that don't apply rather than to treat them as an error. In some ways, this can be annoying, but it does help avoid problems in generic code. So, whether an error should be given in this particular case and not others is up for debate, but it's par for the course around here.
(In reply to RazvanN from comment #4)
> What about object that have static fields? If you have a static function
> which modify static fields? I would argue that an invariant might want to
> check whether a static function has modified the state of the object.
We could certainly add a feature like that, but it's certainly not what invariant was designed for. Its purpose was specifically to verify the state of an object, and arguably, the static fields of an object aren't any different from those at module-sope except for the fact that they're scoped to be inside a struct or class. And as such, having an invariant for them would be pretty weird and is of pretty debatable value. If we went down that route, the question would become why we don't have module-level invariants. |
default_357-line (@FeepingCreature) commented on 2018-04-16T17:43:06ZIn my opinion, static this sets the precedent that static + class-level feature = module-level feature. |
bugzilla (@WalterBright) commented on 2018-04-16T18:32:11ZA `static invariant` does not have special semantics distinct from `invariant` other than it does not have a `this` parameter. That fully explains the observed behavior. The `static` is not ignored:
struct S {
int i;
static invariant { assert (i == 3); } // Error: need this for i of type int
void foo() {}
}
void main() {
S s;
s.foo(); // invariant does get called
}
Whether that is desirable behavior or not is another matter entirely. Our general practice when confronted with these sorts of issues is to make it an error until we figure out what is the best approach, if there even is one, rather than inventing arbitrary behavior without much of any supporting rationale or use cases. |
andrei (@andralex) commented on 2018-04-16T18:47:01ZThe problem is that static methods don't call the static invariant. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
FeepingCreature (@FeepingCreature) reported this on 2018-04-12T13:15:37Z
Transferred from https://issues.dlang.org/show_bug.cgi?id=18757
CC List
Description
Right now, you can define a struct to have a static invariant: struct S { static invariant { assert(false); } static void foo() { } } But the invariant will not be checked when calling foo. Either this should work, or "static invariant {}" should be a syntax error.The text was updated successfully, but these errors were encountered: