summaryrefslogtreecommitdiff
path: root/src/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'src/compiler')
-rw-r--r--src/compiler/scala/tools/nsc/matching/MatchSupport.scala18
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala21
2 files changed, 17 insertions, 22 deletions
diff --git a/src/compiler/scala/tools/nsc/matching/MatchSupport.scala b/src/compiler/scala/tools/nsc/matching/MatchSupport.scala
index 5f2c18e597..117973865b 100644
--- a/src/compiler/scala/tools/nsc/matching/MatchSupport.scala
+++ b/src/compiler/scala/tools/nsc/matching/MatchSupport.scala
@@ -29,20 +29,22 @@ trait MatchSupport extends ast.TreeDSL { self: ParallelMatching =>
implicit def enrichType(x: Type): RichType = new RichType(x)
// see bug1434.scala for an illustration of why "x <:< y" is insufficient.
- // this code is definitely inadequate at best. Inherited comment:
+ // this code is inadequate but slowly improving... Inherited comment:
//
// an approximation of _tp1 <:< tp2 that ignores _ types. this code is wrong,
// ideally there is a better way to do it, and ideally defined in Types.scala
private[matching] def matches(arg1: Type, arg2: Type) = {
val List(t1, t2) = List(arg1, arg2) map decodedEqualsType
- def eqSymbols = t1.typeSymbol eq t2.typeSymbol
- // note: writing this as "t1.baseTypeSeq exists (_ =:= t2)" does not lead to 1434 passing.
- def isSubtype = t1.baseTypeSeq exists (_.typeSymbol eq t2.typeSymbol)
- (t1 <:< t2) || ((t1, t2) match {
- case (_: TypeRef, _: TypeRef) => !t1.isArray && (t1.prefix =:= t2.prefix) && (eqSymbols || isSubtype)
- case _ => false
- })
+ def matchesIgnoringBounds(tp1: Type, tp2: Type) = tp2 match {
+ case TypeRef(pre, sym, args) => tp1 <:< TypeRef(pre, sym, args map (_ => AnyClass.tpe))
+ case _ => false
+ }
+ def okPrefix = t1.prefix =:= t2.prefix
+ def okSubtype = t1.baseTypeSeq exists (_.typeSymbol eq t2.typeSymbol)
+ def okBounds = matchesIgnoringBounds(t1, t2)
+
+ (t1 <:< t2) || (okPrefix && okSubtype && okBounds)
}
class RichType(undecodedTpe: Type) {
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 879dadcbed..aeb3762afc 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -4206,20 +4206,13 @@ trait Typers { self: Analyzer =>
/** Types a pattern with prototype <code>pt</code> */
def typedPattern(tree: Tree, pt: Type): Tree = {
- // The commented out code stems from investigation into whether
- // "abc" match { case Seq('a', 'b', 'c') => true }
- // can be ruled out statically. At present this is a runtime
- // error both because there is an implicit from String to Seq
- // (even though such implicits are not used by the matcher) and
- // because the typer is fine with concluding that "abc" might
- // be of type "String with Seq[T]" and thus eligible for a call
- // to unapplySeq.
- //
- // val savedImplicitsEnabled = context.implicitsEnabled
- // context.implicitsEnabled = false
- // try
- typed(tree, PATTERNmode, pt)
- // finally context.implicitsEnabled = savedImplicitsEnabled
+ // We disable implicits because otherwise some constructs will
+ // type check which should not. The pattern matcher does not
+ // perform implicit conversions in an attempt to consummate a match.
+ val savedImplicitsEnabled = context.implicitsEnabled
+ context.implicitsEnabled = false
+ try typed(tree, PATTERNmode, pt)
+ finally context.implicitsEnabled = savedImplicitsEnabled
}
/** Types a (fully parameterized) type tree */