-
Notifications
You must be signed in to change notification settings - Fork 10
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
Allow oc
on const(Optional!X)
, allow frontOr
within const nothrow @nogc
#57
Comments
SimonN
changed the title
Allow
Allow Apr 21, 2023
oc
on const(Optional!X), make frontOr const nothrow @nogcoc
on const(Optional!X)
, allow frontOr
within const nothrow @nogc
Hi!
Thanks for the report. Been a minute since I’ve used D now 😅. I will try
and find time to look into this. Off the top of my head I don’t see why
this _shouldnt_ work. But the interplay between annotations in D have
always been from what I remember a royal pain. Will post back when I get
the chance to!
…On Fri, 21 Apr 2023 at 23:15, Simon Naarmann ***@***.***> wrote:
Using optional 1.3.0.
The following code works with no problems.
import optional;
class X {
int foo() const pure nothrow @safe @nogc {
return 5;
}
}
class Y {
Optional!X x;
int bar() pure @safe
{
return x.oc.foo.frontOr(3);
}
}
This compiles fine.
The problem arises when we want to annotate bar() not only as pure @safe,
but as const pure nothrow @safe @nogc in the same way as we did with foo.
In theory, i.e., without looking at the implementation of the optional
library, these extra annotations comply with the type system:
- We don't modify x by maybe calling the const method foo() on
(presumably) a const(X) through the const(Optional!X).
- We don't modify x.oc.foo by calling .frontOr(3) because we merely
have to examine the range x.oc.foo for emptiness and possibly take its
front element. We never have to advance this range. Only if we were to call
.popFront on a range, the range struct would have to be mutable, but
.frontOr(3) should never call .popFront on any range. The exact static
assert is: "Unable to call frontOr on type const(OptionalChain!int). It has
to either be an input range, a Nullable!T, or an Optional!T".
- We provide a default value for frontOr without calling anything that
throws, therefore frontOr will never throw.
- Since frontOr never throws, it will never allocate with the GC.
We can argue that this report should be split into two separate issues: 1.
oc should work on a const(Optional!X) and 2. frontOr should infer that it
will neither modify, throw, nor allocate, given its usage with a default
value like in our example. But I filed them together because they're so
closely related, and because above example code is more meaningful when it
shows both.
Do you see conceptual difficulties in allowing x.oc.foo.frontOr(3) from
within a method annotated const pure nothrow @safe @nogc?
—
Reply to this email directly, view it on GitHub
<#57>, or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAUEDTD53C53WHVKV3C7WH3XCL2IJANCNFSM6AAAAAAXHKQTNY>
.
You are receiving this because you are subscribed to this thread.Message
ID: ***@***.***>
|
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Using optional 1.3.0.
The following code works with no problems.
This compiles fine.
The problem arises when we want to annotate
bar()
not only aspure @safe
, but asconst pure nothrow @safe @nogc
in the same way as we did withfoo()
. If we add all those annotations tobar()
, we get these errors:.oc.foo
on aconst Optional!X
.frontOr
withinnothrow
or@nogc
, or on aconst OptionalChain!int
. The exact static assert is: "Unable to call frontOr on type const(OptionalChain!int). It has to either be an input range, a Nullable!T, or an Optional!T".In theory, i.e., without looking at the implementation of the optional library, these extra annotations comply with D's type system:
x
by maybe calling theconst
methodfoo()
on (presumably) aconst(X)
through theconst(Optional!X)
.x.oc.foo
by calling.frontOr(3)
because we merely have to examine the rangex.oc.foo
for emptiness and possibly take its front element. We never have to advance this range. Only if we were to call.popFront
on a range, the range struct would have to be mutable, but.frontOr(3)
should never call.popFront
on any range.frontOr
without calling anything that throws, thereforefrontOr
will never throw.frontOr
never throws, it will never allocate with the GC.We can argue that this report should be split into two separate issues: 1.
oc
should work on aconst(Optional!X)
and 2.frontOr
should infer that it will neither modify, throw, nor allocate, given its usage with a default value like in our example. But I filed them together because they're so closely related, and because above example code is more meaningful when it shows both.Do you see conceptual difficulties in allowing
x.oc.foo.frontOr(3)
from within a method annotatedconst pure nothrow @safe @nogc
?For now, I've rewritten the example as:
The text was updated successfully, but these errors were encountered: