August 16, 2016
https://issues.dlang.org/show_bug.cgi?id=16394

--- Comment #10 from Steven Schveighoffer <schveiguy@yahoo.com> ---
A compile time error isn't possible, as this is a virtual function. It would have to be a runtime error, which I think is even worse.

Let's just fix the docs, any bugs that are in druntime/Phobos, and move on. I don't understand the pushback on this, TypeInfo.initializer is for druntime internals, and those who need it for low-level memory management code. It's not commonly used, so there aren't many places to fix. The current implementation is entirely reasonable (why store N copies of the same thing?).

--
August 16, 2016
https://issues.dlang.org/show_bug.cgi?id=16394

--- Comment #11 from ag0aep6g@gmail.com ---
Alright, these are arguments for changing the documentation instead of the implementation:

1) Changing the behavior would break existing code.
2) It's hard or impossible to fix in a satisfactory way. In particular: binary
bloat.

If I'm missing or misrepresenting anything, please yell at me.

Re 1: I agree that it may break existing code, which isn't good. I don't assign a lot of value to this, though. I.e., yes it's a bit bad, but in my opinion the bad doesn't outweigh the good we would get from having the function behave as documented. The documented behavior is far more sensible (to the user) than the actual behavior. The code that would get broken by a fix is likely workaround code for the inconsistency.

Re 2: I don't know how much bloat a fix would add, but consider that we can embed a static array in a struct, and `initializer` works as documented then. So that case has the bloat and everything seems to be just fine.

In code:
----
struct S { char[3] a; }
void main()
{
    assert(typeid(S).initializer == "\xFF\xFF\xFF"); /* passes */
    assert(typeid(char[3]).initializer == "\xFF\xFF\xFF"); /* fails */
}
----

--
August 16, 2016
https://issues.dlang.org/show_bug.cgi?id=16394

--- Comment #12 from Steven Schveighoffer <schveiguy@yahoo.com> ---
3) Changing the compiler potentially introduces new issues. Changing the docs does not.

--
August 16, 2016
https://issues.dlang.org/show_bug.cgi?id=16394

--- Comment #13 from Steven Schveighoffer <schveiguy@yahoo.com> ---
changing the compiler when the existing code works JUST FINE as long as it's properly understood and documented seems like a horrible idea to me.

It would be a different story if it was not possible to properly initialize a static array using the TypeInfo.

The current code also returns an array that is null, but with a non-zero length when the initializer would otherwise be all zeros to save on binary space. That's a weird behavior, but somehow we live just fine with that. I don't see why we can't document the other weird, yet legitimate, behavior.

--
August 16, 2016
https://issues.dlang.org/show_bug.cgi?id=16394

--- Comment #14 from ag0aep6g@gmail.com ---
(In reply to Steven Schveighoffer from comment #12)
> 3) Changing the compiler potentially introduces new issues. Changing the docs does not.

(In reply to Steven Schveighoffer from comment #13)
> changing the compiler when the existing code works JUST FINE as long as it's properly understood and documented seems like a horrible idea to me.

Ok, I guess we just disagree on this. I don't think we should shy away from fixing issues properly (<- just my opinion) because the code is so fragile that every touch could break stuff elsewhere.

> It would be a different story if it was not possible to properly initialize a static array using the TypeInfo.

It's possible, but even when documented, `initializer`'s behavior is surprising. I.e., it's likely to be missed/forgotten, bug-prone.

> The current code also returns an array that is null, but with a non-zero length when the initializer would otherwise be all zeros to save on binary space. That's a weird behavior, but somehow we live just fine with that. I don't see why we can't document the other weird, yet legitimate, behavior.

In no particular order:

1) That's documented. Yes, I know, we would make the other weirdness documented, too. But it isn't yet, so we an opportunity to do it differently, whereas the all-zeroes ship has sailed. If all-zeroes were undocumented today, I'm not sure what way of dealing with it I would prefer.

2) All-zeroes is the same for all types. You don't have to check for one specific kind of type, and then handle the result of `initializer` differently. You have to check all return values of `initializer` equally. That's significantly more consistent. It fails way earlier.

By the way, I would say that TypeInfo_StaticArray.initializer violates substitutability when it behaves differently from the others. Documenting it on the base class that a derived class behaves differently just makes it a substitutability violation that we try to handwave our way out of.

3) The point is basically: "We already have one corner case, let's add one more." I don't think that's the way to go. Minimizing the number corner cases should be the goal.

Overall, having `initializer` return an array seems like a bad design decision, since we try to bend/break it whenever the result consists of repeated values. Maybe we should come up with something that handles repetitive cases more gracefully, and then get rid of `initializer` (slowly with a full deprecation cycle, of course).

--
August 16, 2016
https://issues.dlang.org/show_bug.cgi?id=16394

--- Comment #15 from Steven Schveighoffer <schveiguy@yahoo.com> ---
I just disagree that the current behavior is a bug. Note that this wasn't documented to begin with, and whoever documented it (probably me) didn't realize the corner case behavior. This was never a code bug IMO, it's working as designed.

The runtime is full of undocumented implementation behaviors. Having worked many times on fixing things, there's quite a few cases where the compiler and runtime interact in weird undocumented ways. Documenting them is the first step, then if we want to change it, then we change it with a proper discussion with the main players.

I'm working on 2 PRs, one to fix the docs, and one to fix std.algorithm.mutation.initializeAll (the only affected code in druntime or Phobos).

Even if we get a dmd upgrade at some point, I'd like to at least fix the current problems.

Interestingly enough, TypeInfo.initializer is rarely needed, because most of the time, you have the static type, and that is usually plenty to get this working.

--
August 16, 2016
https://issues.dlang.org/show_bug.cgi?id=16394

--- Comment #16 from Steven Schveighoffer <schveiguy@yahoo.com> ---
(In reply to Eyal from comment #1)
> Prints out:
> [Int(1, 7FE7FED92000), Int(2, 7FE7FED92000)]
> [Int(3, null), Int(0, 73)]
> 
> The second field being printed for Int seems like *yet another* bug.

The other field being printed is the context pointer, since your struct is nested in the unittest.

--
August 16, 2016
https://issues.dlang.org/show_bug.cgi?id=16394

--- Comment #17 from Eyal <eyal@weka.io> ---
> The other field being printed is the context pointer, since your struct is nested in the unittest.

Yeah, I've since figured it out - but was surprised because it is inconsistent with code blocks like: x=>x+1 which is inferred to be a function, not a delegate.  So I expected structs to be similarly inferred to static structs when they do not actually need the context ptr.

--
August 16, 2016
https://issues.dlang.org/show_bug.cgi?id=16394

--- Comment #18 from Steven Schveighoffer <schveiguy@yahoo.com> ---
druntime documentation PR: https://github.com/dlang/druntime/pull/1634 phobos initializeAll PR: https://github.com/dlang/phobos/pull/4736

--
August 16, 2016
https://issues.dlang.org/show_bug.cgi?id=16394

Steven Schveighoffer <schveiguy@yahoo.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |pull, spec

--