digitalmars.D.learn - nogc nothrow for Variant.peek
- Bogdan Szabo (9/9) Aug 10 2023 Hi everyone,
- Steven Schveighoffer (4/13) Aug 10 2023 The only "smart" operation there is the TypeInfo comparison. I don't see...
- Paul Backus (26/35) Aug 11 2023 If I put `@nogc nothrow` on `Variant.peek` and attempt to compile
- Steven Schveighoffer (10/50) Aug 11 2023 You can assume TypeInfo.opEquals is nogc (all TypeInfos in this instance...
- Paul Backus (11/20) Aug 11 2023 Casting is an ugly solution, but in practice, yeah, you would
- Steven Schveighoffer (9/19) Aug 11 2023 I actually find that uglier. From a performance standpoint, this
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
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
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, BogdanIf 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
On 8/11/23 10:24 AM, Paul Backus wrote:On Thursday, 10 August 2023 at 07:56:07 UTC, Bogdan Szabo 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. Could be the same solution with fptr, since we know that this specific call to fptr will not use the gc or throw. -SteveHi 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, BogdanIf 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
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
On 8/11/23 11:05 AM, Paul Backus wrote:On Friday, 11 August 2023 at 14:50:25 UTC, Steven Schveighoffer wrote: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. -SteveCould 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