Brush Up Language Features
Contents
Mangling Scheme
Consistently stop encoding return type of parent functions
Implemented: Issue 12352 - Consistently stop encoding return type of parent functions (commit)
Currently, for function local symbols, the return types of their parent functions are normally mangled into the name.
module test; int foo() { void bar() { struct S {} pragma(msg, S.mangleof); // S 4test 3fooFZi 3barMFZv 1S // | | // int of foo | // void of bar } return 0; }
But, for voldemort types, we already has an exception of the rule.
module test; auto foo() { auto bar() { struct S {} pragma(msg, S.mangleof); // S 4test 3fooFZ 3barMFZ 1S // | | // no return type for foo | // no return type for bar return S(); } return 0; }
The change was introduced to fix Issue 8847. https://d.puremagic.com/issues/show_bug.cgi?id=8847
In D, functions cannot be overloaded based on the return types.
void foo() {} int foo() {} // wrong overloading of foo
So the return type mangling is essentially redundant.
module test; void foo() { struct S {} pragma(msg, "1: ", S.mangleof); } void foo(int) { struct S {} pragma(msg, "2: ", S.mangleof); }
Current result;
1: S4test3fooFZv1S 2: S4test3fooFiZv1S
Modified result:
1: S4test3fooFZ1S 2: S4test3fooFiZ1S // --> The two local symbols S still have unique mangled names.
Do not mangle context-ness of parent lambdas
Lambdas are the only one element of D language which have context-inference.
void main() { int x; auto fp = (){ return 1; }; auto dg = (){ return x; }; static assert(!is(typeof(fp) == delegate)); static assert( is(typeof(dg) == delegate)); }
But the context-ness is normally mangled into the name:
MangledName: _D QualifiedName Type _D QualifiedName M Type
And has an undeterministic case for lambda local symbols:
module test; void main() { int x; auto y = (){ // __lambda1 struct S {} pragma(msg, S.mangleof); // S 4test 4mainFZv 9__lambda1MFZ 1S // or: S 4test 4mainFZv 9__lambda1FZ 1S ? // | // the context-ness of __lambda1 is not yet determined. version(A) return 1; else return x; }; }
To avoid the ambiguity, I think we should add a special mangling rule for lambdas:
module test; void main() { int x; auto y = (){ // __lambda1 struct S {} pragma(msg, S.mangleof); // S 4test 4mainFZv 9__lambda1 1S // | // stop mangling of the context, parameters, and return type version(A) return 1; else return x; }; }
Today, most of lambdas have unique names in the defined scope.
void main() { pragma(msg, __traits(identifier, {})); // __lambda1 pragma(msg, __traits(identifier, {})); // __lambda2 // in 'main' function, unique numbers are distributed. }
The proposed rule will work relying on the lambdas unique names.
Nested Symbols
Static alias parameter
void foo(alias sym)() { ... } void main() { static int x; int y; static class C { int z; } pragma(msg, typeof(&foo!x)); // the instantiated function will be global function pragma(msg, typeof(&foo!y)); // the instantiated function will be a local function of 'main' pragma(msg, typeof(&foo!(C.z))); // the instantiated function will be a member function of 'C' }
The behavior is necessary if foo will access to sym in runtime.
But, if sym is only needed for the compile-time calculation, foo!y
and foo!(C.z)
will cause need 'this' for ...
error in some cases.
Issue 11946 - "need 'this' to access member" when passing field to template parameter https://d.puremagic.com/issues/show_bug.cgi?id=11946
However, I think that inferring context-ness in general case is mostly impossible. A particular problem against the context inference is the deterministic mangling scheme for the local symbols of the inferred function. (Related: "Do not mangle context-ness of parent lambdas")
A small idea to avoid problems is:
void bar(static alias sym)() { ... } void main() { static int x; int y; static class C { int z; } pragma(msg, typeof(&bar!x)); // the instantiated function will be global function pragma(msg, typeof(&bar!y)); // the instantiated function will be global function pragma(msg, typeof(&bar!(C.z))); // the instantiated function will be global function // In all cases, bar will ignore the context of the symbol that passed to sym }
IFTI
Consider narrowing conversions for literal expressions
Implemented: Issue 12290 - IFTI should consider implicit conversions of the literal arguments (commit)
void foo(E)(E[], E) {} void main() { short[] arr; foo(arr, 1); // Current: E = common-type-of(short, int) => no match // Possible: E = common-type-of(short, typeof(1)) => E = short }
Related issue: improve common type calculation
auto a1 = true ? [1L,2] : [3,4]; // should work auto a2 = true ? [3,4] : [1L,2]; // should work