Designing interfaces with the assumption that a template will compile if the arguments match leads to silent failure. std.conv.text is one such offender. If a templated toString exists for the type but causes compiler errors on instantiation, text() will incorrectly fall back on some other method.
Example:
```
void main() {
writeln(X().text); //X(false)? That's not what I wanted!
}
struct X {
bool a;
void toString(T)(T sink) {
easilyMistypedMethod(sink);
}
void easilyMisspelledMethod(T)(T sink) {
put(sink, "Hello!");
}
}
```
I'd like to propose a simple trait to resolve this.
Example:
```
void x(T : int)() {
nonexistent();
}
static assert(!__traits(compiles, x!bool()));
static assert(__traits(templateMatches, x, int));
static assert(__traits(templateMatches, x, short));
static assert(!__traits(templateMatches, x, string));
void doSomething(alias T)() {
static if(__traits(templateMatches, T, int)) {
T!int();
}
}
static assert(!__traits(compiles, doSomething!x())); //x!int exists, but doesn't compile, so this is expected
```
Comment #1 by robert.schadek — 2024-12-13T19:01:29Z