summaryrefslogtreecommitdiff
path: root/src/compiler
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2007-01-16 20:33:20 +0000
committerMartin Odersky <odersky@gmail.com>2007-01-16 20:33:20 +0000
commit6093bbedc0c0cf39650c4cd931afb18feb1bcda8 (patch)
tree3c812fab17a33c73b6ce03bb9129d0674dd1b6bf /src/compiler
parent96376cd15412c66bcd30e9b397f211eec4e7bf35 (diff)
downloadscala-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.scala1
-rw-r--r--src/compiler/scala/tools/nsc/transform/UnCurry.scala10
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Infer.scala19
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala49
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