summaryrefslogtreecommitdiff
path: root/sources/scala/tools/nsc/typechecker/Typers.scala
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2005-06-15 16:05:25 +0000
committerMartin Odersky <odersky@gmail.com>2005-06-15 16:05:25 +0000
commit7fe5ed6df81d9a1ca0a6e333426b5ac77abcde39 (patch)
tree7577a98bbeb2e40dda69e562ee1e95535793a071 /sources/scala/tools/nsc/typechecker/Typers.scala
parent1ec9209a8d92e7e25dc40f3624af44451da260b7 (diff)
downloadscala-7fe5ed6df81d9a1ca0a6e333426b5ac77abcde39.tar.gz
scala-7fe5ed6df81d9a1ca0a6e333426b5ac77abcde39.tar.bz2
scala-7fe5ed6df81d9a1ca0a6e333426b5ac77abcde39.zip
*** empty log message ***
Diffstat (limited to 'sources/scala/tools/nsc/typechecker/Typers.scala')
-rwxr-xr-xsources/scala/tools/nsc/typechecker/Typers.scala66
1 files changed, 48 insertions, 18 deletions
diff --git a/sources/scala/tools/nsc/typechecker/Typers.scala b/sources/scala/tools/nsc/typechecker/Typers.scala
index 027956badc..95e67bba77 100755
--- a/sources/scala/tools/nsc/typechecker/Typers.scala
+++ b/sources/scala/tools/nsc/typechecker/Typers.scala
@@ -198,8 +198,22 @@ abstract class Typers: Analyzer {
else if ((mode & (EXPRmode | QUALmode)) == EXPRmode && !sym.isValue) // (2)
errorTree(tree, sym.toString() + " is not a value");
else if (sym.isStable && pre.isStable && tree.tpe.symbol != ByNameParamClass &&
- (pt.isStable || (mode & QUALmode) != 0 && !sym.isConstant || sym.isModule)) { // (3)
- tree.setType(singleType(pre, sym))
+ (pt.isStable || (mode & QUALmode) != 0 && !sym.isConstant ||
+ sym.isModule && !sym.tpe.isInstanceOf[MethodType])) {
+ tree.setType(singleType(pre, sym))
+ } else tree
+ }
+
+ def stabilizeFun(tree: Tree, mode: int, pt: Type): Tree = {
+ val sym = tree.symbol;
+ val pre = tree match {
+ case Select(qual, _) => qual.tpe
+ case _ => NoPrefix
+ }
+ if (tree.tpe.isInstanceOf[MethodType] && pre.isStable &&
+ (pt.isStable || (mode & QUALmode) != 0 && !sym.isConstant || sym.isModule)) {
+ assert(sym.tpe.paramTypes.isEmpty);
+ tree.setType(MethodType(List(), singleType(pre, sym)))
} else tree
}
@@ -803,7 +817,7 @@ abstract class Typers: Analyzer {
copy.Select(tree, Apply(coercion, List(qual)) setPos qual.pos, name), mode, pt)
}
if (sym.info == NoType) {
- if (settings.debug.value) log("qual = " + qual + ":" + qual.tpe + "\nmembers = " + qual.tpe.members + "\nfound = " + sym);
+ if (settings.debug.value) log("qual = " + qual + ":" + qual.tpe + "\nSymbol=" + qual.tpe.symbol + "\nsymbol-info = " + qual.tpe.symbol.info + "\nscope-id = " + qual.tpe.symbol.info.decls.hashCode() + "\nmembers = " + qual.tpe.members + "\nfound = " + sym);
errorTree(tree,
decode(name) + " is not a member of " + qual.tpe.widen +
(if (Position.line(tree.pos) > Position.line(qual.pos))
@@ -978,6 +992,14 @@ abstract class Typers: Analyzer {
if (vble.name != nme.WILDCARD) namer.enterInScope(vble);
copy.Bind(tree, name, body1) setSymbol vble setType pt
+ case SeqTerm(elems) =>
+ val elempt = pt.baseType(SeqClass) match {
+ case TypeRef(pre, seqClass, List(arg)) => arg
+ case _ => WildcardType
+ }
+ val elems1 = List.mapConserve(elems)(elem => typed(elem, mode, elempt));
+ copy.SeqTerm(tree, elems1) setType ptOrLub(elems1 map (.tpe))
+
case fun @ Function(_, _) =>
newTyper(context.makeNewScope(tree, context.owner)).typedFunction(fun, mode, pt)
@@ -1073,21 +1095,29 @@ abstract class Typers: Analyzer {
typedTypeApply(typed(fun, funmode | TAPPmode, WildcardType), args1)
case Apply(fun, args) =>
- val funpt = if ((mode & PATTERNmode) != 0) pt else WildcardType;
- var fun1 = typed(fun, funmode, funpt);
- // if function is overloaded, filter all alternatives that match
- // number of arguments and expected result type.
- // if (settings.debug.value) log("trans app " + fun1 + ":" + fun1.symbol + ":" + fun1.tpe + " " + args);//DEBUG
- if (fun1.hasSymbol && fun1.symbol.hasFlag(OVERLOADED)) {
- val argtypes = args map (arg => AllClass.tpe);
- val pre = fun1.symbol.tpe.prefix;
- val sym = fun1.symbol filter (alt =>
- isApplicable(context.undetparams, pre.memberType(alt), argtypes, pt));
- if (sym != NoSymbol)
- fun1 = adapt(fun1 setSymbol sym setType pre.memberType(sym), funmode, WildcardType)
- }
- appcnt = appcnt + 1;
- typedApply(fun1, args)
+ val stableApplication =
+ fun.symbol != null && fun.symbol.tpe.isInstanceOf[MethodType] && fun.symbol.isStable;
+ if (stableApplication && (mode & PATTERNmode) != 0) {
+ // treat stable function applications f() as expressions.
+ typed1(tree, mode & ~PATTERNmode | EXPRmode, pt)
+ } else {
+ val funpt = if ((mode & PATTERNmode) != 0) pt else WildcardType;
+ var fun1 = typed(fun, funmode, funpt);
+ if (stableApplication) fun1 = stabilizeFun(fun1, mode, pt);
+ // if function is overloaded, filter all alternatives that match
+ // number of arguments and expected result type.
+ // if (settings.debug.value) log("trans app " + fun1 + ":" + fun1.symbol + ":" + fun1.tpe + " " + args);//DEBUG
+ if (fun1.hasSymbol && fun1.symbol.hasFlag(OVERLOADED)) {
+ val argtypes = args map (arg => AllClass.tpe);
+ val pre = fun1.symbol.tpe.prefix;
+ val sym = fun1.symbol filter (alt =>
+ isApplicable(context.undetparams, pre.memberType(alt), argtypes, pt));
+ if (sym != NoSymbol)
+ fun1 = adapt(fun1 setSymbol sym setType pre.memberType(sym), funmode, WildcardType)
+ }
+ appcnt = appcnt + 1;
+ typedApply(fun1, args)
+ }
case Super(qual, mix) =>
val clazz = if (tree.symbol != NoSymbol) tree.symbol else qualifyingClass(qual);