summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAdriaan Moors <adriaan.moors@epfl.ch>2012-06-04 15:25:44 +0200
committerEugene Burmako <xeno.by@gmail.com>2012-06-08 15:34:59 +0200
commitb31c6d4f778df6b415c605a468b155cea0b84a16 (patch)
treef3bc55f72169d6e6c55413244497965641cece92 /src
parentef9720f0ebc1fe1ab06be4751985fa4bd279a73d (diff)
downloadscala-b31c6d4f778df6b415c605a468b155cea0b84a16.tar.gz
scala-b31c6d4f778df6b415c605a468b155cea0b84a16.tar.bz2
scala-b31c6d4f778df6b415c605a468b155cea0b84a16.zip
unapply may be called on arbitrary tree
before, an unapply call would be derived from a case SomeClass(_, ..., _) pattern, where SomeClass is a valid constructor reference, and thus also a reference to an unapply-bearing companion object this assumption is going to be violated once we start using class tags to make uncheckable type tests checkable, since we could encounter unapply calls like {<method calls that construct classTag>}.unapply(<arg>)
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala17
1 files changed, 13 insertions, 4 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 5ef0d85fd7..95a2962199 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -966,12 +966,21 @@ trait Typers extends Modes with Adaptations with Tags {
* see test/files/../t5189*.scala
*/
def adaptConstrPattern(): Tree = { // (5)
- def isExtractor(sym: Symbol) = reallyExists(unapplyMember(sym.tpe))
- val extractor = tree.symbol filter isExtractor
+ def hasUnapplyMember(tp: Type) = reallyExists(unapplyMember(tp))
+ val overloadedExtractorOfObject = tree.symbol filter (sym => hasUnapplyMember(sym.tpe))
+ // if the tree's symbol's type does not define an extractor, maybe the tree's type does
+ // this is the case when we encounter an arbitrary tree as the target of an unapply call (rather than something that looks like a constructor call)
+ // (for now, this only happens due to maybeTypeTagExtractor, but when we support parameterized extractors, it will become more common place)
+ val extractor = overloadedExtractorOfObject orElse unapplyMember(tree.tpe)
if (extractor != NoSymbol) {
- tree setSymbol extractor
+ // if we did some ad-hoc overloading resolution, update the tree's symbol
+ // do not update the symbol if the tree's symbol's type does not define an unapply member
+ // (e.g. since it's some method that returns an object with an unapply member)
+ if (overloadedExtractorOfObject != NoSymbol)
+ tree setSymbol overloadedExtractorOfObject
+
tree.tpe match {
- case OverloadedType(pre, alts) => tree.tpe = overloadedType(pre, alts filter isExtractor)
+ case OverloadedType(pre, alts) => tree.tpe = overloadedType(pre, alts filter (alt => hasUnapplyMember(alt.tpe)))
case _ =>
}
val unapply = unapplyMember(extractor.tpe)