[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