Thread overview
Static functions calls should only resolve to static functions
6 days ago
Salih Dincer
October 21

Currently, the combining of static and non-static function overloads can cause static overloads to be ignored, even when these are the only fit.

I have been told this is simply the way it is. Although I would consider this a bug. It's even slightly problematic for my static OpDispatch code (workarounds always exist ...).
Given the self-contradicting documentation & differing views, I'm here suggesting it as an improvement. (If it is to be considered a bug I would love to hear it)

Code Example:

import std;

class A {
    void foo(int a, bool b) {
        writeln("foo");
    }
    static void foo(T...)(T args) {
        writeln("static foo");
    }
}

void main(){
     A.foo(1,true); // calling non-static function `foo` requires an instance of type `A`
}

Documentation:

(https://dlang.org/spec/function.html#function-overloading)

>
  1. Each argument (including any this reference) is compared against the function's corresponding parameter to determine the match level for that argument. The match level for a function is the worst match level of each of its arguments.

Thus one would expect this (or an absence of) to be considered during function resolution; static calls should be resolved to static functions.

>
  1. A static member function can be overloaded with a member function. The struct, class or union of the static member function is inferred from the type of the this argument.

The intent in this sentence seems to be to indicate non-static calls can drop their implicit this reference. Though the sentence is very confusing.

The examples contained within the documentation meanwhile describe the current state of things. (No wonder, as they're unittests and need to pass)


Suggestion / Expectation:

Given static calls are not using an implicit this reference, and are explicitly bound to using static functions, I suggest their calls should only ever resolve to static functions. The code above should then compile and print "static foo".

This would not break anything, and would make the overloading much more intuitive.

October 21

On Monday, 21 October 2024 at 01:22:02 UTC, HuskyNator wrote:

>

Currently, the combining of static and non-static function overloads can cause static overloads to be ignored, even when these are the only fit.

Simplified example:

struct S
{
    void foo(byte) {}
    static void foo(int) {}
}

void main()
{
    byte arg;
    S.foo(arg); // resolves to foo(byte)
}
6 days ago

On Monday, 21 October 2024 at 01:22:02 UTC, HuskyNator wrote:

>

Suggestion / Expectation:

Given static calls are not using an implicit this reference, and are explicitly bound to using static functions, I suggest their calls should only ever resolve to static functions. The code above should then compile and print "static foo".

This would not break anything, and would make the overloading much more intuitive.

I agree with your published suggestion and find it appropriate. Because only one of the following versions (s) is compiled. However, if your suggestion is implemented, version i will also be made to work. Thank you for sharing your intuitive idea.

version = s;
struct S
{
  version(i) // onlineapp.d(29): Error:
  {// calling non-static function `foo` requires an instance of type `S`
    void foo(ubyte u) {}
    static void foo(T)(T i) {}
  }

  version(u) // onlineapp.d(30): Error:
  {// calling non-static function `foo` requires an instance of type `S`
    static void foo(ubyte u) {}
    void foo(T)(T i) {}
  }

  version(s)
  {// Works:
    static
    {
      void foo(ubyte u) {1.write;}
      void foo(T)(T i) {2.write;}
    }
  }
}

void main()
{
  ubyte arg;
  S.foo(arg); // prints 1
  S.foo(int.max); // prints 2

  S s;
  s.foo(arg); // prints 1
  s.foo(int.max);// prints 2
}

SDB@79