[Issue 18945] immutable variable is used as if it's an enum
https://issues.dlang.org/show_bug.cgi?id=18945 Iain Buclaw changed: What|Removed |Added Priority|P1 |P3 --
[Issue 18945] immutable variable is used as if it's an enum
https://issues.dlang.org/show_bug.cgi?id=18945 --- Comment #11 from David Bennett --- (In reply to Simen Kjaeraas from comment #10) > (In reply to David Bennett from comment #9) > > https://run.dlang.io/is/zZWdIQ > > > > Only works currently with static immutable > > What do you mean? It works perfectly with enum: > https://run.dlang.io/is/3Xy5pI So it does... I'm sure I tried that a while back (years maybe) and it didn't so I had been avoiding it. --
[Issue 18945] immutable variable is used as if it's an enum
https://issues.dlang.org/show_bug.cgi?id=18945 --- Comment #10 from Simen Kjaeraas --- (In reply to David Bennett from comment #9) > https://run.dlang.io/is/zZWdIQ > > Only works currently with static immutable What do you mean? It works perfectly with enum: https://run.dlang.io/is/3Xy5pI --
[Issue 18945] immutable variable is used as if it's an enum
https://issues.dlang.org/show_bug.cgi?id=18945 ag0aep6g changed: What|Removed |Added CC||ag0ae...@gmail.com --
[Issue 18945] immutable variable is used as if it's an enum
https://issues.dlang.org/show_bug.cgi?id=18945 --- Comment #9 from David Bennett --- (In reply to David Bennett from comment #8) > (In reply to David Bennett from comment #7) > > Then there are immutable struct members used at compile time, they might not > > be easy to convert to an enum. > > https://run.dlang.io/is/cfGfxw > > I've never seen it used like that... but it does work currently. > > Actually, I reduced that last case a bit to much that it would work fine > even with this change... Here is the case I was thinking of: https://run.dlang.io/is/zZWdIQ Only works currently with static immutable, so not sure if it could be a problem as I think this change would only effect immutable (without static). sorry for the noise. --
[Issue 18945] immutable variable is used as if it's an enum
https://issues.dlang.org/show_bug.cgi?id=18945 --- Comment #8 from David Bennett --- (In reply to David Bennett from comment #7) > Then there are immutable struct members used at compile time, they might not > be easy to convert to an enum. > https://run.dlang.io/is/cfGfxw > I've never seen it used like that... but it does work currently. Actually, I reduced that last case a bit to much that it would work fine even with this change... --
[Issue 18945] immutable variable is used as if it's an enum
https://issues.dlang.org/show_bug.cgi?id=18945 --- Comment #7 from David Bennett --- (In reply to Jonathan M Davis from comment #6) > > Just use an enum if you want the value to be known and used at compile time, > and use an immutable variable if you want it to be known and used at > runtime. Don't try to have a variable with different values at compile time > and runtime. And if for some reason, you want the value calculated at > compile time but to still have a variable, then use an enum to initialize > the immutable variable. That's what you have to do with mutable variables > already. So the deprecation message shouldn't have a concrete example to opt-in to keep the current functionality. Just something like "Deprecation: Using an immutable variable at compile time will be removed in a future version. Try changing `n` in `int[n] a;` to use an enum variable.". And assume D users will know that they will need to implement the enum separately from the immutable if they want to keep the status quo? Then there are immutable struct members used at compile time, they might not be easy to convert to an enum. https://run.dlang.io/is/cfGfxw I've never seen it used like that... but it does work currently. --
[Issue 18945] immutable variable is used as if it's an enum
https://issues.dlang.org/show_bug.cgi?id=18945 --- Comment #6 from Jonathan M Davis --- (In reply to David Bennett from comment #4) > I'm not sure what workaround we would recommend in the deprecation messaged > as the current functionality is actually hard to replicate. Just use an enum if you want the value to be known and used at compile time, and use an immutable variable if you want it to be known and used at runtime. Don't try to have a variable with different values at compile time and runtime. And if for some reason, you want the value calculated at compile time but to still have a variable, then use an enum to initialize the immutable variable. That's what you have to do with mutable variables already. --
[Issue 18945] immutable variable is used as if it's an enum
https://issues.dlang.org/show_bug.cgi?id=18945 anonymous4 changed: What|Removed |Added Hardware|x86 |All OS|Windows |All --- Comment #5 from anonymous4 --- --- int f(in int a) pure { return a; } void g() { immutable int a=0; static assert(f(a)==0); } --- This works. --- int f(in ref int a) pure { return a; } void g() { immutable int a=0; static assert(f(a)==0); } --- This doesn't. --
[Issue 18945] immutable variable is used as if it's an enum
https://issues.dlang.org/show_bug.cgi?id=18945 David Bennett changed: What|Removed |Added CC||davidbenn...@bravevision.co ||m --- Comment #4 from David Bennett --- I'm not sure what workaround we would recommend in the deprecation messaged as the current functionality is actually hard to replicate... as enum and static would give a different runtime result (actually an error in this case as __ctfe is not known at statictime... only ctfetime and runtime) The best I could do on short notice was: unittest { immutable n = __ctfe ? 1 : 2; enum l = {return __ctfe ? 1 : 2;}(); int[l] a; assert(a.length == n); } --
[Issue 18945] immutable variable is used as if it's an enum
https://issues.dlang.org/show_bug.cgi?id=18945 --- Comment #3 from Jonathan M Davis --- This probably does need to be removed via deprecation rather than simply making it an error, but allowing it is exactly the sort of thing that increases the confusion about how CTFE works and when it's used. Currently, immutable i = foo(); doesn't do CTFE. But immutable i = foo(); int[i] arr; does, and that muddies the waters considerably. We already have problems due to folks getting really confused about why stuff like auto foo(int i) { return bar!i(); } isn't legal, and allowing a runtime variable to be used just because it's immutable makes that worse - even more so when you consider that auto foo(immutable int i) { return bar!i(); } won't work, and neither will auto foo(immutable int i = 42) { return bar!i(); } And allowing immutable i = foo(); int[i] arr; to work doesn't even buy us anything. You could simply use enum instead of immutable, and it works perfectly fine. My guess is that the current behavior was added because of an enhancement request, and the person who implemented it didn't think of all of the consequences that result from that decision (including the issue with __ctfe). But I definitely think that we'd be better off if you _had_ to use an enum in this case and that the fact that a variable was const or immutable would have zero effect on CTFE. --
[Issue 18945] immutable variable is used as if it's an enum
https://issues.dlang.org/show_bug.cgi?id=18945 --- Comment #2 from David Bennett --- Disclaimer: Just a D user, I hold no decision making power or insight into the history here. const and immutable are runtime lvalues that have a known way to get "a" value at compiletime. As you have noticed the runtime and compiletime values could be different. Here is another example to show the same effect. --- unittest { immutable n = __ctfe ? 1 : 2; enum j = n; assert(n == j); } --- If you wanted to opt-in to making sure you could only use n at runtime you could make it a `static immutable` but this has the effect of running the assignment expression at compiletime. I believe the current functionality is being used in various projects so I dont see this being changed without at least a deprecation process. For example, I've seen sending const variables as template parameters more than a few times. As for my personal opinion on this issue, I believe using const and immutable at compiletime is useful, it's just that the values could be different that's confusing. So I believe the current reasoning goes like this: immutable values are theoretically known at compile time so why not use them. It's not always possible to ctfe so runtime immutable is assigned at runtime. But the runtime value is not known at compiletime, so when it's used we do the ctfe then and error if it cant. --
[Issue 18945] immutable variable is used as if it's an enum
https://issues.dlang.org/show_bug.cgi?id=18945 Jonathan M Davis changed: What|Removed |Added CC||issues.dl...@jmdavisprog.co ||m --- Comment #1 from Jonathan M Davis --- Yeah. And bizarrely, this code actually results in an error about not being able to call stuff during CTFE: int foo() { import std.datetime; return cast(int)Clock.currTime().stdTime; } void main() { immutable i = foo(); int[i] arr; } Getting rid of the declaration for arr fixes the problem. So, clearly, the compiler is currently deciding whether it should do CTFE on an immutable, local variable based on whether it's then used in a context where its value must be known at compile time instead of forcing enum to be used instead. It also seems to do the same with const. The fact that the static array's size can use a local variable is completely inconsistent with how CTFE normally works and makes the whole situation that much more confusing. CTFE should only be kicking in based on whether the value is actually needed at compile time and not based on whether the variable that it's assigned to is then used at compile time. --