diff options
author | Burak Emir <emir@epfl.ch> | 2007-12-01 10:26:27 +0000 |
---|---|---|
committer | Burak Emir <emir@epfl.ch> | 2007-12-01 10:26:27 +0000 |
commit | 532d7a9f3525471601a0853a6a6e28a048cb0827 (patch) | |
tree | 2e07fff0a3e6077b4417ded8999a66b5835b9a96 | |
parent | c73986baa5ae1570852e708a1cf43ce7ef5cd6ea (diff) | |
download | scala-532d7a9f3525471601a0853a6a6e28a048cb0827.tar.gz scala-532d7a9f3525471601a0853a6a6e28a048cb0827.tar.bz2 scala-532d7a9f3525471601a0853a6a6e28a048cb0827.zip |
fixed #211
-rw-r--r-- | src/compiler/scala/tools/nsc/matching/CodeFactory.scala | 110 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/matching/ParallelMatching.scala | 12 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/symtab/GenerateIdeMaps.scala | 2 | ||||
-rw-r--r-- | test/files/run/patmatnew.scala | 10 |
4 files changed, 61 insertions, 73 deletions
diff --git a/src/compiler/scala/tools/nsc/matching/CodeFactory.scala b/src/compiler/scala/tools/nsc/matching/CodeFactory.scala index 163c6743f3..3d2d64051f 100644 --- a/src/compiler/scala/tools/nsc/matching/CodeFactory.scala +++ b/src/compiler/scala/tools/nsc/matching/CodeFactory.scala @@ -77,23 +77,6 @@ trait CodeFactory { tpe1.typeArgs(0) } - // --------- these are new - -/* - final def renamingBind(defaultv: Set[Symbol], scrut: Symbol, ndefault: Tree) = { - Console.println("renamingbind "+defaultv+" "+scrut+" "+ndefault) - if (!defaultv.isEmpty) { - var dv: List[Symbol] = Nil - var to: List[Symbol] = Nil - val it = defaultv.elements; while(it.hasNext) { - dv = it.next :: dv - to = scrut :: to - } - val tss = new TreeSymSubstituter(dv, to) - tss.traverse(ndefault) - } - } -*/ final def emptynessCheck(vsym: Symbol) = { if (vsym.tpe.typeSymbol == definitions.SomeClass) // is Some[_] Literal(Constant(true)) @@ -193,57 +176,6 @@ trait CodeFactory { } } - // used by Equals - /* - private def getCoerceToInt(left: Type): Symbol = { - val sym = left.nonPrivateMember( nme.coerce ); - //assert sym != Symbol.NONE : Debug.show(left); - - sym.alternatives.find { - x => x.info match { - case MethodType(vparams, restpe) => - vparams.length == 0 && isSameType(restpe,definitions.IntClass.info) - } - }.get - } - */ - // used by Equals -/* - private def getEqEq(left: Type, right: Type): Symbol = { - //Console.println("getEqeq of left == "+left); - val sym = left.nonPrivateMember( nme.EQEQ ); - - - //if (sym == NoSymbol) - // error("no eqeq for "+left); - // : Debug.show(left) + "::" + Debug.show(left.members()); - - var fun: Symbol = null; - var ftype:Type = null; // faster than `definitions.AnyClass.tpe' - sym.alternatives.foreach { - x => - //Console.println("getEqEq: "+x); - val vparams = x.info.paramTypes; - //Console.println("vparams.length == "+vparams.length); - - if (vparams.length == 1) { - val vptype = vparams(0); - //Console.println("vptype == "+vptype); - //Console.println(" ftype == "+ftype); - //Console.println(" cond1 == "+isSubType(right, vptype)); - //Console.println(" cond2("+vptype+","+ftype+") == "+(ftype == null || isSubType(vptype, ftype))); - //Console.println("vptype.getClass "+vptype.getClass()); - if (isSubType(right, vptype) && (ftype == null || isSubType(vptype, ftype)) ) { - fun = x; - ftype = vptype; - //Console.println("fun now: "+fun+" ftype now "+ftype); - } - } - } - //if (fun == null) scala.Predef.error("couldn't find eqeq for left"+left); - fun; - } -*/ final def Equals(left: Tree, right: Tree): Tree = Apply(Select(left, nme.EQEQ), List(right)) @@ -360,6 +292,46 @@ trait CodeFactory { } } - + final def debugStrings(tps:List[Type]):String = tps.foldLeft("[")({ (x:String,y:Type) => x+","+debugString(y) })+"]" + + final def debugString(tp:Type):String = tp match { + case ErrorType => "ErrorType" + // internal: error + case WildcardType => "WildcardType" + // internal: unknown + case NoType => "NoType" + case NoPrefix => "NoPrefix" + case ThisType(sym) => "ThisType("+sym.toString+")" + // sym.this.type + case SingleType(pre, sym) => "SingleType("+debugString(pre)+","+sym+")" + // pre.sym.type + case ConstantType(value) => "ConstantType("+value+")" + // int(2) + case TypeRef(pre, sym, args) => "TypeRef("+debugString(pre)+","+sym.getClass()+"(=="+sym+")"+","+ debugStrings(args)+")" + // pre.sym[targs] + case RefinedType(parents, defs) => "RefinedType("+debugStrings(parents)+","+defs+")" + // parent1 with ... with parentn { defs } + case AnnotatedType(attribs, tp, selfsym) => "AnnotatedType("+attribs+","+ debugString(tp)+","+ selfsym+")" + // tp @attribs + case p:Product => tp.getClass.toString+"(=="+tp.toString+")"+runtime.ScalaRunTime._toString(p) + + case _ => tp.getClass.toString+"(=="+tp.toString+")" + /* + // the following are non-value types; you cannot write them down in Scala source. + + case TypeBounds(lo, hi) => + // >: lo <: hi + case ClassInfoType(parents, defs, clazz) => + // same as RefinedType except as body of class + case MethodType(paramtypes, result) => + // (paramtypes)result + case PolyType(tparams, result) => + // [tparams]result where result is a MethodType or ClassInfoType + // or + // []T for a eval-by-name type + case ExistentialType(tparams, result) => + // exists[tparams]result + */ + } } diff --git a/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala b/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala index 45218e78e6..32b95944e4 100644 --- a/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala +++ b/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala @@ -682,6 +682,12 @@ trait ParallelMatching { } } + def subsumes_erased(_tp1:Type, tp2:Type) = { + val tp1 = patternType_wrtEquals(_tp1) + tp1.isInstanceOf[TypeRef] && tp2.isInstanceOf[TypeRef] && + ((tp1.prefix =:= tp2.prefix) && (tp1.typeSymbol eq tp2.typeSymbol) && (tp1.typeSymbol ne definitions.ArrayClass)) + } + /** returns true if pattern tests an object */ final def objectPattern(pat:Tree): Boolean = try { (pat.symbol ne null) && @@ -716,7 +722,7 @@ trait ParallelMatching { case z:UnApply => (ms,ss,(j,pat)::rs) - case qq if (patternType_wrtEquals(patternType) <:< headPatternType) && !isDefaultPattern(pat) => + case qq if subsumes_erased(patternType, headPatternType) || (patternType_wrtEquals(patternType) <:< headPatternType) && !isDefaultPattern(pat) => ({if (pat.tpe =:= headPatternType /*never true for <equals>*/) EmptyTree else pat}::ms, (j,subpatterns(pat))::ss, rs); case _ if (headPatternType <:< patternType /*never true for <equals>*/) || isDefaultPattern(pat) => @@ -939,7 +945,8 @@ trait ParallelMatching { markReachedTwice(bx) // if some bx is not reached twice, its LabelDef val args = new ListBuffer[Ident] // is replaced with body itself var vs = vss(bx).elements; while(vs.hasNext) { - val substv = subst(vs.next) + val v = vs.next + val substv = subst(v) assert(substv ne null, "subst is null") // if sharing takes place, then 'binding elsewhere' is not allowed args += substv } @@ -1181,6 +1188,7 @@ trait ParallelMatching { singleType(sym.tpe.prefix, sym.linkedModuleOfClass) // e.g. None, Nil } else sym.tpe (ptpe.typeSymbol == sym) || (symtpe <:< ptpe) || + (symtpe.parents.exists(_.typeSymbol eq ptpe.typeSymbol)) || // e.g. Some[Int] <: Option[&b] /* outer, see scala.util.parsing.combinator.lexical.Scanner */ (ptpe.prefix.memberType(sym) <:< ptpe) } diff --git a/src/compiler/scala/tools/nsc/symtab/GenerateIdeMaps.scala b/src/compiler/scala/tools/nsc/symtab/GenerateIdeMaps.scala index d6855760aa..66f32086c2 100644 --- a/src/compiler/scala/tools/nsc/symtab/GenerateIdeMaps.scala +++ b/src/compiler/scala/tools/nsc/symtab/GenerateIdeMaps.scala @@ -261,7 +261,7 @@ abstract class GenerateIdeMaps extends SubComponent { val types = tpe.asInstanceOf[TypeRef].args trees.zip(types).foreach{ case (tree,tpe) => assert(tree != null && tpe != null); h(tree, tpe) - case _ => + //case _ => } case _ => } diff --git a/test/files/run/patmatnew.scala b/test/files/run/patmatnew.scala index dc8e21701a..f4852b4a0c 100644 --- a/test/files/run/patmatnew.scala +++ b/test/files/run/patmatnew.scala @@ -112,7 +112,7 @@ object Test extends TestConsoleMain { }) assertEquals("s3", 1, ("hello") match { case s:String => 1 - case _ => 0 + //case _ => 0 // unreachable! }) val xyz: (int, String, boolean) = (1, "abc", true); assertEquals("s4", 1, xyz._1 match { @@ -797,6 +797,14 @@ object Test extends TestConsoleMain { override def runTest { assert(Y.toString ne null) /*instantiate Y*/ } } + object Ticket211 extends TestCase("#211") { + override def runTest { + (Some(123):Option[Int]) match { + case (x:Option[a]) if false => {}; + case (y:Option[b]) => {}; + } + } + } } |