Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inappropriate type is inferred for an extracted value #8045

Closed
scabug opened this issue Dec 7, 2013 · 7 comments
Closed

Inappropriate type is inferred for an extracted value #8045

scabug opened this issue Dec 7, 2013 · 7 comments

Comments

@scabug
Copy link

scabug commented Dec 7, 2013

object Test extends App {
  case class Number(i: Int)

  object UnliftNumber {
    def unapply(t: Any): Option[Number] = t match {
      case i: Int => Some(Number(i))
      case _ => None
    }
  }

  def eval(expr: Any): Option[Number] = expr match {
    case UnliftNumber(n) => Some(n)
    case _ => None
  }

  println(eval(1))
}
Test.scala:15: error: type mismatch;
 found   : Int
 required: Test.Number
    case UnliftNumber(n) => Some(n)
                                 ^
one error found

If we the return type of eval is ommited the code compiles and runs just fine:

$ quickc -d sandbox Test.scala

$ quick -cp sandbox Test
Some(Number(1))
@scabug
Copy link
Author

scabug commented Dec 7, 2013

Imported From: https://issues.scala-lang.org/browse/SI-8045?orig=1
Reporter: @densh
Affected Versions: 2.11.0-M7

@scabug
Copy link
Author

scabug commented Dec 9, 2013

@densh said:
Might be related to #7850

@scabug
Copy link
Author

scabug commented Dec 9, 2013

@retronym said:
Yep, regressed in scala/scala#2848

@scabug
Copy link
Author

scabug commented Dec 9, 2013

@retronym said:
Diffing the -Ytyper-debug before/after the regression: https://gist.github.com/retronym/7876473

@scabug
Copy link
Author

scabug commented Dec 9, 2013

@retronym said:
Changing Number to a non-case class works:

object Test extends App {
  class Number(i: Int)
 
  object UnliftNumber {
    def unapply(t: Any): Option[Number] = t match {
      case i: Int => Some(new Number(i))
      case _ => None
    }
  }
 
  def eval(expr: Any): Option[Number] = expr match {
    case UnliftNumber(n) => Some(n)
    case _ => None
  }
 
  println(eval(1))
}

This code seems culpable:

    /** If this is a case class, the case field accessors (which may be an empty list.)
     *  Otherwise, if there are any product selectors, that list.
     *  Otherwise, a list containing only the type itself.
     */
    def typesOfSelectorsOrSelf(tp: Type): List[Type] = (
      if (tp.typeSymbol.isCase)
        typesOfCaseAccessors(tp)
      else typesOfSelectors(tp) match {
        case Nil => tp :: Nil
        case tps => tps
      }
    )

@scabug
Copy link
Author

scabug commented Dec 9, 2013

@scabug
Copy link
Author

scabug commented Dec 23, 2013

@paulp said:
scala/scala#3275

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants