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. - Jonathan M Davis