Component Pascal
May 30, 2002 Written by Charles CookComponent Pascal, described in the interesting Compiling for the .NET Common Language Runtime, does support covariant return types.
I verified this in my first (and last?) CP program:
MODULE HELLO;
IMPORT CPmain, Console;
TYPE
BaseParser = EXTENSIBLE RECORD END;
FaultParser = EXTENSIBLE RECORD (BaseParser) END;
BaseRet = EXTENSIBLE RECORD END;
BaseRetPtr = POINTER TO BaseRet;
FaultRet = RECORD (BaseRet) END;
FaultRetPtr = POINTER TO FaultRet;
VAR
bp : POINTER TO BaseParser;
bret : BaseRetPtr;
fp : POINTER TO FaultParser;
fret : FaultRetPtr;
PROCEDURE (IN p : BaseParser) Foo() : BaseRetPtr, NEW , EXTENSIBLE;
VAR tmp : BaseRetPtr;
BEGIN
NEW(tmp);
RETURN tmp;
END Foo;
PROCEDURE (IN p : FaultParser) Foo() : FaultRetPtr;
VAR tmp : FaultRetPtr;
BEGIN
NEW(tmp);
RETURN tmp;
END Foo;
BEGIN
NEW(bp);
bret := bp.Foo();
NEW(fp);
fret := fp.Foo();
END HELLO.
Method Foo in FaultParser overrides Foo in the base class and returns a pointer to FaultRet instead of BaseRet. CP handles the covariant return type via a two-pronged approach. First, Foo in the derived class, although defined in the IL method signature to return a type of BaseRet, actually returns a type of FaultRet:
.method assembly final virtual instance class HELLO.BaseRet
Foo() cil managed
{
// Code size 8 (0x8)
.maxstack 8
.locals init ([0] class HELLO.FaultRet tmp)
IL_0000: newobj instance void HELLO.FaultRet::.ctor()
IL_0005: stloc.0
IL_0006: ldloc.0
IL_0007: ret
} // end of method FaultParser::Foo
Second, the compiler recognizes that a covariant return is required and automatically downcasts the returned BaseRet to the required FaultRet type:
IL_0015: call instance class HELLO.BaseRet HELLO.FaultParser::Foo()
IL_001a: castclass class HELLO.FaultRet
IL_001f: stsfld class HELLO.FaultRet HELLO.HELLO::fret
I don't how the compiler recognizes that a method supports covariant return when referencing another CP assembly because there doesn't seem to be any metadata to indicate this (even when all the types are marked as exportable)