mirror of https://github.com/sbt/sbt.git
Merge pull request #2413 from smarter/fix/vc-return-type
[0.13.10] Always invalidate API when return type is a value class
This commit is contained in:
commit
03524e3329
|
|
@ -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