diff options
author | Jason Zaugg <jzaugg@gmail.com> | 2013-09-06 17:04:53 +0200 |
---|---|---|
committer | Jason Zaugg <jzaugg@gmail.com> | 2013-09-06 17:20:27 +0200 |
commit | cb028ba477f37778bccfc23e597acc0284259681 (patch) | |
tree | ebe913a6dfb1bb29fd30e1448f66ce6e9150da6e /src/compiler | |
parent | d46519da657ada39d9928308709cdb80ddcd53ce (diff) | |
download | scala-cb028ba477f37778bccfc23e597acc0284259681.tar.gz scala-cb028ba477f37778bccfc23e597acc0284259681.tar.bz2 scala-cb028ba477f37778bccfc23e597acc0284259681.zip |
SI-7818 Cast our way out of extended existential angst
`substituteSymbols` is not sophisticated enough to
operate on `TypeSkolem`-s which are based on one of the
"from" symbols.
The pertinant usage of `substituteSymbols` for this bug in
in `Extender`. Recapping on that transform:
// orig
class C[T](...) extends AnyVal { def foo[U] = <rhs> }
// transform
class C[T] extends AnyVal { ... }
object C { def foo$extension[T', U'] = <rhs'> }
Where `<rhs'>` has been subtituted with, among other things,
`[T, U] ~> [T', U']`.
In this case our expected type contains a new type parameter
(of the extension method), whereas the type of the RHS contains
an existential skolem still pinned to the corresponding class type
parameter.
tree.tpe = Observable1#7037[_$1#12344]
<_$1#12344>.info = <: T#7040
pt = Observable1#7037[T#15644]
The limitation of substution is lamented in the comments
of `adaptMismatchedSkolems`, which faces the harder version of
the issue where the skolems are in the expected type.
But, we're in the "easy" case with the skolems in the tree's type;
we can cast our way out of the problem.
See also f335e447 / ed915c54.
Diffstat (limited to 'src/compiler')
-rw-r--r-- | src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala | 7 |
1 files changed, 6 insertions, 1 deletions
diff --git a/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala b/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala index bc54054028..e0c0cd0fdb 100644 --- a/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala +++ b/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala @@ -231,9 +231,14 @@ abstract class ExtensionMethods extends Transform with TypingTransformers { .substituteThis(origThis, extensionThis) .changeOwner(origMeth -> extensionMeth) ) + val castBody = + if (extensionBody.tpe <:< extensionMono.finalResultType) + extensionBody + else + gen.mkCastPreservingAnnotations(extensionBody, extensionMono.finalResultType) // SI-7818 e.g. mismatched existential skolems // Record the extension method ( FIXME: because... ? ) - extensionDefs(companion) += atPos(tree.pos)(DefDef(extensionMeth, extensionBody)) + extensionDefs(companion) += atPos(tree.pos)(DefDef(extensionMeth, castBody)) // These three lines are assembling Foo.bar$extension[T1, T2, ...]($this) // which leaves the actual argument application for extensionCall. |