Thread overview | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
July 16, 2018 Implicit conversion of struct with methods to immutable in pure function fails | ||||
---|---|---|---|---|
| ||||
Why does this fail? struct F { int i; ushort _x; void x(ushort v) pure {_x = v;} ushort x() const { return _x; } } immutable F f1 = () pure { F lf = F(); return lf; }(); // Error: cannot implicitly convert expression delegate () => lf() of type F to immutable(F) F makeF() pure { F lf = F(); return lf; } immutable F f2 = makeF(); // Error: cannot implicitly convert expression makeF() of type F to immutable(F) Removing the methods in struct F compiles fine. Background: I have a mixin(bitfields!(...)) in the struct which utilizes member functions. ///////////// Idea: Just found out that it works when making the struct static. But why does that help? Is it because the compiler wouldn't be able to check whether methods in the struct are accessing non-immutable data in the enclosing context? That would not make much sense though because the following works: // Compiles fine! int modi = 3; void main () { static struct F { int var() immutable { return modi; } // accessing modi from module scope } immutable f = () pure { F f = F(); return f; }(); } So my explanation wouldn't make sense, since why would it be okay to use module-scope data and not enclosing context data? So where does that limitation come from that I implicitly convert a nested struct to immutable in a pure function? |
July 16, 2018 Re: Implicit conversion of struct with methods to immutable in pure function fails | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timoses | On Monday, 16 July 2018 at 11:43:03 UTC, Timoses wrote:
> Why does this fail?
It doesn't. Not using DMD 2.081.1 under Windows, at least. I tried adding a bitfield since you mentioned it, but it compiles nicely for me. Which version of DMD are you using, and are you having the issues with the exact code you posted here?
--
Simen
|
July 16, 2018 Re: Implicit conversion of struct with methods to immutable in pure function fails | ||||
---|---|---|---|---|
| ||||
Posted in reply to Simen Kjærås | On Monday, 16 July 2018 at 12:00:57 UTC, Simen Kjærås wrote: > On Monday, 16 July 2018 at 11:43:03 UTC, Timoses wrote: >> Why does this fail? > > It doesn't. Not using DMD 2.081.1 under Windows, at least. I tried adding a bitfield since you mentioned it, but it compiles nicely for me. Which version of DMD are you using, and are you having the issues with the exact code you posted here? > > -- > Simen https://run.dlang.io/is/Pgs527 I'm on 2.080.1. But above is on latest 2.081.1 I believe. Note that the bottom code snippet in the original post does work, while the first one does not. |
July 16, 2018 Re: Implicit conversion of struct with methods to immutable in pure function fails | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timoses | On Monday, 16 July 2018 at 13:13:53 UTC, Timoses wrote:
> On Monday, 16 July 2018 at 12:00:57 UTC, Simen Kjærås wrote:
>> On Monday, 16 July 2018 at 11:43:03 UTC, Timoses wrote:
>>> Why does this fail?
>>
>> It doesn't. Not using DMD 2.081.1 under Windows, at least. I tried adding a bitfield since you mentioned it, but it compiles nicely for me. Which version of DMD are you using, and are you having the issues with the exact code you posted here?
>>
>> --
>> Simen
>
> https://run.dlang.io/is/Pgs527
>
> I'm on 2.080.1. But above is on latest 2.081.1 I believe.
>
> Note that the bottom code snippet in the original post does work, while the first one does not.
Yep, run.dlang.io automatically updates itself to the latest compiler (you can check this e.g. with -v).
|
July 17, 2018 Re: Implicit conversion of struct with methods to immutable in pure function fails | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timoses | On Monday, 16 July 2018 at 13:13:53 UTC, Timoses wrote:
> On Monday, 16 July 2018 at 12:00:57 UTC, Simen Kjærås wrote:
>> On Monday, 16 July 2018 at 11:43:03 UTC, Timoses wrote:
>>> Why does this fail?
>>
>> It doesn't. Not using DMD 2.081.1 under Windows, at least. I tried adding a bitfield since you mentioned it, but it compiles nicely for me. Which version of DMD are you using, and are you having the issues with the exact code you posted here?
>>
>> --
>> Simen
>
> https://run.dlang.io/is/Pgs527
>
> I'm on 2.080.1. But above is on latest 2.081.1 I believe.
>
> Note that the bottom code snippet in the original post does work, while the first one does not.
That makes sense. The problem is F has a context pointer to the main() block, since it's a non-static struct with methods inside a block. It doesn't actually use the context pointer for anything, so it possibly shouldn't have one, but it does, so we have to work around it.
The fix is to mark F as static, or move it outside the main() block.
--
Simen
|
July 18, 2018 Re: Implicit conversion of struct with methods to immutable in pure function fails | ||||
---|---|---|---|---|
| ||||
Posted in reply to Simen Kjærås | On Tuesday, 17 July 2018 at 06:24:12 UTC, Simen Kjærås wrote:
>
> That makes sense. The problem is F has a context pointer to the main() block, since it's a non-static struct with methods inside a block. It doesn't actually use the context pointer for anything, so it possibly shouldn't have one, but it does, so we have to work around it.
>
> The fix is to mark F as static, or move it outside the main() block.
>
> --
> Simen
Thanks for the explanation.
But why is a context pointer a problem? Is it problematic because the context pointer to the main scope can not guarantee `immutable`? E.g. if I happened to use data from main in a function of the immutable struct then... well then what?
The struct would still be immutable, but what would prevent a function from using non-immutable data?
E.g. I could do this
int gnumber = 3;
struct F
{
int i;
void fun() immutable
{
gnumber = 5;
}
}
void main ()
{
immutable F f = F();
f.fun;
}
I declared `fun()` to be an immutable function. So calling the immutable struct function `F.fun()` changes a module scope int. The same could be applied to local data of the main scope, however the following fails:
void main ()
{
int mnumber = 3;
struct F
{
int i;
void fun() immutable
{
// Error: immutable function onlineapp.main.F.fun cannot access mutable data mnumber
mnumber = 5;
}
}
immutable F f = F();
f.fun;
}
Is this connected why I can't implicitly convert a local struct with a context pointer to immutable? What's the reason behind it?
|
July 19, 2018 Re: Implicit conversion of struct with methods to immutable in pure function fails | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timoses | On Wednesday, 18 July 2018 at 11:28:54 UTC, Timoses wrote: > But why is a context pointer a problem? Is it problematic because the context pointer to the main scope can not guarantee `immutable`? E.g. if I happened to use data from main in a function of the immutable struct then... well then what? > The struct would still be immutable, but what would prevent a function from using non-immutable data? It's a known bug: https://issues.dlang.org/show_bug.cgi?id=18563 In the associated discussion (https://forum.dlang.org/thread/p7lp2b$1jod$1@digitalmars.com), Steven Schveighoffer points out that an immutable struct may be passed to other threads, which would give one thread access to another thread's stack. This could be a good enough reason to prevent this kind of conversion, but a better error message would still make sense. -- Simen |
July 19, 2018 Re: Implicit conversion of struct with methods to immutable in pure function fails | ||||
---|---|---|---|---|
| ||||
Posted in reply to Simen Kjærås | On Thursday, 19 July 2018 at 06:35:36 UTC, Simen Kjærås wrote:
> On Wednesday, 18 July 2018 at 11:28:54 UTC, Timoses wrote:
>> But why is a context pointer a problem? Is it problematic because the context pointer to the main scope can not guarantee `immutable`? E.g. if I happened to use data from main in a function of the immutable struct then... well then what?
>> The struct would still be immutable, but what would prevent a function from using non-immutable data?
>
> It's a known bug: https://issues.dlang.org/show_bug.cgi?id=18563
> In the associated discussion (https://forum.dlang.org/thread/p7lp2b$1jod$1@digitalmars.com), Steven Schveighoffer points out that an immutable struct may be passed to other threads, which would give one thread access to another thread's stack. This could be a good enough reason to prevent this kind of conversion, but a better error message would still make sense.
>
> --
> Simen
Thanks so much for the pointer, Simen. Interesting discussion.
|
Copyright © 1999-2021 by the D Language Foundation