mirror of https://github.com/sbt/sbt.git
Always invalidate API when return type is a value class
Before this commit, we did not do the invalidation for methods with multiple parameter list, the comment above `hasValueClassAsReturnType` said: Note: We only inspect the "outermost type" (i.e. no recursion) because we don't need to inspect after erasure a function that would, for instance, return a function that returns a subtype of AnyVal. But this is wrong: a method with signature: def foo(a: A)(b: B): C is erased to: def foo(a: A, b: B): C and not, as the comment in the code suggest, to: def foo(a: A): B => C so we do need to inspect the final result type of methods, because they can be value classes that will be erased to their underlying value.
This commit is contained in:
parent
e64b01142b
commit
0993c1c7cc
|
|
@ -208,20 +208,14 @@ class ExtractAPI[GlobalType <: CallbackGlobal](val global: GlobalType,
|
|||
s.asMethod.paramss.flatten map (_.info) exists (t => isAnyValSubtype(t.typeSymbol))
|
||||
}
|
||||
|
||||
// Note: We only inspect the "outermost type" (i.e. no recursion) because we don't need to
|
||||
// inspect after erasure a function that would, for instance, return a function that returns
|
||||
// a subtype of AnyVal.
|
||||
val hasValueClassAsReturnType: Boolean = {
|
||||
val tpe = viewer(in).memberInfo(s)
|
||||
tpe match {
|
||||
case PolyType(_, base) => isAnyValSubtype(base.typeSymbol)
|
||||
case MethodType(_, resultType) => isAnyValSubtype(resultType.typeSymbol)
|
||||
case Nullary(resultType) => isAnyValSubtype(resultType.typeSymbol)
|
||||
case resultType => isAnyValSubtype(resultType.typeSymbol)
|
||||
}
|
||||
def hasValueClassAsReturnType(tpe: Type): Boolean = tpe match {
|
||||
case PolyType(_, base) => hasValueClassAsReturnType(base)
|
||||
case MethodType(_, resultType) => hasValueClassAsReturnType(resultType)
|
||||
case Nullary(resultType) => hasValueClassAsReturnType(resultType)
|
||||
case resultType => isAnyValSubtype(resultType.typeSymbol)
|
||||
}
|
||||
|
||||
val inspectPostErasure = hasValueClassAsParameter || hasValueClassAsReturnType
|
||||
val inspectPostErasure = hasValueClassAsParameter || hasValueClassAsReturnType(viewer(in).memberInfo(s))
|
||||
|
||||
def build(t: Type, typeParams: Array[xsbti.api.TypeParameter], valueParameters: List[xsbti.api.ParameterList]): List[xsbti.api.Def] =
|
||||
{
|
||||
|
|
|
|||
|
|
@ -0,0 +1,3 @@
|
|||
class B {
|
||||
def bar(dummy: String)(dummy2: String): A = new A(0)
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
object C extends App {
|
||||
println(new B().bar("")("").x)
|
||||
}
|
||||
|
|
@ -1,3 +1,4 @@
|
|||
## Case 1: value class as parameter of method
|
||||
$ copy-file changes/A0.scala src/main/scala/A.scala
|
||||
$ copy-file changes/B0.scala src/main/scala/B.scala
|
||||
$ copy-file changes/C0.scala src/main/scala/C.scala
|
||||
|
|
@ -13,6 +14,8 @@ $ copy-file changes/A1.scala src/main/scala/A.scala
|
|||
# This means that we have invalidated C.scala, as expected!
|
||||
-> compile
|
||||
|
||||
|
||||
## Case 2: value class as return type of method with no parameter lists
|
||||
$ copy-file changes/A0.scala src/main/scala/A.scala
|
||||
$ copy-file changes/B1.scala src/main/scala/B.scala
|
||||
$ copy-file changes/C1.scala src/main/scala/C.scala
|
||||
|
|
@ -28,3 +31,20 @@ $ copy-file changes/A1.scala src/main/scala/A.scala
|
|||
# because A is now a value class.
|
||||
> run
|
||||
|
||||
|
||||
## Case 3: value class as return type of method with multiple parameter lists
|
||||
$ copy-file changes/A0.scala src/main/scala/A.scala
|
||||
$ copy-file changes/B2.scala src/main/scala/B.scala
|
||||
$ copy-file changes/C2.scala src/main/scala/C.scala
|
||||
|
||||
# A is a normal class. B.bar takes two dummy arguments and returns an instance of A. C calls B.bar("")("").
|
||||
> compile
|
||||
> run
|
||||
|
||||
# Make A a value class.
|
||||
$ copy-file changes/A1.scala src/main/scala/A.scala
|
||||
|
||||
# The code compiles. It will run iff C is recompiled because the signature of B.bar has changed,
|
||||
# because A is now a value class.
|
||||
> run
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue