rgdawson 8 Posted 20 hours ago 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 1428 Posted 20 hours ago (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 19 hours ago by Remy Lebeau 2 Share this post Link to post
Stefan Glienke 2018 Posted 6 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