Bug 13118 – Allow non-`@nogc` stuff in `@nogc` function contracts

Status
RESOLVED
Resolution
INVALID
Severity
enhancement
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2014-07-13T08:01:54Z
Last change time
2021-12-08T16:40:47Z
Assigned to
No Owner
Creator
Denis Shelomovskii
See also
https://issues.dlang.org/show_bug.cgi?id=4995

Comments

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`.