summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/scala/tools/nsc/CompileSocket.scala8
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/Parsers.scala7
-rw-r--r--src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala7
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Types.scala14
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Contexts.scala17
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Namers.scala136
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala286
-rw-r--r--test/files/neg/bug563.check7
-rw-r--r--test/files/neg/bug633.check4
-rw-r--r--test/files/neg/bug633.scala8
-rw-r--r--test/files/neg/bug639.check9
-rw-r--r--test/files/neg/bug639.scala3
-rw-r--r--test/files/pos/bug640.scala2
-rw-r--r--test/files/run/bigints.check5
-rwxr-xr-xtest/files/run/bigints.scala14
-rw-r--r--test/files/run/bug629.check1
-rw-r--r--test/files/run/bug629.scala13
17 files changed, 319 insertions, 222 deletions
diff --git a/src/compiler/scala/tools/nsc/CompileSocket.scala b/src/compiler/scala/tools/nsc/CompileSocket.scala
index 32683d9029..5549cf18b7 100644
--- a/src/compiler/scala/tools/nsc/CompileSocket.scala
+++ b/src/compiler/scala/tools/nsc/CompileSocket.scala
@@ -99,6 +99,7 @@ object CompileSocket {
def deletePort(port: int): unit = portFile(port).delete()
def getOrCreateSocket(vmArgs: String): Socket = {
+ val nAttempts = 9;
def getsock(attempts: int): Socket =
if (attempts == 0) {
System.err.println("unable to establish connection to server; exiting");
@@ -114,10 +115,13 @@ object CompileSocket {
System.err.println("...connection attempt to server at port "+port+" failed; re-trying...")
if (attempts % 2 == 0) portFile(port).delete()
Thread.sleep(100)
- getsock(attempts - 1)
+ val result = getsock(attempts - 1)
+ if (attempts == nAttempts)
+ System.err.println("... connection established at port "+port)
+ result
}
}
- getsock(9)
+ getsock(nAttempts)
}
def getSocket(serverAdr: String): Socket = {
diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
index ce885459a9..bc0b7a035e 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
@@ -43,9 +43,10 @@ import Tokens._;
trait Parsers requires SyntaxAnalyzer {
import global._;
+ private val glob: global.type = global;
import posAssigner.atPos;
- class Parser(unit: CompilationUnit) {
+ class Parser(unit: global.CompilationUnit) {
val in = new Scanner(unit);
@@ -1316,7 +1317,7 @@ trait Parsers requires SyntaxAnalyzer {
param
}
val params = new ListBuffer[AbsTypeDef];
- newLineOptWhenFollowedBy(LBRACKET);
+ //newLineOptWhenFollowedBy(LBRACKET);
if (in.token == LBRACKET) {
in.nextToken();
params += typeParam();
@@ -1825,7 +1826,7 @@ trait Parsers requires SyntaxAnalyzer {
nvps.toList
} else List()
val constr = atPos(pos) { New(t, List(args)) }
- atPos(pos) { Attribute(constr, nameValuePairs) }
+ atPos(pos) { glob.Attribute(constr, nameValuePairs) }
}
def mixinAttribute(attrs: List[Tree]) = {
diff --git a/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala b/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala
index de8af15695..5611af7b1e 100644
--- a/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala
+++ b/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala
@@ -49,8 +49,9 @@ abstract class SymbolLoaders {
phase = currentphase;
def source = kindString + " " + sourceString;
informTime("loaded " + source, start);
- if (root.rawInfo != this) {
- ok = true;
+ if (root.rawInfo == this && root.linkedSym.rawInfo == this)
+ throw new TypeError(source + " does not define " + root)
+ ok = true;
/*
val sourceFile0 = if (sourceFile == null) (root match {
case clazz: ClassSymbol => clazz.sourceFile;
@@ -59,7 +60,6 @@ abstract class SymbolLoaders {
setSource(root.linkedModule.moduleClass, sourceFile0);
setSource(root.linkedClass, sourceFile0);
*/
- } else throw new TypeError(source + " does not define " + root)
} catch {
case ex: IOException =>
ok = false;
@@ -72,6 +72,7 @@ abstract class SymbolLoaders {
initRoot(root);
if (!root.isPackageClass) initRoot(root.linkedSym);
}
+
override def load(root: Symbol): unit = complete(root);
private def initRoot(root: Symbol): unit = {
diff --git a/src/compiler/scala/tools/nsc/symtab/Types.scala b/src/compiler/scala/tools/nsc/symtab/Types.scala
index e2f8e23b3f..117f4d73cf 100644
--- a/src/compiler/scala/tools/nsc/symtab/Types.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Types.scala
@@ -890,8 +890,14 @@ trait Types requires SymbolTable {
}
val str = (pre.prefixString + sym.nameString +
(if (args.isEmpty) "" else args.mkString("[", ",", "]")))
- if (sym.isPackageClass) "package "+str
- else if (sym.isModuleClass) "object "+str
+ if (sym.isPackageClass)
+ "package "+str
+ else if (sym.isModuleClass)
+ "object "+str
+ else if (sym.isAnonymousClass && sym.isInitialized)
+ sym.info.parents.mkString("", " with ", "{ ... }")
+ else if (sym.isRefinementClass && sym.isInitialized)
+ sym.info.toString()
else str
}
@@ -2178,7 +2184,9 @@ trait Types requires SymbolTable {
// Errors and Diagnostics ---------------------------------------------------------
/** An exception signalling a type error */
- class TypeError(val msg: String) extends java.lang.Error(msg);
+ class TypeError(val pos: int, val msg: String) extends java.lang.Error(msg) {
+ def this(msg: String) = this(Position.NOPOS, msg)
+ }
class NoCommonType(tps: List[Type]) extends java.lang.Error(
"lub/glb of incompatible types: " + tps.mkString("", " and ", ""));
diff --git a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
index f85c5040e4..82c12f7e4b 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
@@ -72,7 +72,7 @@ trait Contexts requires Analyzer {
// template or package definition
var enclMethod: Context = _; // The next outer context whose tree is a method
var variance: int = _; // Variance relative to enclosing class.
- private var _undetparams: List[Symbol] = List(); // Undetermined type parameters
+ private var _undetparams: List[Symbol] = List(); // Undetermined type parameters, not inherited to child contexts
var depth: int = 0
var imports: List[ImportInfo] = List()
@@ -83,6 +83,7 @@ trait Contexts requires Analyzer {
var reportGeneralErrors = false
var implicitsEnabled = false
var checking = false
+ var retyping = false
var savedTypeBounds: List[Pair[Symbol, Type]] = List()
@@ -121,6 +122,7 @@ trait Contexts requires Analyzer {
c.reportGeneralErrors = this.reportGeneralErrors
c.implicitsEnabled = this.implicitsEnabled
c.checking = this.checking
+ c.retyping = this.retyping
c.outer = this
c
}
@@ -148,10 +150,15 @@ trait Contexts requires Analyzer {
def make(tree: Tree): Context =
make(tree, owner)
- def makeImplicit(reportAmbiguousErrors: boolean) = {
+ def makeSilent(reportAmbiguousErrors: boolean): Context = {
val c = make(tree)
- c.reportAmbiguousErrors = reportAmbiguousErrors
c.reportGeneralErrors = false
+ c.reportAmbiguousErrors = reportAmbiguousErrors
+ c
+ }
+
+ def makeImplicit(reportAmbiguousErrors: boolean) = {
+ val c = makeSilent(reportAmbiguousErrors)
c.implicitsEnabled = false
c
}
@@ -191,7 +198,7 @@ trait Contexts requires Analyzer {
if (reportGeneralErrors)
unit.error(pos, if (checking) "**** ERROR DURING INTERNAL CHECKING ****\n" + msg else msg)
else
- throw new TypeError(msg)
+ throw new TypeError(pos, msg)
def ambiguousError(pos: int, pre: Type, sym1: Symbol, sym2: Symbol, rest: String): unit = {
val msg =
@@ -202,7 +209,7 @@ trait Contexts requires Analyzer {
if (reportAmbiguousErrors) {
if (!pre.isErroneous && !sym1.isErroneous && !sym2.isErroneous)
unit.error(pos, msg)
- } else throw new TypeError(msg)
+ } else throw new TypeError(pos, msg)
}
def outerContext(clazz: Symbol): Context = {
diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
index 0dab8927f5..f9e886ab8c 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
@@ -233,7 +233,7 @@ trait Namers requires Analyzer {
tree.pos, mods.flags & AccessFlags | METHOD | CASE, name.toTermName)
.setInfo(innerNamer.caseFactoryCompleter(tree));
setPrivateWithin(tree.symbol, mods);
- }
+ }
tree.symbol = enterClassSymbol(tree.pos, mods.flags, name);
setPrivateWithin(tree.symbol, mods);
finishWith(tparams);
@@ -459,73 +459,75 @@ trait Namers requires Analyzer {
private def aliasTypeSig(tpsym: Symbol, tparams: List[AbsTypeDef], rhs: Tree): Type =
makePolyType(typer.reenterTypeParams(tparams), typer.typedType(rhs).tpe);
- private def typeSig(tree: Tree): Type = deSkolemize {
- try {
- val sym: Symbol = tree.symbol;
- tree match {
- case ClassDef(_, _, tparams, tpt, impl) =>
- new Namer(context.makeNewScope(tree, sym)).classSig(tparams, tpt, impl)
-
- case ModuleDef(_, _, impl) =>
- val clazz = sym.moduleClass;
- clazz.setInfo(new Namer(context.make(tree, clazz)).templateSig(impl));
- //clazz.typeOfThis = singleType(sym.owner.thisType, sym);
- clazz.tpe;
-
- case DefDef(_, _, tparams, vparamss, tpt, rhs) =>
- val result =
- new Namer(context.makeNewScope(tree, sym)).methodSig(tparams, vparamss, tpt, rhs);
- checkContractive(sym, result)
-
- case ValDef(_, _, tpt, rhs) =>
- if (tpt.isEmpty) {
- if (rhs.isEmpty) {
- context.error(tpt.pos, "missing parameter type");
- ErrorType
+ private def typeSig(tree: Tree): Type = {
+ val result =
+ try {
+ val sym: Symbol = tree.symbol;
+ tree match {
+ case ClassDef(_, _, tparams, tpt, impl) =>
+ new Namer(context.makeNewScope(tree, sym)).classSig(tparams, tpt, impl)
+
+ case ModuleDef(_, _, impl) =>
+ val clazz = sym.moduleClass;
+ clazz.setInfo(new Namer(context.make(tree, clazz)).templateSig(impl));
+ //clazz.typeOfThis = singleType(sym.owner.thisType, sym);
+ clazz.tpe;
+
+ case DefDef(_, _, tparams, vparamss, tpt, rhs) =>
+ val result =
+ new Namer(context.makeNewScope(tree, sym)).methodSig(tparams, vparamss, tpt, rhs);
+ checkContractive(sym, result)
+
+ case ValDef(_, _, tpt, rhs) =>
+ if (tpt.isEmpty) {
+ if (rhs.isEmpty) {
+ context.error(tpt.pos, "missing parameter type");
+ ErrorType
+ } else {
+ tpt.tpe = deconstIfNotFinal(sym, newTyper(context.make(tree, sym)).computeType(rhs));
+ tpt.tpe
+ }
} else {
- tpt.tpe = deconstIfNotFinal(sym, newTyper(context.make(tree, sym)).computeType(rhs));
- tpt.tpe
+ val typer1 =
+ if (sym.hasFlag(PARAM) && sym.owner.isConstructor && !phase.erasedTypes)
+ newTyper(context.makeConstructorContext)
+ else typer;
+ typer1.typedType(tpt).tpe
+ }
+
+ case AliasTypeDef(_, _, tparams, rhs) =>
+ new Namer(context.makeNewScope(tree, sym)).aliasTypeSig(sym, tparams, rhs)
+
+ case AbsTypeDef(_, _, lo, hi) =>
+ //System.out.println("bounds of " + sym + ":" + sym.tpe + " = " + typer.typedType(hi).tpe);
+ TypeBounds(typer.typedType(lo).tpe, typer.typedType(hi).tpe);
+
+ case Import(expr, selectors) =>
+ val expr1 = typer.typedQualifier(expr);
+ val base = expr1.tpe;
+ typer.checkStable(expr1);
+ def checkSelectors(selectors: List[Pair[Name, Name]]): unit = selectors match {
+ case Pair(from, to) :: rest =>
+ if (from != nme.WILDCARD && base != ErrorType &&
+ base.member(from) == NoSymbol && base.member(from.toTypeName) == NoSymbol)
+ context.error(tree.pos, from.decode + " is not a member of " + expr);
+ if (from != nme.WILDCARD && (rest.exists (sel => sel._1 == from)))
+ context.error(tree.pos, from.decode + " is renamed twice");
+ if (to != null && to != nme.WILDCARD && (rest exists (sel => sel._2 == to)))
+ context.error(tree.pos, to.decode + " appears twice as a target of a renaming");
+ checkSelectors(rest)
+ case Nil =>
}
- } else {
- val typer1 =
- if (sym.hasFlag(PARAM) && sym.owner.isConstructor && !phase.erasedTypes)
- newTyper(context.makeConstructorContext)
- else typer;
- typer1.typedType(tpt).tpe
- }
-
- case AliasTypeDef(_, _, tparams, rhs) =>
- new Namer(context.makeNewScope(tree, sym)).aliasTypeSig(sym, tparams, rhs)
-
- case AbsTypeDef(_, _, lo, hi) =>
- //System.out.println("bounds of " + sym + ":" + sym.tpe + " = " + typer.typedType(hi).tpe);
- TypeBounds(typer.typedType(lo).tpe, typer.typedType(hi).tpe);
-
- case Import(expr, selectors) =>
- val expr1 = typer.typedQualifier(expr);
- val base = expr1.tpe;
- typer.checkStable(expr1);
- def checkSelectors(selectors: List[Pair[Name, Name]]): unit = selectors match {
- case Pair(from, to) :: rest =>
- if (from != nme.WILDCARD && base != ErrorType &&
- base.member(from) == NoSymbol && base.member(from.toTypeName) == NoSymbol)
- context.error(tree.pos, from.decode + " is not a member of " + expr);
- if (from != nme.WILDCARD && (rest.exists (sel => sel._1 == from)))
- context.error(tree.pos, from.decode + " is renamed twice");
- if (to != null && to != nme.WILDCARD && (rest exists (sel => sel._2 == to)))
- context.error(tree.pos, to.decode + " appears twice as a target of a renaming");
- checkSelectors(rest)
- case Nil =>
- }
- checkSelectors(selectors);
- ImportType(expr1)
- }
- } catch {
- case ex: TypeError =>
- //System.out.println("caught " + ex + " in typeSig");//DEBUG
- typer.reportTypeError(tree.pos, ex);
- ErrorType
- }
+ checkSelectors(selectors);
+ ImportType(expr1)
+ }
+ } catch {
+ case ex: TypeError =>
+ //System.out.println("caught " + ex + " in typeSig");//DEBUG
+ typer.reportTypeError(tree.pos, ex);
+ ErrorType
+ }
+ deSkolemize(result)
}
/** Check that symbol's definition is well-formed. This means:
@@ -546,7 +548,7 @@ trait Namers requires Analyzer {
Flags.flagsToString(flag1) + " and " + Flags.flagsToString(flag2));
if (sym.hasFlag(IMPLICIT) && !sym.isTerm)
context.error(sym.pos, "`implicit' modifier can be used only for values, variables and methods");
- if (sym.hasFlag(IMPLICIT) && sym.owner.isPackage)
+ if (sym.hasFlag(IMPLICIT) && sym.owner.isPackageClass)
context.error(sym.pos, "`implicit' modifier cannot be used for top-level objects");
if (sym.hasFlag(ABSTRACT) && !sym.isClass)
context.error(sym.pos, "`abstract' modifier can be used only for classes; " +
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 9d488261b4..bce9133222 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -58,7 +58,6 @@ trait Typers requires Analyzer {
private def inferView(pos: int, from: Type, to: Type, reportAmbiguous: boolean): Tree = {
if (settings.debug.value) log("infer view from "+from+" to "+to);//debug
- assert(!(from <:< to))//debug
if (phase.erasedTypes) EmptyTree
else from match {
case MethodType(_, _) => EmptyTree
@@ -124,11 +123,14 @@ trait Typers requires Analyzer {
private val stickyModes: int = EXPRmode | PATTERNmode | TYPEmode | CONSTmode
+ private def funMode(mode: int) = mode & stickyModes | FUNmode | POLYmode
+
/** Report a type error.
* @param pos The position where to report the error
* @param ex The exception that caused the error */
- def reportTypeError(pos: int, ex: TypeError): unit = {
+ def reportTypeError(pos0: int, ex: TypeError): unit = {
if (settings.debug.value) ex.printStackTrace()
+ val pos = if (ex.pos == Position.NOPOS) pos0 else ex.pos
ex match {
case CyclicReference(sym, info: TypeCompleter) =>
context.unit.error(
@@ -1011,9 +1013,98 @@ trait Typers requires Analyzer {
result
}
- protected def typed1(tree: Tree, mode: int, pt: Type): Tree = {
+ def typedArg(arg: Tree, mode: int, pt: Type): Tree = {
+ val argTyper = if ((mode & SCCmode) != 0) newTyper(context.makeConstructorContext)
+ else this
+ argTyper.typed(arg, mode & (stickyModes | POLYmode), pt)
+ }
+
+ def typedArgs(args: List[Tree], mode: int) =
+ List.mapConserve(args)(arg => typedArg(arg, mode, WildcardType))
+
+ def typedApply(tree: Tree, fun0: Tree, args: List[Tree], mode: int, pt: Type): Tree = {
+ var fun = fun0;
+ if (fun.hasSymbol && (fun.symbol hasFlag OVERLOADED)) {
+ // preadapt symbol to number of arguments given
+ val argtypes = args map (arg => AllClass.tpe)
+ val pre = fun.symbol.tpe.prefix
+ val sym = fun.symbol filter (alt =>
+ isApplicable(context.undetparams, pre.memberType(alt), argtypes, pt))
+ if (sym != NoSymbol)
+ fun = adapt(fun setSymbol sym setType pre.memberType(sym), funMode(mode), WildcardType)
+ }
+ fun.tpe match {
+ case OverloadedType(pre, alts) =>
+ val args1 = typedArgs(args, mode)
+ inferMethodAlternative(fun, context.undetparams, args1 map (.tpe.deconst), pt)
+ typedApply(tree, adapt(fun, funMode(mode), WildcardType), args1, mode, pt)
+ case MethodType(formals0, restpe) =>
+ val formals = formalTypes(formals0, args.length)
+ if (formals.length != args.length) {
+ //System.out.println(""+formals.length+" "+args.length);//DEBUG
+ errorTree(tree, "wrong number of arguments for "+treeSymTypeMsg(fun))
+ } else {
+ val tparams = context.undetparams
+ context.undetparams = List()
+ if (tparams.isEmpty) {
+ val args1 = List.map2(args, formals)((arg, formal) =>
+ typedArg(arg, mode, formal))
+ def ifPatternSkipFormals(tp: Type) = tp match {
+ case MethodType(_, rtp) if ((mode & PATTERNmode) != 0) => rtp
+ case _ => tp
+ }
+ if (fun.symbol == List_apply && args.isEmpty) {
+ gen.mkNil setType restpe
+ }
+ else if ((mode & CONSTmode) != 0 && fun.symbol.owner == PredefModule.tpe.symbol && fun.symbol.name == nme.Array) {
+ val elems = new Array[Constant](args1.length)
+ var i = 0;
+ for (val arg <- args1) arg match {
+ case Literal(value) =>
+ elems(i) = value
+ i = i + 1
+ case _ => errorTree(arg, "constant required")
+ }
+ val arrayConst = new ArrayConstant(elems, restpe)
+ Literal(arrayConst) setType ConstantType(arrayConst)
+ }
+ else
+ constfold(copy.Apply(tree, fun, args1).setType(ifPatternSkipFormals(restpe)))
+ } else {
+ assert((mode & PATTERNmode) == 0); // this case cannot arise for patterns
+ val lenientTargs = protoTypeArgs(tparams, formals, restpe, pt)
+ val strictTargs = List.map2(lenientTargs, tparams)((targ, tparam) =>
+ if (targ == WildcardType) tparam.tpe else targ)
+ def typedArgToPoly(arg: Tree, formal: Type): Tree = {
+ val lenientPt = formal.subst(tparams, lenientTargs)
+ val arg1 = typedArg(arg, mode | POLYmode, lenientPt)
+ val argtparams = context.undetparams
+ context.undetparams = List()
+ if (!argtparams.isEmpty) {
+ val strictPt = formal.subst(tparams, strictTargs)
+ inferArgumentInstance(arg1, argtparams, strictPt, lenientPt)
+ }
+ arg1
+ }
+ val args1 = List.map2(args, formals)(typedArgToPoly)
+ if (args1 exists (.tpe.isError)) setError(tree)
+ else {
+ if (settings.debug.value) log("infer method inst "+fun+", tparams = "+tparams+", args = "+args1.map(.tpe)+", pt = "+pt+", lobounds = "+tparams.map(.tpe.bounds.lo));//debug
+ val undetparams = inferMethodInstance(fun, tparams, args1, pt)
+ val result = typedApply(tree, fun, args1, mode, pt)
+ context.undetparams = undetparams
+ result
+ }
+ }
+ }
+ case ErrorType =>
+ setError(tree)
+ case _ =>
+ errorTree(tree, ""+fun+" does not take parameters")
+ }
+ }
- def funmode = mode & stickyModes | FUNmode | POLYmode
+ protected def typed1(tree: Tree, mode: int, pt: Type): Tree = {
def ptOrLub(tps: List[Type]) = if (isFullyDefined(pt)) pt else lub(tps)
@@ -1040,121 +1131,61 @@ trait Typers requires Analyzer {
errorTree(tree, treeSymTypeMsg(fun)+" does not take type parameters.")
}
- def typedArg(arg: Tree, pt: Type, polyMode: int): Tree = {
- val argTyper = if ((mode & SCCmode) != 0) newTyper(context.makeConstructorContext)
- else this
- argTyper.typed(arg, mode & stickyModes | polyMode, pt)
- }
-
- def typedArgs(args: List[Tree]) =
- List.mapConserve(args)(arg => typedArg(arg, WildcardType, 0))
-
- def typedApply(fun0: Tree, args: List[Tree]): Tree = {
- var fun = fun0;
- if (fun.hasSymbol && (fun.symbol hasFlag OVERLOADED)) {
- // preadapt symbol to number of arguments given
- val argtypes = args map (arg => AllClass.tpe)
- val pre = fun.symbol.tpe.prefix
- val sym = fun.symbol filter (alt =>
- isApplicable(context.undetparams, pre.memberType(alt), argtypes, pt))
- if (sym != NoSymbol)
- fun = adapt(fun setSymbol sym setType pre.memberType(sym), funmode, WildcardType)
- }
- fun.tpe match {
- case OverloadedType(pre, alts) =>
- val args1 = typedArgs(args)
- inferMethodAlternative(fun, context.undetparams, args1 map (.tpe.deconst), pt)
- typedApply(adapt(fun, funmode, WildcardType), args1)
- case MethodType(formals0, restpe) =>
- val formals = formalTypes(formals0, args.length)
- if (formals.length != args.length) {
- //System.out.println(""+formals.length+" "+args.length);//DEBUG
- errorTree(tree, "wrong number of arguments for "+treeSymTypeMsg(fun))
- } else {
- val tparams = context.undetparams
- context.undetparams = List()
- if (tparams.isEmpty) {
- val args1 = List.map2(args, formals)((arg, formal) => typedArg(arg, formal, 0))
- def ifPatternSkipFormals(tp: Type) = tp match {
- case MethodType(_, rtp) if ((mode & PATTERNmode) != 0) => rtp
- case _ => tp
- }
- if (fun.symbol == List_apply && args.isEmpty) {
- gen.mkNil setType restpe
- }
- else if ((mode & CONSTmode) != 0 && fun.symbol.owner == PredefModule.tpe.symbol && fun.symbol.name == nme.Array) {
- val elems = new Array[Constant](args1.length)
- var i = 0;
- for (val arg <- args1) arg match {
- case Literal(value) =>
- elems(i) = value
- i = i + 1
- case _ => errorTree(arg, "constant required")
- }
- val arrayConst = new ArrayConstant(elems, restpe)
- Literal(arrayConst) setType ConstantType(arrayConst)
- }
- else
- constfold(copy.Apply(tree, fun, args1).setType(ifPatternSkipFormals(restpe)))
- } else {
- assert((mode & PATTERNmode) == 0); // this case cannot arise for patterns
- val lenientTargs = protoTypeArgs(tparams, formals, restpe, pt)
- val strictTargs = List.map2(lenientTargs, tparams)((targ, tparam) =>
- if (targ == WildcardType) tparam.tpe else targ)
- def typedArgToPoly(arg: Tree, formal: Type): Tree = {
- val lenientPt = formal.subst(tparams, lenientTargs)
- val arg1 = typedArg(arg, lenientPt, POLYmode)
- val argtparams = context.undetparams
- context.undetparams = List()
- if (!argtparams.isEmpty) {
- val strictPt = formal.subst(tparams, strictTargs)
- inferArgumentInstance(arg1, argtparams, strictPt, lenientPt)
- }
- arg1
- }
- val args1 = List.map2(args, formals)(typedArgToPoly)
- if (args1 exists (.tpe.isError)) setError(tree)
- else {
- if (settings.debug.value) log("infer method inst "+fun+", tparams = "+tparams+", args = "+args1.map(.tpe)+", pt = "+pt+", lobounds = "+tparams.map(.tpe.bounds.lo));//debug
- val undetparams = inferMethodInstance(fun, tparams, args1, pt)
- val result = typedApply(fun, args1)
- context.undetparams = undetparams
- result
- }
- }
- }
- case ErrorType =>
- setError(tree)
- case _ =>
- errorTree(tree, ""+fun+" does not take parameters")
- }
- }
-
def tryTypedArgs(args: List[Tree]) = {
- val reportGeneralErrors = context.reportGeneralErrors
- val reportAmbiguousErrors = context.reportAmbiguousErrors
try {
- context.reportGeneralErrors = false
- context.reportAmbiguousErrors = false
- typedArgs(args)
+ val c = context.makeSilent(false)
+ c.retyping = true
+ newTyper(c).typedArgs(args, mode)
} catch {
case ex: TypeError =>
null
- } finally {
- context.reportGeneralErrors = reportGeneralErrors
- context.reportAmbiguousErrors = reportAmbiguousErrors
}
}
/** Try to apply function to arguments; if it does not work try to insert an implicit
* conversion
*/
+ def tryTypedApply(fun: Tree, args: List[Tree]): Tree = try {
+ if (context.reportGeneralErrors) {
+ val context1 = context.makeSilent(context.reportAmbiguousErrors)
+ context1.undetparams = context.undetparams
+ val typer1 = newTyper(context1)
+ val result = typer1.typedApply(tree, fun, args, mode, pt)
+ context.undetparams = context1.undetparams
+ result
+ } else {
+ typedApply(tree, fun, args, mode, pt)
+ }
+ } catch {
+ case ex: CyclicReference =>
+ throw ex
+ case ex: TypeError =>
+ val Select(qual, name) = fun
+ val args1 = tryTypedArgs(args)
+ val qual1 =
+ if (args1 != null && !pt.isError) {
+ def templateArgType(arg: Tree) =
+ new BoundedWildcardType(TypeBounds(arg.tpe, AnyClass.tpe))
+ adaptToMember(qual, name, MethodType(args1 map templateArgType, pt))
+ } else qual
+ if (qual1 ne qual) {
+ val tree1 = Apply(Select(qual1, name) setPos fun.pos, args1) setPos tree.pos
+ typed1(tree1, mode | SNDTRYmode, pt)
+ } else {
+ reportTypeError(tree.pos, ex)
+ setError(tree)
+ }
+ }
+/*
+ /** Try to apply function to arguments; if it does not work try to insert an implicit
+ * conversion
+ */
def tryTypedApply(fun: Tree, args: List[Tree]): Tree = {
val reportGeneralErrors = context.reportGeneralErrors
val undetparams = context.undetparams
try {
context.reportGeneralErrors = false
- typedApply(fun, args)
+ typedApply(tree, fun, args, mode, pt)
} catch {
case ex: CyclicReference =>
throw ex
@@ -1173,7 +1204,7 @@ trait Typers requires Analyzer {
context.reportGeneralErrors = reportGeneralErrors
}
}
-
+*/
/** Attribute a selection where `tree' is `qual.name'.
* `qual' is already attributed.
*/
@@ -1374,14 +1405,9 @@ trait Typers requires Analyzer {
null
}
typed(constr, mode | CONSTmode, AttributeClass.tpe) match {
- case t @ Apply(Select(New(tpt), nme.CONSTRUCTOR), args) =>
+ case Apply(Select(New(tpt), nme.CONSTRUCTOR), args) =>
val constrArgs = args map getConstant
- val attrScope = tpt.tpe.decls.filter(s => (s.isMethod && !s.isConstructor))
- val names = new collection.mutable.HashSet[Symbol]
- names ++= attrScope.elements
- if (args.length == 1) {
- names.filter(sym => sym.name != nme.value)
- }
+ val attrScope = tpt.tpe.decls;
val nvPairs = elements map {
case Assign(ntree @ Ident(name), rhs) => {
val sym = attrScope.lookup(name);
@@ -1389,23 +1415,12 @@ trait Typers requires Analyzer {
error(ntree.pos, "unknown attribute element name: " + name)
attrError = true;
null
- } else if (!names.contains(sym)) {
- error(ntree.pos, "duplicate value for element " + name)
- attrError = true;
- null
} else {
- names -= sym
Pair(sym, getConstant(typed(rhs, mode | CONSTmode,
sym.tpe.resultType)))
}
}
}
- for (val name <- names) {
- if (!name.attributes.contains(Triple(AnnotationDefaultAttr.tpe, List(), List()))) {
- error(t.pos, "attribute " + tpt.tpe.symbol.fullNameString + " is missing element " + name.name)
- attrError = true;
- }
- }
if (!attrError) {
val attrInfo = Triple(tpt.tpe, constrArgs, nvPairs)
val attributed =
@@ -1568,7 +1583,7 @@ trait Typers requires Analyzer {
case TypeApply(fun, args) =>
val args1 = List.mapConserve(args)(typedType)
// do args first in order to maintain conext.undetparams on the function side.
- typedTypeApply(typed(fun, funmode | TAPPmode, WildcardType), args1)
+ typedTypeApply(typed(fun, funMode(mode) | TAPPmode, WildcardType), args1)
case Apply(Block(stats, expr), args) =>
typed1(Block(stats, Apply(expr, args)), mode, pt)
@@ -1580,7 +1595,7 @@ trait Typers requires Analyzer {
typed1(tree, mode & ~PATTERNmode | EXPRmode, pt)
} else {
val funpt = if ((mode & PATTERNmode) != 0) pt else WildcardType
- var fun1 = typed(fun, funmode, funpt)
+ var fun1 = typed(fun, funMode(mode), funpt)
if (stableApplication) fun1 = stabilizeFun(fun1, mode, pt)
// if function is overloaded, filter all alternatives that match
// number of arguments and expected result type.
@@ -1591,7 +1606,7 @@ trait Typers requires Analyzer {
!fun1.tpe.isInstanceOf[ImplicitMethodType] &&
(mode & (EXPRmode | SNDTRYmode)) == EXPRmode) tryTypedApply(fun1, args)
else {
- typedApply(fun1, args)
+ typedApply(tree, fun1, args, mode, pt)
}
}
@@ -1707,6 +1722,11 @@ trait Typers requires Analyzer {
if (settings.debug.value) {
assert(pt != null, tree);//debug
}
+ if (context.retyping &&
+ tree.tpe != null && (tree.tpe.isErroneous || !(tree.tpe <:< pt))) {
+ tree.tpe = null
+ if (tree.hasSymbol) tree.symbol = NoSymbol
+ }
//System.out.println("typing "+tree+", "+context.undetparams);//DEBUG
val tree1 = if (tree.tpe != null) tree else typed1(tree, mode, pt)
//System.out.println("typed "+tree1+":"+tree1.tpe+", "+context.undetparams);//DEBUG
@@ -1716,14 +1736,14 @@ trait Typers requires Analyzer {
} catch {
case ex: TypeError =>
//System.out.println("caught "+ex+" in typed");//DEBUG
- reportTypeError(tree.pos, ex)
- setError(tree)
- case ex: Throwable =>
- if (settings.debug.value)
- System.out.println("exception when typing "+tree+", pt = "+pt)
- if (context != null && context.unit != null && context.unit.source != null && tree != null)
- logError("AT: " + context.unit.source.dbg(tree.pos), ex);
- throw(ex)
+ reportTypeError(tree.pos, ex)
+ setError(tree)
+ case ex: Throwable =>
+ if (settings.debug.value)
+ System.out.println("exception when typing "+tree+", pt = "+pt)
+ if (context != null && context.unit != null && context.unit.source != null && tree != null)
+ logError("AT: " + context.unit.source.dbg(tree.pos), ex);
+ throw(ex)
}
def atOwner(owner: Symbol): Typer =
diff --git a/test/files/neg/bug563.check b/test/files/neg/bug563.check
index 0f2eac240e..3c7423ea7d 100644
--- a/test/files/neg/bug563.check
+++ b/test/files/neg/bug563.check
@@ -1,9 +1,4 @@
bug563.scala:6 error: missing parameter type
map(n,ptr => new Cell(ptr.elem));
^
-bug563.scala:6 error: no type parameters for method map: (scala.List[A],(A) => R)scala.List[R] exist so that it can be applied to arguments (scala.List[scala.Cell[scala.Int]],(<error>) => <error>)
- --- because ---
-result type scala.List[R] is incompatible with expected type scala.Unit
- map(n,ptr => new Cell(ptr.elem));
- ^
-two errors found
+one error found
diff --git a/test/files/neg/bug633.check b/test/files/neg/bug633.check
new file mode 100644
index 0000000000..55f827ee69
--- /dev/null
+++ b/test/files/neg/bug633.check
@@ -0,0 +1,4 @@
+bug633.scala:3 error: not found: type ListBuffer
+ def t(a : ListBuffer[String]) = {
+ ^
+one error found
diff --git a/test/files/neg/bug633.scala b/test/files/neg/bug633.scala
new file mode 100644
index 0000000000..fd4e560720
--- /dev/null
+++ b/test/files/neg/bug633.scala
@@ -0,0 +1,8 @@
+object Test
+{
+ def t(a : ListBuffer[String]) = {
+ Console.println(a.length)
+ }
+
+ def main(argv : Array[String]) = t(null)
+}
diff --git a/test/files/neg/bug639.check b/test/files/neg/bug639.check
new file mode 100644
index 0000000000..7458952ce3
--- /dev/null
+++ b/test/files/neg/bug639.check
@@ -0,0 +1,9 @@
+/home/odersky/scala/test/files/pos/bug639.scala:1 error: not found: value a
+import a._
+ ^
+/home/odersky/scala/test/files/pos/bug639.scala:2 error: type mismatch;
+ found : B
+ required: scala.Attribute
+[B]
+ ^
+two errors found
diff --git a/test/files/neg/bug639.scala b/test/files/neg/bug639.scala
new file mode 100644
index 0000000000..7be0968069
--- /dev/null
+++ b/test/files/neg/bug639.scala
@@ -0,0 +1,3 @@
+import a._
+[B]
+class C
diff --git a/test/files/pos/bug640.scala b/test/files/pos/bug640.scala
new file mode 100644
index 0000000000..d46ecb7546
--- /dev/null
+++ b/test/files/pos/bug640.scala
@@ -0,0 +1,2 @@
+[serializable] class A
+[serializable] class B extends A
diff --git a/test/files/run/bigints.check b/test/files/run/bigints.check
new file mode 100644
index 0000000000..fb50db6447
--- /dev/null
+++ b/test/files/run/bigints.check
@@ -0,0 +1,5 @@
+3
+true
+false
+true
+true
diff --git a/test/files/run/bigints.scala b/test/files/run/bigints.scala
new file mode 100755
index 0000000000..f1328274c6
--- /dev/null
+++ b/test/files/run/bigints.scala
@@ -0,0 +1,14 @@
+object Test extends Application {
+ import BigInt._
+
+ val x: BigInt = 1
+ val y = x + 1
+ val z = 1 + y
+ System.out.println(z)
+ System.out.println(z <= 3)
+ System.out.println(3 < z)
+ System.out.println(z == 3)
+ System.out.println(3 == z)
+
+}
+
diff --git a/test/files/run/bug629.check b/test/files/run/bug629.check
new file mode 100644
index 0000000000..d86bac9de5
--- /dev/null
+++ b/test/files/run/bug629.check
@@ -0,0 +1 @@
+OK
diff --git a/test/files/run/bug629.scala b/test/files/run/bug629.scala
new file mode 100644
index 0000000000..67baead5f1
--- /dev/null
+++ b/test/files/run/bug629.scala
@@ -0,0 +1,13 @@
+object Test
+{
+ def main(args : Array[String]) : Unit = Console.println(new C(1))
+}
+
+abstract class A(val x : Int)
+
+class C(x : Int) extends A(x)
+{
+ override def toString() = "OK"
+ val v = new D
+ class D { def value = x }
+}