Here's a clearer presentation of the issue:

void f(T)(const(T)[] x, const(T)* y) {}
void test()
{
    // this works; f(T) is inferred as f!int
    int[] x;
    const int y;
    f(x, &y);

    // fails: expected that f(T) is inferred as f!(int*)
    int*[] a;
    const int* b;
    f(a, &b);
}

Removing `const` from `y` and `b` makes the problem go away, so I think this is a bug in some interaction between the type deduction logic and parameter const promotion?

On Thu, 3 Oct 2024 at 09:34, Manu <turkeyman@gmail.com> wrote:
On Wed, 2 Oct 2024 at 20:06, kdevel via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
On Wednesday, 2 October 2024 at 08:55:15 UTC, Manu wrote:
> Does anyone understand why this doesn't work?
>
> void f(T)(const(T)[] x, const(T)* y) {}
> void test()
> {
>     int*[] x;
>     const int* y;
>     f(x, &y);
> }
>
> error : template `f` is not callable using argument types
> `!()(int*[],
> const(int*)*)`
>         Candidate is: `f(T)(const(T)[] x, const(T)* y)`
>
> Should this work? It looks like it should work to me.
> ...assuming T is inferred to be `int*`... which it's not clear
> why it
> wouldn't be?
>
> The argument `y` is an exact match.

The second actual parameter to f!int is &y not y.

Yes, the `y` argument is `const(int*)*`, so `T` must be inferred `int*`

> The argument `x` requires a const promotion,

The type of x is int*[] and not const(int) [];

Right, `x` is `int*[]`, and matching the argument `const(T)[]` required const promotion `int*[]` -> `const(int*)[]`, which is a perfectly normal promotion. In which case, `T` is `int*`, matching with `y`, and so `T` can be properly inferred.

If you remove the `*` from `x` and `y`, the `T` inference works properly... so something about `T` being inferred as `int*` rather than an `int` causes the type inference to fail.
The non-uniformity looks like a bug, unless there's a reasonable explanation that I've missed.