[Issue 1807] ENHANCEMENT: Let IFTI "see through" templates to simple aliases

d-bugmail at puremagic.com d-bugmail at puremagic.com
Tue Oct 11 21:31:16 UTC 2022


https://issues.dlang.org/show_bug.cgi?id=1807

--- Comment #11 from John Hall <john.michael.hall at gmail.com> ---
Creating a new type with an alias this'ed parameter is similar conceptually to
a template alias. The new type is implicitly convertible to the target of the
alias this and can be used wherever that original type was used. However, since
it is a separate type, it can't called called where the alias is used. 

```d
struct TemplateType(T) {}

//alias TemplateAlias(T) = TemplateType!T;
struct TemplateAlias(T) {
    TemplateType!T x;
    alias x this;
}

void templateFunction(T)(TemplateType!T arg) {}
void templateAliasFunction(T)(TemplateAlias!T arg) {}

void main()
{
    TemplateType!int inst;
    TemplateAlias!int ainst;

    templateFunction(inst);
    templateFunction(ainst);
    templateAliasFunction(inst); //doesn't compile
    templateAliasFunction(ainst); 
}
```

Perhaps what is needed is some kind of mechanism like alias this...not in the
sense of implicit conversion but in terms the programmer having the tools to
tell the compiler what to do.

The idea would be that your template alias would include an additional template
(with some rudimentary sketch below), call it `opResolveAlias`, that would let
the compiler know the relationships going in reverse (so instead of from the
alias to the alias target, this would be going from the alias target to the
alias). The compiler could then make use of that information to make sure the
function call can properly occur (with type inference as needed). 

So for instance, if you have a function that accepts a `TemplateAlias!T`
parameter, but pass in a `TemplateType!int` parameter, then currently the
compiler doesn't look through the `TemplateAlias!T` to see that
`TemplateType!int` is the same. However, if the compiler knows that a
`TemplateType!int` is the same as `TemplateAlias!int`, then it would be better
able to proceed. 

```d
template TemplateAlias(T) {
    alias TemplateAlias = TemplateType!T;

    template opResolveAlias(alias U)
        if(is(U == TemplateType!V, V))
    {
        alias opResolveAlias = TemplateAlias!V;
    }
}
```

For simple cases like this, the compiler could generate its own
`opResolveAlias`, but in the more general case it would be up to the user to
provide it if it is important to them.

Issue 16486 has an example of a more complicated template alias [1] that should
still be able to have this approach applied:

```d
template TestAlias(T)
{
    static if (is(T == float)) alias TestAlias = TestType!int;
    else alias TestAlias = string;

    // new part:
    template opResolveAlias(alias U)
    {
        static if (is(U == TestType!int)) {
            alias opResolveAlias = TestAlias!float;
        } else static if (is(U == string)) {
            alias opResolveAlias = TestAlias!int; //could put anything there
that's not float...not the most elegant
        }
    }
}
```

[1] https://issues.dlang.org/show_bug.cgi?id=16486#c1

--


More information about the Digitalmars-d-bugs mailing list