summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/typechecker/Typers.scala
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2006-10-19 20:52:30 +0000
committerMartin Odersky <odersky@gmail.com>2006-10-19 20:52:30 +0000
commitbcac3c45b280584f740c94b2ccd77f7812adf672 (patch)
treebe08675b14e33b8b78c828e0626e8920420eabd5 /src/compiler/scala/tools/nsc/typechecker/Typers.scala
parent458d3d10cfcd7dd44cb1d6b02de7ea0fdbe6b955 (diff)
downloadscala-bcac3c45b280584f740c94b2ccd77f7812adf672.tar.gz
scala-bcac3c45b280584f740c94b2ccd77f7812adf672.tar.bz2
scala-bcac3c45b280584f740c94b2ccd77f7812adf672.zip
added support for typed patterns
Diffstat (limited to 'src/compiler/scala/tools/nsc/typechecker/Typers.scala')
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala71
1 files changed, 47 insertions, 24 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 9beb1db673..6cabad4aa6 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -288,10 +288,12 @@ trait Typers requires Analyzer {
!o.privateWithin.ownerChain.contains(sym.owner))
o = o.owner
if (o == sym.owner) badSymbol = sym
- } else if (sym.owner.isTerm) {
- val e = scope.lookupEntry(sym.name)
- if (e != null && e.sym == sym && e.owner == scope && !e.sym.isTypeParameterOrSkolem)
- badSymbol = e.sym
+ } else if (sym.owner.isTerm && !sym.isTypeParameterOrSkolem) {
+ var e = scope.lookupEntry(sym.name)
+ while (e != null && e.owner == scope && badSymbol == NoSymbol) {
+ if (e.sym == sym) badSymbol = e.sym
+ e = scope.lookupNextEntry(e)
+ }
}
}
if (badSymbol == NoSymbol)
@@ -464,7 +466,7 @@ trait Typers requires Analyzer {
if (clazz.hasFlag(CASE)) { // (5.1)
val tree1 = TypeTree(clazz.primaryConstructor.tpe.asSeenFrom(tree.tpe.prefix, clazz.owner)) setOriginal tree
try {
- inferConstructorInstance(tree1, clazz.typeParams, pt)
+ inferConstructorInstance(tree1, clazz.typeParams, widen(pt))
} catch {
case npe : NullPointerException =>
logError("CONTEXT: " + context.unit.source.dbg(tree.pos), npe)
@@ -520,9 +522,9 @@ trait Typers requires Analyzer {
typed(atPos(tree.pos)(Select(qual, nme.apply)), mode, pt)
} else if (!context.undetparams.isEmpty && (mode & POLYmode) == 0) { // (9)
instantiate(tree, mode, pt)
- } else if (tree.tpe <:< pt) {
+ } else if ((mode & PATTERNmode) != 0) {
tree
- } else if ((mode & PATTERNmode) != 0 && treeInfo.isSequencePattern(tree)) {
+ } else if (tree.tpe <:< pt) {
tree
} else {
val tree1 = constfold(tree, pt) // (10) (11)
@@ -998,15 +1000,17 @@ trait Typers requires Analyzer {
else typed(cdef.guard, BooleanClass.tpe)
var body1: Tree = typed(cdef.body, pt)
if (!context.savedTypeBounds.isEmpty) {
- context.restoreTypeBounds
- // the following is a hack to make the pattern matcher work
- body1 =
- typed {
- atPos(body1.pos) {
- TypeApply(Select(body1, Any_asInstanceOf), List(TypeTree(pt)))
+ body1.tpe = context.restoreTypeBounds(body1.tpe)
+ if (isFullyDefined(pt))
+ // the following is a hack to make the pattern matcher work !!! (still needed?)
+ body1 =
+ typed {
+ atPos(body1.pos) {
+ TypeApply(Select(body1, Any_asInstanceOf), List(TypeTree(pt)))
+ }
}
- }
}
+ body1 = checkNoEscaping.locals(context.scope, pt, body1)
copy.CaseDef(cdef, pat1, guard1, body1) setType body1.tpe
}
@@ -1611,8 +1615,22 @@ trait Typers requires Analyzer {
case Bind(name, body) =>
var vble = tree.symbol
- if (vble == NoSymbol) vble = context.owner.newValue(tree.pos, name)
- if (vble.name != nme.WILDCARD) {
+ if (name.isTypeName) {
+ assert(body == EmptyTree)
+ if (vble == NoSymbol)
+ vble =
+ if (isFullyDefined(pt))
+ context.owner.newAliasType(tree.pos, name) setInfo pt
+ else
+ context.owner.newAbstractType(tree.pos, name) setInfo
+ TypeBounds(AllClass.tpe, AnyClass.tpe)
+ if (vble.name == nme.WILDCARD.toTypeName) context.scope.enter(vble)
+ else namer.enterInScope(vble)
+ tree setType vble.tpe
+ } else {
+ if (vble == NoSymbol)
+ vble = context.owner.newValue(tree.pos, name)
+ if (vble.name.toTermName != nme.WILDCARD) {
/*
if (namesSomeIdent(vble.name))
context.unit.warning(tree.pos,
@@ -1620,13 +1638,14 @@ trait Typers requires Analyzer {
"use backquotes `"+vble.name+"` if you mean to match against that value;\n" +
"or rename the variable or use an explicit bind "+vble.name+"@_ to avoid this warning.")
*/
- namer.enterInScope(vble)
+ namer.enterInScope(vble)
+ }
+ val body1 = typed(body, mode, pt)
+ vble.setInfo(
+ if (treeInfo.isSequenceValued(body)) seqType(body1.tpe)
+ else body1.tpe)
+ copy.Bind(tree, name, body1) setSymbol vble setType body1.tpe // buraq, was: pt
}
- val body1 = typed(body, mode, pt)
- vble.setInfo(
- if (treeInfo.isSequenceValued(body)) seqType(body1.tpe)
- else body1.tpe)
- copy.Bind(tree, name, body1) setSymbol vble setType body1.tpe // buraq, was: pt
case ArrayValue(elemtpt, elems) =>
val elemtpt1 = typedType(elemtpt)
@@ -1742,10 +1761,13 @@ trait Typers requires Analyzer {
case _ =>
setError(tree)
}
+
case Typed(expr, tpt) =>
val tpt1 = typedType(tpt)
val expr1 = typed(expr, mode & stickyModes, tpt1.tpe)
- copy.Typed(tree, expr1, tpt1) setType tpt1.tpe
+ val owntype = if ((mode & PATTERNmode) != 0) inferTypedPattern(tpt1, widen(pt)) else tpt1.tpe
+ //Console.println(typed pattern: "+tree+":"+", tp = "+tpt1.tpe+", pt = "+pt+" ==> "+owntype)//DEBUG
+ copy.Typed(tree, expr1, tpt1) setType owntype
case TypeApply(fun, args) =>
val args1 = List.mapConserve(args)(typedType)
@@ -1837,7 +1859,8 @@ trait Typers requires Analyzer {
case Ident(name) =>
idcnt = idcnt + 1
- if (name == nme.WILDCARD && (mode & (PATTERNmode | FUNmode)) == PATTERNmode)
+ if ((name == nme.WILDCARD && (mode & (PATTERNmode | FUNmode)) == PATTERNmode) ||
+ (name == nme.WILDCARD.toTypeName && (mode & TYPEmode) != 0))
tree setType pt
else
typedIdent(name)