diff options
author | Adriaan Moors <adriaan.moors@epfl.ch> | 2012-06-04 15:25:44 +0200 |
---|---|---|
committer | Eugene Burmako <xeno.by@gmail.com> | 2012-06-08 15:34:59 +0200 |
commit | b31c6d4f778df6b415c605a468b155cea0b84a16 (patch) | |
tree | f3bc55f72169d6e6c55413244497965641cece92 /src | |
parent | ef9720f0ebc1fe1ab06be4751985fa4bd279a73d (diff) | |
download | scala-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.scala | 17 |
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) |