On Sunday, June 2, 2019 1:29:22 PM MDT Jonathan M Davis via Digitalmars-d- learn wrote: > On Sunday, June 2, 2019 8:32:16 AM MDT Paul Backus via Digitalmars-d-learn > wrote: > > On Sunday, 2 June 2019 at 06:59:02 UTC, Jonathan M Davis wrote: > > > Almost certainly, hasElaborateCopyConstructor should be updated > > > to test for both postblit constructors and copy constructors, > > > since its purpose is to test for whether the type has a > > > user-defined copying function [...] Whether > > > hasElaborateCopyConstructor was the best name is debatable, but > > > it _does_ involve "elaborate" copying, and copy constructors > > > weren't actually in the language at the time. The documentation > > > is wonderfully confusing though in that it talks about copy > > > constructors and then says that a copy constructor is > > > introduced by defining this(this) for a struct. So, it > > > basically calls a postblit constructor a copy constructor. > > > > I've made the mistake in the past of trying to use > > hasElaborateCopyConstructor to test for the presence of > > __xpostblit, and I'm sure I'm not the only one. The name is quite > > misleading--even more so now that D has real copy constructors. > > > > If std.v2 ever materializes, we'll have an opportunity to fix > > papercuts like this. Until then, my preferred workaround is to > > use a renaming import: > > > > import std.traits: hasNontrivialCopy = > > hasElaborateCopyConstructor; > > Why is it a mistake to use hasElaborateCopyConstructor to test for > __xpostblit? Because you're trying to test for __xpostblit for some > purpose other than determining whether the type is blittable? I'm not > sure what other reason there would be to test for __xpostblit though. > Either way, hasElaborateCopyConstructor currently checks for exactly that > (with the addition that it checks whether a static array has elements > with __xpostblit): > > template hasElaborateCopyConstructor(S) > { > static if (__traits(isStaticArray, S) && S.length) > { > enum bool hasElaborateCopyConstructor = > hasElaborateCopyConstructor! (typeof(S.init[0])); > } > else static if (is(S == struct)) > { > enum hasElaborateCopyConstructor = __traits(hasMember, S, > "__xpostblit"); > } > else > { > enum bool hasElaborateCopyConstructor = false; > } > } > > My point was that given the purpose of hasElaborateCopyConstructor, > updating it to test for both a postblit constructor and copy constructor > would be appropriate. In fact, the fact that it hasn't been means that > the introduction of copy constructors has broken existing code (or at > least that such code won't interact correctly with structs that have copy > constructors). There should be no need to rename the trait, just update > it, and whether it uses the name "elaborate" or "non-trivial" is pretty > much irrelevant. Personally, I probably would have chosen hasNonTrivial > over hasElaborate, but they mean the same thing, and we have > hasElaborateDestructor for the corresponding test for destructors and > hasElaborateAssign for the corresponding test for assignment. It really > doesn't make sense to change the name at this point.
It looks like Manu already reported a bug on this: https://issues.dlang.org/show_bug.cgi?id=19902 - Jonathan M Davis