Bug 18757 – static invariant{} should either work or not be valid syntax

Status
NEW
Severity
minor
Priority
P3
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2018-04-12T13:15:37Z
Last change time
2024-12-13T18:58:20Z
Assigned to
No Owner
Creator
FeepingCreature
Moved to GitHub: dmd#17856 →

Comments

Comment #0 by default_357-line — 2018-04-12T13:15:37Z
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.
Comment #1 by razvan.nitu1305 — 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)
Comment #2 by default_357-line — 2018-04-16T13:43:21Z
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.
Comment #3 by uplink.coder — 2018-04-16T14:31:57Z
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.
Comment #4 by razvan.nitu1305 — 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.
Comment #5 by issues.dlang — 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.
Comment #6 by default_357-line — 2018-04-16T17:43:06Z
In my opinion, static this sets the precedent that static + class-level feature = module-level feature.
Comment #7 by bugzilla — 2018-04-16T18:32:11Z
A `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.
Comment #8 by andrei — 2018-04-16T18:47:01Z
The problem is that static methods don't call the static invariant.
Comment #9 by robert.schadek — 2024-12-13T18:58:20Z
THIS ISSUE HAS BEEN MOVED TO GITHUB https://github.com/dlang/dmd/issues/17856 DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB