Anybody here knows since when we don't have to write when calling generic ProcSomething(param: T)?

Anybody here knows since when we don't have to write when calling generic ProcSomething(param: T)?

It was brought to my attention today that the following code compiles and works as expected and I was quite surprised.

program Project17;

{$APPTYPE CONSOLE}

{$R *.res}

uses
System.SysUtils;

type
TGeneric = class
class procedure GuessTheType(const value: T);
end;

var
x: Exception;
s: TSimpleRWSync;

{ TGeneric }

class procedure TGeneric.GuessTheType(const value: T);
begin
end;

begin
TGeneric.GuessTheType(x);
TGeneric.GuessTheType(x);
TGeneric.GuessTheType(s);
end.

A quick look into the generated assembler code proves that the type is indeed resolved correctly:

Project17.dpr.26: TGeneric.GuessTheType(x);
0041C530 8B151C484200 mov edx,[$0042481c]
0041C536 A1F4974100 mov eax,[$004197f4]
0041C53B E84CD3FFFF call TGeneric.GuessTheType
Project17.dpr.27: TGeneric.GuessTheType(x);
0041C540 8B151C484200 mov edx,[$0042481c]
0041C546 A1F4974100 mov eax,[$004197f4]
0041C54B E83CD3FFFF call TGeneric.GuessTheType
Project17.dpr.28: TGeneric.GuessTheType(s);
0041C550 8B1520484200 mov edx,[$00424820]
0041C556 A1F4974100 mov eax,[$004197f4]
0041C55B E83CD3FFFF call TGeneric.GuessTheType

Tested in Berlin and Tokyo.

Comments

  1. P.S. This is neither bug nor issue but I couldn't find a better category for the post.

    ReplyDelete
  2. AFAIK this has been in the compiler since generic methods in non-generic classes have been introduced. The compiler infers the type from the parameter. Of course, there are times you don't want this to happen -- if the param is 200 you might want to force "Integer" rather then Byte of what the compiler would map the small number to

    ReplyDelete
  3. Type inference for generic methods, described here: "There are two ways to instantiate a method:
    - Explicitly specifying type argument
    - Automatically inferring from the type argument"

    docwiki.embarcadero.com - Declaring Generics - RAD Studio

    ReplyDelete
  4. Thank you, guys! I was not aware that this existed at all!

    ReplyDelete
  5. This is a rare piece of code where type inference actually works. Mostly it does not which is very frustrating.

    It's a little ironic that you ask why you don't need to include . Normally people ask about the much more frequent instances where you do need to include because the compiler's type inference is so weak.

    ReplyDelete
  6. Marco Cantù Much more commonly there are times when you want the compiler to infer the type, but it won't. It would really make a difference to us if the compiler was better at this.

    ReplyDelete
  7. David Heffernan I tend to agree the compiler should be much better at type inference. Working on it!

    ReplyDelete
  8. Infering the generic argument from a constructed generic type would be great.

    GuessTheType(const x: TArray);

    var
    a: TArray;
    begin
    GuessTheType(a);

    does not work although the compiler could infer the parameter for GuessTheType from its x parameter but currently it does not know that a originally was a TArray (yes, I know array of T as signature works but that is a different thing).

    P.S. Marco Cantù btw how hard can it be to finally implement generic standalone routines without that ugly static type? Probably one of the highest voted feature requests: https://quality.embarcadero.com/browse/RSP-13724)

    ReplyDelete

Post a Comment