Jump to content
rgdawson

Case: Please Explain Why Inline Variable Prevents Compilation

Recommended Posts

I was experimenting with inline variable definitions and came across a case that I do not understand, so I made a very simple example.  See Foo1 and Foo2 below.  The only difference is where I define the variables.  No type inference going on, nothing that unusual to my eyes, except that the type IShared<T>, from Spring4D, is defined as reference to function: T.

 

Foo2 will not compile and I get an error: E2250 There is no overloaded version of 'Post' that can be called with these arguments.

 

procedure Foo1; {<--Compiles}
var
  Http: IShared<TIdHttp>;
  Request  : IShared<TStringStream>;
  Response : IShared<TStringStream>;
begin
  Http := Shared.Make(TIdHttp.Create);
  Request := Shared.Make(TStringStream.Create('Foo'));
  Response := Shared.Make(TStringStream.Create);

  Http.Post('Foo', Request, Response);
end;

procedure Foo2; {<-- Will not compile}
begin
  var Http: IShared<TIdHttp>;
  var Request: IShared<TStringStream>;
  var Response: IShared<TStringStream>;

  Http := Shared.Make(TIdHttp.Create);
  Request := Shared.Make(TStringStream.Create('Foo'));
  Response := Shared.Make(TStringStream.Create);

  Http.Post('Foo', Request, Response);  {<--Fails on this line}  
end;

Can someone explain what is going on here?

 

 

 

 

Share this post


Link to post

I can reproduce the problem in a simple example that doesn't involve Spring4D (however, I get an "E2010 Incompatible types" error instead of an E2250) :

 

type
  IShared<T> = reference to function: T;

  Shared = class
    class function Make<T: class>(AObj: T): IShared<T>;
  end;

  TSharedImpl<T: class> = class(TInterfacedObject, IShared<T>)
    FObj: T;
    constructor Create(AObj: T);
    destructor Destroy; override;
    function Invoke: T;
  end;

  TTest = class
  end;

  TTester = class
    procedure DoTest(AObj: TTest);
  end;

class function Shared.Make<T>(AObj: T): IShared<T>;
begin
  Result := TSharedImpl<T>.Create(AObj) as IShared<T>;
end;

constructor TSharedImpl<T>.Create(AObj: T);
begin
  inherited Create;
  FObj := AObj;
end;

destructor TSharedImpl<T>.Destroy;
begin
  FObj.Free;
  inherited Destroy;
end;

function TSharedImpl<T>.Invoke: T;
begin
  Result := FObj;
end;

procedure TTester.DoTest(AObj: TTest);
begin
  //...
end;

procedure Foo1;
var
  Tester  : IShared<TTester>;
  TestObj : IShared<TTest>;
begin
  Tester := Shared.Make(TTester.Create);
  TestObj := Shared.Make(TTest.Create);

  Tester.DoTest(TestObj); // <-- Compiles OK!
end;

procedure Foo2;
begin
  var Tester: IShared<TTester>;
  var TestObj: IShared<TTest>;

  Tester := Shared.Make(TTester.Create);
  TestObj := Shared.Make(TTest.Create);

  Tester.DoTest(TestObj); // <-- E2010 Incompatible types: 'TTest' and 'IShared<TTest>'
  Tester.DoTest(TestObj()); // <-- Compiles OK!
end;

I have now reported this issue to Embarcadero:

 

RSS-2613: Anonymous Method is called differently depending on whether it is declared as an Inline Variable or not

 

Edited by Remy Lebeau
  • Thanks 2

Share this post


Link to post

Most simple case to repro to compiler error:

procedure X(i: Integer);
begin
end;

procedure Y;
begin
  var f: TFunc<Integer>;
  X(f);
end;

 

Share this post


Link to post
7 hours ago, Stefan Glienke said:

Most simple case to repro to compiler error:

Show off 😉

7 hours ago, Stefan Glienke said:

procedure X(i: Integer);
begin
end;

procedure Y;
begin
  var f: TFunc<Integer>;
  X(f);
end;

 

Thanks, I have added it to the bug report. 

  • Haha 1

Share this post


Link to post

How are the () implemented then are they to be implied?

procedure X(i: Integer);
begin
end;

procedure Y;

begin
  var f: TFunc<Integer>;
  //X(f);  You need give the compiler a "Clue"
  X(f()); //runs

 //(procedure begin Beep; end);  Boo
 (procedure begin Beep; end) ();  //Yay!
 
 //In VBA need use either Call or add (); 'To even add a line of code. 

end;

 

Edited by Pat Foley
Oops should read compiles does not 'run' as is.

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×