Uploaded image for project: 'Scala Programming Language'
  1. Scala Programming Language
  2. SI-1503

Casts inserted when pattern matching for equality on singletons are unsound

    Details

      Description

      I've added a test to pending/run/castsingleton.scala:

      object Test extends Application {
        case class L();
        object N extends L();
       
        def empty(xs : L) : Unit = xs match {
          case x@N => println(x); println(x);
        }
       
        empty(L())
      } 
      

      The problem is that the compiler inserts a cast of xs to N.type, which is unsound: The pattern match will succeed for any L, because N == L().

        Attachments

          Issue Links

            Activity

            Hide
            extempore Paul Phillips added a comment -

            Moors - have you looked at SI-7714? Does your proposed change handle those cases?

            Show
            extempore Paul Phillips added a comment - Moors - have you looked at SI-7714 ? Does your proposed change handle those cases?
            Hide
            moors Adriaan Moors added a comment -

            I had not. Thanks for the pointer. Will add it to the investigation for my next available bugfixing slot.

            Show
            moors Adriaan Moors added a comment - I had not. Thanks for the pointer. Will add it to the investigation for my next available bugfixing slot.
            Hide
            moors Adriaan Moors added a comment - - edited
            Show
            moors Adriaan Moors added a comment - - edited Xlint warning for 2.11: https://github.com/scala/scala/pull/3559
            Hide
            bkent314 Brian Kent added a comment -

            Is it possible for the compiler to offer more guidance in addition to the current warnings?

            For example, in doing case x@N => ..., the compiler could offer:

            you probably want case x:N.type => ...

            Currently it just says something is dangerous buy offers no alternatives.

            Show
            bkent314 Brian Kent added a comment - Is it possible for the compiler to offer more guidance in addition to the current warnings? For example, in doing case x@N => ... , the compiler could offer: you probably want case x:N.type => ... Currently it just says something is dangerous buy offers no alternatives.
            Hide
            milessabin Miles Sabin added a comment -

            In 2.12.x the example in this ticket produces a non-exhaustive match warning,

            > scala
            [info] Running scala.tools.nsc.MainGenericRunner -usejavacp                                                                                 
            Welcome to Scala 2.12.0-20160722-172732-9ee8124 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_102).                                        
            Type in expressions for evaluation. Or try :help.                                                                                           
                                                                                                                                                        
            scala> :paste
            // Entering paste mode (ctrl-D to finish)                                                                                                   
                                                                                                                                                        
            object Test extends App {                                                                                                                   
              case class L();                                                                                                                           
              object N extends L();                                                                                                                     
                                                                                                                                                        
              def empty(xs : L) : Unit = xs match {                                                                                                     
                case x@N => println(x); println(x);                                                                                                     
              }                                                                                                                                         
                                                                                                                                                        
              empty(L())                                                                                                                                
            }                                                                                                                                           
                                                                                                                                                        
            // Exiting paste mode, now interpreting.                                                                                                    
                                                                                                                                                        
            <console>:15: warning: match may not be exhaustive.
            It would fail on the following input: L()
                     def empty(xs : L) : Unit = xs match {
                                                ^
            defined object Test
            

            Show
            milessabin Miles Sabin added a comment - In 2.12.x the example in this ticket produces a non-exhaustive match warning, > scala [info] Running scala.tools.nsc.MainGenericRunner -usejavacp Welcome to Scala 2.12.0-20160722-172732-9ee8124 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_102). Type in expressions for evaluation. Or try :help. scala> :paste // Entering paste mode (ctrl-D to finish) object Test extends App { case class L(); object N extends L(); def empty(xs : L) : Unit = xs match { case x@N => println(x); println(x); } empty(L()) } // Exiting paste mode, now interpreting. <console>:15: warning: match may not be exhaustive. It would fail on the following input: L() def empty(xs : L) : Unit = xs match { ^ defined object Test

              People

              • Assignee:
                moors Adriaan Moors
                Reporter:
                drmaciver David R. MacIver
                TracCC:
                Erik Engbrecht, Paul Phillips
              • Votes:
                5 Vote for this issue
                Watchers:
                14 Start watching this issue

                Dates

                • Created:
                  Updated: