[nem-bug] [Nemerle 0000801]: Invalid IL for cast between two
generic parameters
feedback at nemerle.org
feedback at nemerle.org
Mon Dec 4 12:48:26 CET 2006
The following issue has been RESOLVED.
======================================================================
<http://nemerle.org/bugs/view.php?id=801>
======================================================================
Reported By: Evin Robertson
Assigned To: malekith
======================================================================
Project: Nemerle
Issue ID: 801
Category: Compiler (type engine)
Reproducibility: always
Severity: minor
Priority: high
Status: resolved
Resolution: fixed
Fixed in Version:
======================================================================
Date Submitted: 12-03-2006 19:24 CET
Last Modified: 12-04-2006 12:48 CET
======================================================================
Summary: Invalid IL for cast between two generic parameters
Description:
The following code compiles, but it shouldn't:
public class GenericCast[F, T]
{
private from : F;
public this(from : F)
{
this.from = from
}
public Run() : T
{
from :> T
}
}
public class A
{
public static Main(_ : array[string]) : void
{
def c = GenericCast(100);
_ = c.Run() : byte
}
}
At runtime, a NullReferenceException is thrown in Run(). gmcs rejects the
equivalent C# program. Nemerle should reject this program just as it does
the one with "from : T" instead of "from :> T".
======================================================================
----------------------------------------------------------------------
nazgul - 12-03-06 21:17
----------------------------------------------------------------------
As far as I remember this is the intended behavior. In Nemerle we have two
kind of casts - static `:' and dynamic `:>' - the static one is just a
hint for compiler (to increase code readability and help in complex
type-inference scenarios) and dynamic is an information from user "I know
what I'm doing". This gives somewhat more power to express what semantics
is expected than simple (TYPE)expr case in C#.
Following this argumentation we decided to do not restrict "I know better"
scenario like C# designers did - if user want to cast something dynamically
and if we know that there is a chance that this is proper use, then we do
not forbid such use.
Things to note here are:
- :> will give you a warning if you do not need a dynamic cast, so in case
of
class [A,B] where A: B { ... (x : B) :> A ... }
compiler warns you that you do something, which might not be the
intended use
- you can workaround the C# restriction by
(T)((object)x)
there is no reason we should force users to write
(x : object) :> T this doesn't make much sense
- compiler will correctly forbid any "impossible" casts:
class A { } class B { }
(x : A) :> B
will give error
----------------------------------------------------------------------
Evin Robertson - 12-03-06 22:21
----------------------------------------------------------------------
If I change the last line to: "_ = c.Run() : int" it still causes the
NullReferenceException (using mono 1.1.18).
In fact, if I change Run to use "(from : object) :> T" then things work
better. It adds a box instruction before the unbox. With this change,
trying to use GenericCast[int, byte] throws an InvalidCastException and
GenericCast[int, int] works perfectly.
Reading the unbox.any specification, I'm not sure if mono should be
throwing an InvalidCastException instead of the NullReferenceException, or
if mono can do whatever it wants because unboxing a non-reference type
fails the correctness requirements.
----------------------------------------------------------------------
nazgul - 12-03-06 22:26
----------------------------------------------------------------------
Ok, I tried verifying the example code and it gives:
[IL]: Error: [E:\cygwin\home\nazgul\nemerle\ncc\testsuite\out.exe :
GenericCast`2[F,T]::Run][offset 0x00000006][found (unboxed) 'F'] Expected
an ObjRef on the stack.
So this is indeed a bug in code generation. I was sure we support such
code, but maybe it was a cast in a little bit different context.
----------------------------------------------------------------------
malekith - 12-04-06 12:48
----------------------------------------------------------------------
It properly generates InvalidCastExn now (r7041).
Issue History
Date Modified Username Field Change
======================================================================
12-03-06 19:24 Evin Robertson New Issue
12-03-06 21:17 nazgul Note Added: 0001547
12-03-06 22:21 Evin Robertson Note Added: 0001548
12-03-06 22:26 nazgul Note Added: 0001549
12-03-06 22:26 nazgul Priority normal => high
12-03-06 22:26 nazgul Status new => confirmed
12-03-06 22:26 nazgul Summary Explicit conversion is
too powerful for generics => Invalid IL for cast between two generic parameters
12-03-06 22:26 nazgul Description Updated
12-04-06 12:39 malekith Status confirmed => assigned
12-04-06 12:39 malekith Assigned To => malekith
12-04-06 12:48 malekith Status assigned => resolved
12-04-06 12:48 malekith Resolution open => fixed
12-04-06 12:48 malekith Note Added: 0001552
======================================================================
More information about the bugs
mailing list