Comment #0 by verylonglogin.reg — 2014-07-13T08:01:54Z
This code should compile:
---
void f() @nogc
in { new int; }
body { }
---
Note this is already the case for `nothrow` functions as one can throw `Exception`s in contracts which allows e.g. use `assert(expr, format(...))`.
Comment #1 by bearophile_hugs — 2014-07-13T08:06:29Z
(In reply to Denis Shelomovskij from comment #0)
> This code should compile:
> ---
> void f() @nogc
> in { new int; }
> body { }
> ---
>
> Note this is already the case for `nothrow` functions as one can throw
> `Exception`s in contracts which allows e.g. use `assert(expr, format(...))`.
I think this is a bad idea. The point of @nogc is to be sure the GC will not be called or used inside a piece of code. This ER invalidates that. For this ER to be accepted I'll want a @reallynogc added to D that really forbids the use of GC.
Comment #2 by verylonglogin.reg — 2014-07-13T09:56:31Z
(In reply to bearophile_hugs from comment #1)
> (In reply to Denis Shelomovskij from comment #0)
> > This code should compile:
> > ---
> > void f() @nogc
> > in { new int; }
> > body { }
> > ---
> >
> > Note this is already the case for `nothrow` functions as one can throw
> > `Exception`s in contracts which allows e.g. use `assert(expr, format(...))`.
>
> I think this is a bad idea. The point of @nogc is to be sure the GC will not
> be called or used inside a piece of code. This ER invalidates that. For this
> ER to be accepted I'll want a @reallynogc added to D that really forbids the
> use of GC.
I don't see any difference here with `nothrow` which can be violated in contracts allowing e.g. `format` calls.
Comment #3 by yebblies — 2014-07-13T15:23:23Z
(In reply to Denis Shelomovskij from comment #0)
> This code should compile:
> ---
> void f() @nogc
> in { new int; }
> body { }
> ---
>
> Note this is already the case for `nothrow` functions as one can throw
> `Exception`s in contracts which allows e.g. use `assert(expr, format(...))`.
assert throws an error and does not violate nothrow.
Comment #4 by bearophile_hugs — 2014-07-13T15:34:29Z
(In reply to yebblies from comment #3)
> assert throws an error and does not violate nothrow.
This compiles, but is it good?
void foo() nothrow
in {
throw new Exception(null);
} body {
}
void main() {}
Comment #5 by yebblies — 2014-07-13T15:38:35Z
(In reply to bearophile_hugs from comment #4)
>
> This compiles, but is it good?
>
>
> void foo() nothrow
> in {
> throw new Exception(null);
> } body {
> }
> void main() {}
I think it's a bug. 'debug' blocks do skip checking, but seeing as pure, @safe and @nogc are enforced it's probably just been overlooked.
Comment #6 by public — 2014-07-13T15:46:41Z
I believe contracts should not be treated any specially for @nogc
Instead throwing an errors (including AssertError) should be replaced with HLT same as it is done for assert(false) in release builds. It will keep basic sanity checks in place without sacrificing @nogc guarantees.
Comment #7 by bearophile_hugs — 2014-07-13T16:08:05Z
(In reply to yebblies from comment #5)
> I think it's a bug. 'debug' blocks do skip checking, but seeing as pure,
> @safe and @nogc are enforced it's probably just been overlooked.
Filed as Issue 13123
Comment #8 by verylonglogin.reg — 2014-07-14T10:54:50Z
(In reply to yebblies from comment #3)
> (In reply to Denis Shelomovskij from comment #0)
> > This code should compile:
> > ---
> > void f() @nogc
> > in { new int; }
> > body { }
> > ---
> >
> > Note this is already the case for `nothrow` functions as one can throw
> > `Exception`s in contracts which allows e.g. use `assert(expr, format(...))`.
>
> assert throws an error and does not violate nothrow.
`assert` is here just because it is where `format` is called. I'm talking about `format`.
Comment #9 by yebblies — 2014-07-14T11:04:05Z
(In reply to Denis Shelomovskij from comment #8)
>
> `assert` is here just because it is where `format` is called. I'm talking
> about `format`.
You're right, I missed that, but it is addressed in the other comments.
Comment #10 by stanislav.blinov — 2021-12-08T16:40:47Z
2.098 rewrite:
void f() @nogc
in { new int; } // Error: cannot use `new` in `@nogc` function `f`
do { }
---
Which should stay. Contracts shouldn't alter expected behavior. If one wants an escape hatch, there's `debug`.