[Issue 19125] IFTI and inout removes head mutability qualifier on by-val parameters
d-bugmail at puremagic.com
d-bugmail at puremagic.com
Mon Jul 30 13:16:55 UTC 2018
https://issues.dlang.org/show_bug.cgi?id=19125
Steven Schveighoffer <schveiguy at yahoo.com> changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |schveiguy at yahoo.com
--- Comment #1 from Steven Schveighoffer <schveiguy at yahoo.com> ---
The issue here is that IFTI applies inout to the head when it shouldn't
If you have a function like this:
struct S(T)
{
T t;
}
inout(S!T) makeS(T)(inout(T) t)
{
return inout S!T(t);
}
One expects the type parameter of S to match the type parameter passed in.
inout is just saying "I'm not going to change anything"
However, in the case of types that have tail-mutability modifier capability
(pointers, arrays), IFTI is pulling the mutability OUT from the tail and
applying it to the entire parameter:
auto s1 = makeS("hello");
assert(is(typeof(s1) == immutable(S!(char[])));
auto s2 = makeS("hello".ptr);
assert(is(typeof(s2) == immutable(S!(char *));
But tail-modified values are distinctly more capable in terms of mutability
than fully modified values. So IFTI I believe should NOT perform this
adjustment, and just match T as string (and therefore the type of t should be
inout(string)).
If one wishes to actually match inout to the modifier of the tail, one can do
so with a specialization:
auto makeS(T)(inout(T)[] t)
{
return inout S!(T[])(t);
}
Note that the use of auto ref in the original code is affecting what is
inferred, because of the double-indirection rule. This makes it doubly
confusing (see the cases for wrap0("foo") and wrap0(s0), which one might expect
to be identical ).
--
More information about the Digitalmars-d-bugs
mailing list