diff options
-rw-r--r-- | src/compiler/scala/tools/nsc/matching/MatchSupport.scala | 18 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Typers.scala | 21 | ||||
-rw-r--r-- | test/files/pos/t0999.scala | 5 |
3 files changed, 17 insertions, 27 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 */ diff --git a/test/files/pos/t0999.scala b/test/files/pos/t0999.scala deleted file mode 100644 index c384820af1..0000000000 --- a/test/files/pos/t0999.scala +++ /dev/null @@ -1,5 +0,0 @@ -object A { - val d: Double = Math.sqrt(5 match { - case x: Double => x - }) -} |