www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - nogc nothrow for Variant.peek

reply Bogdan Szabo <contact szabobogdan.com> writes:
Hi everyone,

I'm trying to use `Variant.peek` structs in a ` nogc nothrow` 
code, but it seems this is not possible.

 From what I see in the source code here: 
https://github.com/dlang/phobos/blob/master/std/variant.d#L790 
there is no reason why this function would not be ` nogc 
nothrow`. Is there something that I am missing?

Thanks,
Bogdan
Aug 10 2023
next sibling parent Steven Schveighoffer <schveiguy gmail.com> writes:
On 8/10/23 3:56 AM, Bogdan Szabo wrote:
 Hi everyone,
 
 I'm trying to use `Variant.peek` structs in a ` nogc nothrow` code, but 
 it seems this is not possible.
 
  From what I see in the source code here: 
 https://github.com/dlang/phobos/blob/master/std/variant.d#L790 there is 
 no reason why this function would not be ` nogc nothrow`. Is there 
 something that I am missing?
The only "smart" operation there is the TypeInfo comparison. I don't see why it can't be ` nogc` and `nothrow`. -Steve
Aug 10 2023
prev sibling parent reply Paul Backus <snarwin gmail.com> writes:
On Thursday, 10 August 2023 at 07:56:07 UTC, Bogdan Szabo wrote:
 Hi everyone,

 I'm trying to use `Variant.peek` structs in a ` nogc nothrow` 
 code, but it seems this is not possible.

 From what I see in the source code here: 
 https://github.com/dlang/phobos/blob/master/std/variant.d#L790 
 there is no reason why this function would not be ` nogc 
 nothrow`. Is there something that I am missing?

 Thanks,
 Bogdan
If I put ` nogc nothrow` on `Variant.peek` and attempt to compile Phobos, DMD master gives this error message: ``` std/variant.d(795): Error: ` nogc` function `std.variant.VariantN!32LU.VariantN.peek!void.peek` cannot call non- nogc function `std.variant.VariantN!32LU.VariantN.type` std/variant.d(823): which wasn't inferred ` nogc` because of: std/variant.d(823): ` nogc` function `std.variant.VariantN!32LU.VariantN.type` cannot call non- nogc `this.fptr` std/variant.d(795): Error: ` nogc` function `std.variant.VariantN!32LU.VariantN.peek!void.peek` cannot call non- nogc function `object.opEquals!(TypeInfo, TypeInfo).opEquals` ../dmd/druntime/import/object.d(275): which calls `object.TypeInfo.opEquals` ``` So, there are two reasons: 1. `Variant.peek` calls `Variant.type` which calls `Variant.fptr`, which is not ` nogc nothrow`. 2. `Variant.peek` calls `TypeInfo.opEquals`, which is not ` nogc nothrow`. Reason (1) is theoretically solvable by refactoring `Variant`. Reason (2) would require backwards-incompatible language changes to solve (changes to `TypeInfo`'s public interface).
Aug 11 2023
parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 8/11/23 10:24 AM, Paul Backus wrote:
 On Thursday, 10 August 2023 at 07:56:07 UTC, Bogdan Szabo wrote:
 Hi everyone,

 I'm trying to use `Variant.peek` structs in a ` nogc nothrow` code, 
 but it seems this is not possible.

 From what I see in the source code here: 
 https://github.com/dlang/phobos/blob/master/std/variant.d#L790 there 
 is no reason why this function would not be ` nogc nothrow`. Is there 
 something that I am missing?

 Thanks,
 Bogdan
If I put ` nogc nothrow` on `Variant.peek` and attempt to compile Phobos, DMD master gives this error message: ``` std/variant.d(795): Error: ` nogc` function `std.variant.VariantN!32LU.VariantN.peek!void.peek` cannot call non- nogc function `std.variant.VariantN!32LU.VariantN.type` std/variant.d(823):        which wasn't inferred ` nogc` because of: std/variant.d(823):        ` nogc` function `std.variant.VariantN!32LU.VariantN.type` cannot call non- nogc `this.fptr` std/variant.d(795): Error: ` nogc` function `std.variant.VariantN!32LU.VariantN.peek!void.peek` cannot call non- nogc function `object.opEquals!(TypeInfo, TypeInfo).opEquals` ../dmd/druntime/import/object.d(275):        which calls `object.TypeInfo.opEquals` ``` So, there are two reasons: 1. `Variant.peek` calls `Variant.type` which calls `Variant.fptr`, which is not ` nogc nothrow`. 2. `Variant.peek` calls `TypeInfo.opEquals`, which is not ` nogc nothrow`. Reason (1) is theoretically solvable by refactoring `Variant`. Reason (2) would require backwards-incompatible language changes to solve (changes to `TypeInfo`'s public interface).
You can assume TypeInfo.opEquals is nogc (all TypeInfos in this instance are compiler-generated and opEquals does not use the gc). So it would be fine to cast around that. The "public interface" in this case is anyone making their own TypeInfo derivative. It would be fine to change TypeInfo.opEquals to nogc as a user of it. But in this case, I think it's fine to cast away the nogc thing. Could be the same solution with fptr, since we know that this specific call to fptr will not use the gc or throw. -Steve
Aug 11 2023
parent reply Paul Backus <snarwin gmail.com> writes:
On Friday, 11 August 2023 at 14:50:25 UTC, Steven Schveighoffer 
wrote:
 You can assume TypeInfo.opEquals is nogc (all TypeInfos in this 
 instance are compiler-generated and opEquals does not use the 
 gc). So it would be fine to cast around that.

 The "public interface" in this case is anyone making their own 
 TypeInfo derivative. It would be fine to change 
 TypeInfo.opEquals to  nogc as a user of it. But in this case, I 
 think it's fine to cast away the nogc thing.
Casting is an ugly solution, but in practice, yeah, you would almost certainly get away with it.
 Could be the same solution with fptr, since we know that this 
 specific call to fptr will not use the gc or throw.
Well, you know it doesn't in the current version of the code. But there's nothing stopping future changes from breaking that assumption. The non-ugly way to fix this is to split `handler` up into separate functions, and replace `fptr` with a pointer to a vtable. Then each of the function pointers in the vtable can have its own set of attributes.
Aug 11 2023
parent Steven Schveighoffer <schveiguy gmail.com> writes:
On 8/11/23 11:05 AM, Paul Backus wrote:
 On Friday, 11 August 2023 at 14:50:25 UTC, Steven Schveighoffer wrote:
 Could be the same solution with fptr, since we know that this specific 
 call to fptr will not use the gc or throw.
Well, you know it doesn't in the current version of the code. But there's nothing stopping future changes from breaking that assumption. The non-ugly way to fix this is to split `handler` up into separate functions, and replace `fptr` with a pointer to a vtable. Then each of the function pointers in the vtable can have its own set of attributes.
I actually find that uglier. From a performance standpoint, this probably involves a 2-level indirection (one to the vtable, and then the function call as well). Possibly, a compromise is to factor out pieces that need specific attributes as nested functions and attribute those. At least that would silo off the pieces that need to be attributed that way, and make it more obvious if you change something that violates the attributes. -Steve
Aug 11 2023