In some code I am fixing up, which makes heavy use of generics and interfaced types, I am getting error
E2134, Type '<void>' has no type info.
I believe it is because I am in the middle of a refactor where some deeply nested set of units that all use generics are out of sync, but the error is not happening in a place where I can make use of the error message to fix the code, because there is nothing wrong with the code, at the location where the error is appearing.
Here is the context, mocked up, because I can not post the code, there is too much:
unit GenericThing;
...
interface
...
type
...
IThingListOf<ThingT> = interface( IThingContainer )
function getEnumerator: TEnumerator<ThingT>;
function getCount: Integer;
function getThing( Index: integer ): ThingT;
function getFirst: ThingT;
function IndexOf( value: ThingT): integer;
function addItem( const Thing: ThingT ): ThingT;
function removeItem( const Thing: ThingT ): Integer;
procedure clear;
procedure Sort; overload;
procedure Sort(const AComparer: IComparer<ThingT>); overload;
property Count: integer read getCount;
property First: ThingT read getFirst;
property Items[Index: integer]: ThingT read getThing; default;
end;
// error appears on whatever line number comes after the declaration of IThingListOf<ThingT>...end;
function AnythingYouLikeHere:Integer; // there is nothign wrong with this line, but you get the E2134 here.
It appears that the problem is in IThingContainer itself:
IThingContainer = interface ...
...
procedure DoSomething(const Param);
end;
THe above "const Param" has no type information. This is a weird (armpit) of Pascal/Delphi in my opinion, where you completely violate Wirth's idea of strong typing. It is about as weakly typed as a "void *" pointer in C, or the "Pointer" type in Delphi, but it is rarely used, except for in places like the standard pre-object-pascal RTL functions like Move, and so on. In my opinion, untyped parameters in interfaces, used in generics, should either be allowed, or disallowed, but not allowed sometimes, and disallowed other times.
This is a case of a Pascal feature from 1978 mixing badly with an ObjectPascal feature from 2009.
The error message means there's no type info available for the given type.
Here's a minimal program which produces the message:
type
{$M+}
IThing = interface
procedure P(const X);
end;
{$M-}
begin
end.
The problem, it would appear, is that IThingListOf<>
, or one of its ancestors, was compiled with {$M+}
active. The compiler presumes from this that you really want full type info for the interface; originally it was used by SOAP etc. support to produce stubs etc. The interface RTTI doesn't support untyped parameters (logically enough, they can't be marshalled by SOAP etc.) - and they show up as being of void type, and you end up with this error message.
The solution is to either not use {$M+}
- though presumably the RTTI is being used, otherwise it wouldn't be enabled - or use e.g. Pointer
instead, and pass the address explicitly.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With