The following code works fine in DMD 2.065.0:
void main ()
{
ModuleInfo* minfo;
foreach (m ; ModuleInfo)
minfo = m;
}
But in DMD 2.066.0-b1 the delegate parameter in ModuleInfo.opApply expects an immutable ModuleInfo*. This is a breaking change and a regression.
Is it possible to fix this by overloading opApply with a mutable parameter?
I assumed that, but i still breaks code. What about the standard deprecation cycle?
Comment #3 by k.hara.pg — 2014-07-11T12:50:03Z
(In reply to Jacob Carlborg from comment #2)
> I assumed that, but i still breaks code. What about the standard deprecation
> cycle?
Unfortunately, it's impossible. We cannot allow iterating both mutable and immutable objects by ModuleInfo.opApply, because it will cause type system violation. We should change the opApply signature all at once.
And compiler already place all ModuleInfo in read-only section. So modifying ModuleInfo will cause segfault in some platforms. It's more worse.
Comment #4 by bugzilla — 2014-07-12T04:44:42Z
Hmm. Suppose we did this:
alias immutable(_ModuleInfo) ModuleInfo;
?
Comment #5 by doob — 2014-07-12T12:40:49Z
(In reply to Walter Bright from comment #4)
> Hmm. Suppose we did this:
>
> alias immutable(_ModuleInfo) ModuleInfo;
>
> ?
It would still break the API.
Comment #6 by doob — 2014-07-12T12:42:22Z
(In reply to Kenji Hara from comment #3)
> And compiler already place all ModuleInfo in read-only section. So modifying
> ModuleInfo will cause segfault in some platforms. It's more worse.
How can you modify ModuleInfo when all its members (methods and fields) are const?
Comment #7 by bugzilla — 2014-07-12T17:41:24Z
(In reply to Jacob Carlborg from comment #5)
> (In reply to Walter Bright from comment #4)
> > Hmm. Suppose we did this:
> >
> > alias immutable(_ModuleInfo) ModuleInfo;
> >
> > ?
>
> It would still break the API.
How? (I know it will break people modifying ModuleInfo at runtime, but anything else?)
Comment #8 by doob — 2014-07-12T20:19:54Z
(In reply to Walter Bright from comment #7)
> How? (I know it will break people modifying ModuleInfo at runtime, but
> anything else?)
If I understand you correctly the current ModuleInfo would be renamed to _ModuleInfo and a new immutable alias would be added, named ModuleInfo?
The ModuleInfo I have declared would be immutable? That could work. I will work for the function where I found the problem but it returns the module info and I have not looked yet how the returned value is used.
Comment #9 by bugzilla — 2014-07-13T06:09:45Z
(In reply to Jacob Carlborg from comment #8)
> If I understand you correctly the current ModuleInfo would be renamed to
> _ModuleInfo and a new immutable alias would be added, named ModuleInfo?
Yes.
> The ModuleInfo I have declared would be immutable?
Yes.
> That could work. I will
> work for the function where I found the problem but it returns the module
> info and I have not looked yet how the returned value is used.
(In reply to Walter Bright from comment #9)
> (In reply to Jacob Carlborg from comment #8)
> > If I understand you correctly the current ModuleInfo would be renamed to
> > _ModuleInfo and a new immutable alias would be added, named ModuleInfo?
>
> Yes.
>
> > The ModuleInfo I have declared would be immutable?
>
> Yes.
>
> > That could work. I will
> > work for the function where I found the problem but it returns the module
> > info and I have not looked yet how the returned value is used.
I don't think it's good idea. It would introduce confusing than benefits.
Comment #12 by bugzilla — 2014-07-13T09:18:54Z
(In reply to Kenji Hara from comment #11)
> I don't think it's good idea. It would introduce confusing than benefits.
Please explain. What confusion?
Comment #13 by k.hara.pg — 2014-07-13T10:07:51Z
(In reply to Walter Bright from comment #12)
> (In reply to Kenji Hara from comment #11)
> > I don't think it's good idea. It would introduce confusing than benefits.
>
> Please explain. What confusion?
All D programmers would assume that unqualified type name T is a mutable type, and const(T) is const, immutable(T) is immutable.
But, the proposed idea will break the assumption - all ModuleInfo, const(ModuleInfo), immutable(ModuleInfo) will be same immutable. it's very confusing situation.
Comment #14 by doob — 2014-07-13T10:09:11Z
(In reply to Kenji Hara from comment #13)
> All D programmers would assume that unqualified type name T is a mutable
> type, and const(T) is const, immutable(T) is immutable.
>
> But, the proposed idea will break the assumption - all ModuleInfo,
> const(ModuleInfo), immutable(ModuleInfo) will be same immutable. it's very
> confusing situation.
Hmm, that's a good point.
Comment #15 by bugzilla — 2014-07-13T19:09:46Z
(In reply to Kenji Hara from comment #13)
> All D programmers would assume that unqualified type name T is a mutable
> type,
There were some bumps in transitioning to the immutable alias 'string', but it all turned out for the best. The compiler complains if you do anything wrong, and this proposal fixes the breaking code issue.
Comment #16 by doob — 2014-07-13T19:30:56Z
Find another project with the same error.
Comment #17 by bugzilla — 2014-07-13T21:27:01Z
(In reply to Jacob Carlborg from comment #16)
> Find another project with the same error.
??
Comment #18 by doob — 2014-07-13T21:41:29Z
(In reply to Walter Bright from comment #17)
> (In reply to Jacob Carlborg from comment #16)
> > Find another project with the same error.
>
> ??
I'm just indicating that there are more than one project that is affected by this.
Comment #19 by code — 2014-07-14T00:56:34Z
(In reply to Jacob Carlborg from comment #18)
> I'm just indicating that there are more than one project that is affected by
> this.
Affected by what? If you know one, why not name it?
Comment #20 by doob — 2014-07-14T07:38:32Z
(In reply to David Nadlinger from comment #19)
> Affected by what? If you know one, why not name it?
Affected by the issue I reported here. Or rather the change that causes this issue. The projects I've found this in so far is DWT and Tango.
Comment #21 by k.hara.pg — 2014-07-17T04:20:52Z
(In reply to Walter Bright from comment #15)
> (In reply to Kenji Hara from comment #13)
> > All D programmers would assume that unqualified type name T is a mutable
> > type,
>
> There were some bumps in transitioning to the immutable alias 'string',
Note that, string == immutable(char)[], it is _mutable_ array of immutable elements. It's different.
Comment #22 by code — 2014-07-17T23:02:46Z
I posted a little overview of the situation at the druntime pull request page.
Comment #23 by public — 2014-07-17T23:52:28Z
> All D programmers would assume that unqualified type name T is a mutable type, and const(T) is const, immutable(T) is immutable.
What? Sounds like total nonsense. I use aliases of qualified types all the time, it is a very useful tool for enforcing certain qualified semantics. Programmers that expect that must have never read the docs.
I think it is a reasonable solution.
Comment #24 by k.hara.pg — 2014-07-18T02:10:02Z
(In reply to Dicebot from comment #23)
> > All D programmers would assume that unqualified type name T is a mutable type, and const(T) is const, immutable(T) is immutable.
>
> What? Sounds like total nonsense. I use aliases of qualified types all the
> time, it is a very useful tool for enforcing certain qualified semantics.
> Programmers that expect that must have never read the docs.
>
> I think it is a reasonable solution.
In your code, you can have such aliases. But don't add such alias in standard library code. It will introduce much limited situation than benefits.
For example, in the proposal original mutable name _ModuleInfo is private and inaccessible. So if a programmer want to use const ModuleInfo, he should write it like const(Unqual!ModuleInfo). Why Unqual is necessary? In other words, you assumes that most D programmers won't use non-immutable ModuleInfo in their code. I think it's not reasonable assumption.
Comment #25 by bugzilla — 2014-07-18T07:47:30Z
Let's list a few objective facts:
1. The current situation (this bug report) occurs in the wild in real code in more than one project. Existing code is broken.
2. https://issues.dlang.org/show_bug.cgi?id=13148 has not been shown to occur anywhere in existing code, it is conjecture. A reason to write such code has not been demonstrated.
3. If there is a reason to write 13148 code, it can be fixed with the Unqual!ModuleInfo change.
4. In either solution, using ModuleInfo incorrectly will result in compiler errors, not silent corruption.
Therefore it seems highly likely that there will be far more instances of requiring users to write immutable(ModuleInfo) than Unqual!ModuleInfo. Making ModuleInfo an immutable alias thus breaks far less existing code.
(Inferring that an unadorned type name would necessarily be mutable comes as a surprise to me. This assumption is not stated anywhere in the documentation nor in common usage. A grep of phobos/std shows immutable aliases occurring. It's one of the things alias is for.)
Comment #26 by public — 2014-07-18T10:08:49Z
> In your code, you can have such aliases. But don't add such alias in standard library code. It will introduce much limited situation than benefits.
This is just your preference, there is nothing standard about it. Such solution is introduced exactly to impose limits and make using unqualified type harder. Forcing certain type to be always used as immutable is not unheard of which also means that you don't normally need const version of same type - because, well, it is always meant to be immutable.
On actual topic: is there any reason why ModuleInfo itself needs to be immutable and marking all its data members is not enough? That should still make all the the options from PR #790 valid or am I missing something?
Comment #27 by doob — 2014-07-18T19:43:09Z
(In reply to Dicebot from comment #26)
> On actual topic: is there any reason why ModuleInfo itself needs to be
> immutable and marking all its data members is not enough? That should still
> make all the the options from PR #790 valid or am I missing something?
Exactly, I've already asked that but didn't get a reply on that question. Is it possible to write to the pointer that will cause problems?
Comment #28 by bugzilla — 2014-07-19T04:17:01Z
(In reply to Jacob Carlborg from comment #27)
> (In reply to Dicebot from comment #26)
>
> > On actual topic: is there any reason why ModuleInfo itself needs to be
> > immutable and marking all its data members is not enough? That should still
> > make all the the options from PR #790 valid or am I missing something?
>
> Exactly, I've already asked that but didn't get a reply on that question. Is
> it possible to write to the pointer that will cause problems?
ModuleInfo is a variable sized struct that is decoded at runtime. The two explicit fields are only the start of it. Making the whole thing immutable makes the intent clear.
Comment #29 by public — 2014-07-19T12:29:16Z
Is it possible to apply usual C idiom for variadic length structs? Something like this:
struct ModuleInfo
{
immutable:
uint _flags;
uint _index;
void[0] payload;
/* methods */
}
I am not sure it is legal application of immutable qualifier though.
Comment #30 by code — 2014-07-21T21:21:47Z
(In reply to Dicebot from comment #26)
> On actual topic: is there any reason why ModuleInfo itself needs to be
> immutable and marking all its data members is not enough? That should still
> make all the the options from PR #790 valid or am I missing something?
Well, without breaking the type system, the runtime only has access to an array of immutable pointers to ModuleInfos.
Comment #31 by github-bugzilla — 2014-07-25T07:11:29Z