rgdawson 8 Posted Saturday at 10:52 PM 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
Remy Lebeau 1429 Posted Saturday at 11:33 PM (edited) 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 yesterday at 12:24 AM by Remy Lebeau 2 Share this post Link to post
Stefan Glienke 2018 Posted 16 hours ago 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
Remy Lebeau 1429 Posted 8 hours ago 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. 1 Share this post Link to post
Pat Foley 52 Posted 7 hours ago (edited) 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 6 hours ago by Pat Foley Oops should read compiles does not 'run' as is. Share this post Link to post