diff options
author | Martin Odersky <odersky@gmail.com> | 2007-01-16 20:33:20 +0000 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2007-01-16 20:33:20 +0000 |
commit | 6093bbedc0c0cf39650c4cd931afb18feb1bcda8 (patch) | |
tree | 3c812fab17a33c73b6ce03bb9129d0674dd1b6bf /src/compiler | |
parent | 96376cd15412c66bcd30e9b397f211eec4e7bf35 (diff) | |
download | scala-6093bbedc0c0cf39650c4cd931afb18feb1bcda8.tar.gz scala-6093bbedc0c0cf39650c4cd931afb18feb1bcda8.tar.bz2 scala-6093bbedc0c0cf39650c4cd931afb18feb1bcda8.zip |
enabled -Xunapply.
fixed bug contrib 291.
Added Map/Set types to Predef.
Option no longer inherits from Iterable, but there's an implicit conversion.
various other small things.
Diffstat (limited to 'src/compiler')
-rw-r--r-- | src/compiler/scala/tools/nsc/Settings.scala | 1 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/transform/UnCurry.scala | 10 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Infer.scala | 19 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Typers.scala | 49 |
4 files changed, 42 insertions, 37 deletions
diff --git a/src/compiler/scala/tools/nsc/Settings.scala b/src/compiler/scala/tools/nsc/Settings.scala index 4ee1ec82d0..129d0dcfaf 100644 --- a/src/compiler/scala/tools/nsc/Settings.scala +++ b/src/compiler/scala/tools/nsc/Settings.scala @@ -129,6 +129,7 @@ class Settings(error: String => unit) { val Xscript = new BooleanSetting("-Xscript", "compile script file") { override def hiddenToIDE = true } val Xexperimental = BooleanSetting("-Xexperimental", "enable experimental extensions") val Xunapply = BooleanSetting("-Xunapply", "enable unapply pattern matching") + Xunapply.value = true val Xplugtypes = BooleanSetting("-Xplugtypes", "parse but ignore annotations in more locations") val Xkilloption = BooleanSetting("-Xkilloption", "optimizes option types") val XprintOuterMatches = BooleanSetting("-XprintOuterMatches", "prints outer-checks caused by pattern matching ") diff --git a/src/compiler/scala/tools/nsc/transform/UnCurry.scala b/src/compiler/scala/tools/nsc/transform/UnCurry.scala index 352dc3b75c..b3feb1ed7f 100644 --- a/src/compiler/scala/tools/nsc/transform/UnCurry.scala +++ b/src/compiler/scala/tools/nsc/transform/UnCurry.scala @@ -424,9 +424,13 @@ abstract class UnCurry extends InfoTransform with TypingTransformers { case _ => val tree1 = super.transform(tree) if (isByNameRef(tree1)) - localTyper.typed(atPos(tree1.pos)( - Apply(Select(tree1 setType functionType(List(), tree1.tpe), nme.apply), List()))) - else tree1; + return localTyper.typed { + atPos(tree1.pos) { + Apply(Select(tree1 setType functionType(List(), tree1.tpe), nme.apply), + List()) + } + } + tree1 } } setType uncurryTreeType(tree.tpe) diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala index 35954ca8a7..63b59f01cb 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala @@ -843,30 +843,29 @@ trait Infer requires Analyzer { } } - def inferTypedPattern(tpt: Tree, pt: Type): Type = { - //Console.println("infer typed pattern: "+tpt+" wrt "+pt)//debug - checkCheckable(tpt.pos, tpt.tpe) - if (!(tpt.tpe <:< pt)) { - val tpparams = freeTypeParamsOfTerms.collect(tpt.tpe) + def inferTypedPattern(pos: PositionType, pattp: Type, pt: Type): Type = { + checkCheckable(pos, pattp) + if (!(pattp <:< pt)) { + val tpparams = freeTypeParamsOfTerms.collect(pattp) if (settings.debug.value) log("free type params (1) = " + tpparams) var tvars = tpparams map freshVar - var tp = tpt.tpe.subst(tpparams, tvars) + var tp = pattp.subst(tpparams, tvars) if (!(tp <:< pt)) { tvars = tpparams map freshVar - tp = tpt.tpe.subst(tpparams, tvars) + tp = pattp.subst(tpparams, tvars) val ptparams = freeTypeParamsOfTerms.collect(pt) if (settings.debug.value) log("free type params (2) = " + ptparams) val ptvars = ptparams map freshVar val pt1 = pt.subst(ptparams, ptvars) if (!isPopulated(tp, pt1)) { - error(tpt.pos, "pattern type is incompatibe with expected type"+foundReqMsg(tpt.tpe, pt)) - return tpt.tpe + error(pos, "pattern type is incompatibe with expected type"+foundReqMsg(pattp, pt)) + return pattp } ptvars foreach instantiateTypeVar } tvars foreach instantiateTypeVar } - intersect(pt, tpt.tpe) + intersect(pt, pattp) } def inferModulePattern(pat: Tree, pt: Type) = diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 7d361a1800..2bea199dbc 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -1417,6 +1417,7 @@ trait Typers requires Analyzer { // !!! this is fragile, maybe needs to be revised when unapply patterns become terms val unapp = definitions.unapplyMember(otpe) assert(unapp.exists, tree) + val unappType = otpe.memberType(unapp) // this is no longer needed! @@ -1427,11 +1428,12 @@ trait Typers requires Analyzer { if (args.length > MaxTupleArity) error(fun.pos, "too many arguments for unapply pattern, maximum = "+MaxTupleArity) val arg = Ident(argDummy) setType argDummyType +/* var funPt: Type = null try { funPt = unapp.name match { case nme.unapply => unapplyReturnTypeExpected(args.length) - case nme.unapplySeq => unapplyTypeListFromReturnTypeSeq(unapp.tpe) match { + case nme.unapplySeq => unapplyTypeListFromReturnTypeSeq(unappType) match { case List() => null //fail case List(TypeRef(pre,repeatedParam, tpe)) => optionType(seqType(WildcardType)) //succeed case xs => optionType(productType((xs.tail map {x => WildcardType}) ::: List(seqType(WildcardType))))// succeed @@ -1444,31 +1446,30 @@ trait Typers requires Analyzer { error(fun.pos, " unapplySeq should return Option[T] for T<:Product?[...Seq[?]]") return setError(tree) } - val fun0 = Ident(fun.symbol) setPos fun.pos setType otpe // would this change when patterns are terms??? - val fun1untyped = atPos(fun.pos) { - Apply(Select(gen.mkAttributedRef(fun.tpe.prefix,fun.symbol), unapp), List(arg)) - } - - // bq: find out if argument requires instanceOf check, if yes then lie about the type +*/ val oldArgType = arg.tpe - unapp.tpe match { - case MethodType(formals, restpe) => - if(!isSubType(arg.tpe, formals(0))) { - //Console.println(" -- apply mono hack") - arg.tpe = AllClass.tpe // deceive typechecker, we'll insert an instanceOf check later - } - case PolyType(tparams,MethodType(fmls, res)) => - try { - methTypeArgs(tparams, fmls, res, List(arg.tpe.deconst), WildcardType, new ListBuffer[Symbol]()) - } catch { - case e => //Console.println(e.getMessage()) - //Console.println(" -- apply poly hack") - arg.tpe = AllClass.tpe // deceive typechecker, we'll insert an instanceOf check later - } + if (!isApplicable(List(), unappType, List(arg.tpe), WildcardType)) { + //Console.println("UNAPP: need to typetest, arg.tpe = "+arg.tpe+", unappType = "+unappType) + def freshArgType(tp: Type): {Type, List[Symbol]} = tp match { + case MethodType(formals, restpe) => + {formals(0), List()} + case PolyType(tparams, restype) => + val tparams1 = cloneSymbols(tparams) + {freshArgType(restype)._1.substSym(tparams, tparams1), tparams1} + } + val {unappFormal, freeVars} = freshArgType(unappType) + val context1 = context.makeNewScope(context.tree, context.owner) + freeVars foreach context1.scope.enter + val typer1 = new Typer(context1) + arg.tpe = typer1.infer.inferTypedPattern(tree.pos, unappFormal, arg.tpe) + //todo: replace arg with arg.asInstanceOf[inferTypedPattern(unappFormal, arg.tpe)] instead. } - //Console.println("UNAPPLY2 "+fun+"/"+fun.tpe+" "+fun1untyped+", funPt = "+funPt) - val fun1 = typed(fun1untyped, EXPRmode, funPt) + val fun1untyped = atPos(fun.pos) { + Apply(Select(gen.mkAttributedRef(fun.tpe.prefix,fun.symbol), unapp), List(arg)) + } + //Console.println("UNAPPLY2 "+fun+"/"+fun.tpe+" "+fun1untyped) + val fun1 = typed(fun1untyped) if (fun1.tpe.isErroneous) setError(tree) else { val formals0 = unapplyTypeList(fun1.symbol, fun1.tpe) @@ -2021,7 +2022,7 @@ trait Typers requires Analyzer { case Typed(expr, tpt) => val tpt1 = typedType(tpt) val expr1 = typed(expr, mode & stickyModes, tpt1.tpe) - val owntype = if ((mode & PATTERNmode) != 0) inferTypedPattern(tpt1, widen(pt)) else tpt1.tpe + val owntype = if ((mode & PATTERNmode) != 0) inferTypedPattern(tpt1.pos, tpt1.tpe, widen(pt)) else tpt1.tpe //Console.println(typed pattern: "+tree+":"+", tp = "+tpt1.tpe+", pt = "+pt+" ==> "+owntype)//DEBUG copy.Typed(tree, expr1, tpt1) setType owntype |