summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2007-01-25 13:51:15 +0000
committerMartin Odersky <odersky@gmail.com>2007-01-25 13:51:15 +0000
commit11bcf8ef29e894298b16d89fb58c73adc87188cf (patch)
treefde11a53bba46f50e40cb65959a7aa3f79eadbd5 /src
parentd169735abb70d59995e3e8783cea62f876654ad4 (diff)
downloadscala-11bcf8ef29e894298b16d89fb58c73adc87188cf.tar.gz
scala-11bcf8ef29e894298b16d89fb58c73adc87188cf.tar.bz2
scala-11bcf8ef29e894298b16d89fb58c73adc87188cf.zip
fsee message for 9732
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Infer.scala28
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/RefChecks.scala46
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala41
-rw-r--r--src/library/scala/util/parsing/Parsers.scala4
4 files changed, 69 insertions, 50 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
index 63b59f01cb..983e72c75f 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
@@ -243,6 +243,12 @@ trait Infer requires Analyzer {
";\n found : " + found.toLongString + "\n required: " + req
}
+ def typeErrorMsg(found: Type, req: Type) =
+ "type mismatch" + foundReqMsg(found, req) +
+ (if (!(found.resultType eq found) && isWeaklyCompatible(found.resultType, req))
+ "\n possible cause: missing arguments for method or constructor"
+ else "")
+
def error(pos: PositionType, msg: String): unit =
context.error(pos, msg)
@@ -251,15 +257,12 @@ trait Infer requires Analyzer {
setError(tree)
}
- def typeError(pos: PositionType, found: Type, req: Type): unit =
+ def typeError(pos: PositionType, found: Type, req: Type) {
if (!found.isErroneous && !req.isErroneous) {
- error(pos,
- "type mismatch" + foundReqMsg(found, req) +
- (if (!(found.resultType eq found) && isWeaklyCompatible(found.resultType, req))
- "\n possible cause: missing arguments for method or constructor"
- else ""))
+ error(pos, typeErrorMsg(found, req))
if (settings.explaintypes.value) explainTypes(found, req)
}
+ }
def typeErrorTree(tree: Tree, found: Type, req: Type): Tree = {
typeError(tree.pos, found, req)
@@ -574,12 +577,10 @@ trait Infer requires Analyzer {
}
/** error if arguments not within bounds. */
- def checkBounds(pos: PositionType, tparams: List[Symbol],
- targs: List[Type], prefix: String): unit =
- if (!isWithinBounds(NoPrefix, NoSymbol, tparams, targs)) {
+ def checkBounds(pos: PositionType, pre: Type, owner: Symbol,
+ tparams: List[Symbol], targs: List[Type], prefix: String) {
+ if (!isWithinBounds(pre, owner, tparams, targs)) {
if (!(targs exists (.isErroneous)) && !(tparams exists (.isErroneous))) {
- //Console.println("tparams = "+tparams+", bounds = "+tparams.map(.info)+", targs="+targs)//DEBUG
- //withTypesExplained(isWithinBounds(NoPrefix, tparams, targs))//DEBUG
error(pos,
prefix + "type arguments " + targs.mkString("[", ",", "]") +
" do not conform to " + tparams.head.owner + "'s type parameter bounds " +
@@ -592,6 +593,7 @@ trait Infer requires Analyzer {
()
}
}
+ }
/** Substitite free type variables `undetparams' of polymorphic argument
* expression `tree', given two prototypes `strictPt', and `lenientPt'.
@@ -655,7 +657,7 @@ trait Infer requires Analyzer {
val targs = methTypeArgs(
undetparams, formalTypes(formals, argtpes.length),
restpe, argtpes, pt, uninstantiated)
- checkBounds(fn.pos, undetparams, targs, "inferred ")
+ checkBounds(fn.pos, NoPrefix, NoSymbol, undetparams, targs, "inferred ")
//Console.println("UNAPPLY subst type "+undetparams+" to "+targs+" in "+fn+" ( "+args+ ")")
val treeSubst = new TreeTypeSubstituter(undetparams, targs)
treeSubst.traverse(fn)
@@ -724,7 +726,7 @@ trait Infer requires Analyzer {
def computeArgs =
try {
val targs = solve(tvars, undetparams, undetparams map varianceInType(restpe), true)
- checkBounds(tree.pos, undetparams, targs, "inferred ")
+ checkBounds(tree.pos, NoPrefix, NoSymbol, undetparams, targs, "inferred ")
new TreeTypeSubstituter(undetparams, targs).traverse(tree)
} catch {
case ex: NoInstance =>
diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
index 407068299b..8209665c15 100644
--- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
@@ -486,24 +486,28 @@ abstract class RefChecks extends InfoTransform {
case ClassDef(_, _, _, _, _) if isConcreteLocalCaseFactory(tree.symbol) =>
val clazz = tree.symbol
val factory = clazz.caseFactory
- assert(factory != NoSymbol, clazz)
- def mkArgument(vparam: Symbol) = {
- val id = Ident(vparam)
- if (vparam.tpe.symbol == RepeatedParamClass) Typed(id, Ident(nme.WILDCARD_STAR.toTypeName))
- else id
- }
- val caseFactoryDef =
- localTyper.typed {
- atPos(tree.pos) {
- DefDef(
- factory,
- vparamss =>
- (toConstructor(tree.pos, factory.tpe) /: vparamss) {
- (fn, vparams) => Apply(fn, vparams map mkArgument)
- })
- }
+ if (factory == NoSymbol) {
+ assert(clazz.owner.isTerm, clazz)
+ List(transform(tree))
+ } else {
+ def mkArgument(vparam: Symbol) = {
+ val id = Ident(vparam)
+ if (vparam.tpe.symbol == RepeatedParamClass) Typed(id, Ident(nme.WILDCARD_STAR.toTypeName))
+ else id
}
- List(transform(tree), caseFactoryDef)
+ val caseFactoryDef =
+ localTyper.typed {
+ atPos(tree.pos) {
+ DefDef(
+ factory,
+ vparamss =>
+ (toConstructor(tree.pos, factory.tpe) /: vparamss) {
+ (fn, vparams) => Apply(fn, vparams map mkArgument)
+ })
+ }
+ }
+ List(transform(tree), caseFactoryDef)
+ }
case ValDef(_, _, _, _) =>
val tree1 = transform(tree); // important to do before forward reference check
@@ -523,8 +527,8 @@ abstract class RefChecks extends InfoTransform {
override def transform(tree: Tree): Tree = try {
/* Check whether argument types conform to bounds of type parameters */
- def checkBounds(tparams: List[Symbol], argtps: List[Type]): unit = try {
- typer.infer.checkBounds(tree.pos, tparams, argtps, "");
+ def checkBounds(pre: Type, owner: Symbol, tparams: List[Symbol], argtps: List[Type]): unit = try {
+ typer.infer.checkBounds(tree.pos, pre, owner, tparams, argtps, "");
} catch {
case ex: TypeError => unit.error(tree.pos, ex.getMessage());
}
@@ -579,13 +583,13 @@ abstract class RefChecks extends InfoTransform {
case TypeTree() =>
new TypeTraverser {
def traverse(tp: Type): TypeTraverser = tp match {
- case TypeRef(pre, sym, args) => checkBounds(sym.typeParams, args); this
+ case TypeRef(pre, sym, args) => checkBounds(pre, sym.owner, sym.typeParams, args); this
case _ => this
}
} traverse tree.tpe
case TypeApply(fn, args) =>
- checkBounds(fn.tpe.typeParams, args map (.tpe))
+ checkBounds(NoPrefix, NoSymbol, fn.tpe.typeParams, args map (.tpe))
if (sym.isSourceMethod && sym.hasFlag(CASE)) result = toConstructor(tree.pos, tree.tpe)
case Apply(
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index aa81ba6de3..6c5462196a 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -1525,7 +1525,7 @@ trait Typers requires Analyzer {
case PolyType(tparams, restpe) if (tparams.length != 0) =>
if (tparams.length == args.length) {
val targs = args map (.tpe)
- checkBounds(tree.pos, tparams, targs, "")
+ checkBounds(tree.pos, NoPrefix, NoSymbol, tparams, targs, "")
if (fun.symbol == Predef_classOf) {
if (!targs.head.symbol.isClass || targs.head.symbol.isRefinementClass)
error(args.head.pos, "class type required");
@@ -1939,15 +1939,19 @@ trait Typers requires Analyzer {
}
val lhs1 = typed(lhs, EXPRmode | LHSmode, WildcardType)
val varsym = lhs1.symbol
- if ((varsym ne null) && mayBeVarGetter(varsym)) {
+ if ((varsym ne null) && mayBeVarGetter(varsym))
lhs1 match {
case Select(qual, name) =>
- typed(
+ return typed(
Apply(
Select(qual, nme.getterToSetter(name)) setPos lhs.pos,
- List(rhs)) setPos tree.pos, mode, pt)
+ List(rhs)) setPos tree.pos,
+ mode, pt)
+
+ case _ =>
+
}
- } else if ((varsym ne null) && (varsym.isVariable || varsym.isValue && phase.erasedTypes)) {
+ if ((varsym ne null) && (varsym.isVariable || varsym.isValue && phase.erasedTypes)) {
val rhs1 = typed(rhs, lhs1.tpe)
copy.Assign(tree, lhs1, rhs1) setType UnitClass.tpe
} else {
@@ -2391,16 +2395,23 @@ trait Typers requires Analyzer {
val tc = newTyper(context.makeImplicit(reportAmbiguous))
- def ambiguousError(info1: ImplicitInfo, info2: ImplicitInfo,
- pre1: String, pre2: String, trailer: String) =
- error(
- pos,
- "ambiguous implicit value:\n "+
+ def ambiguousImplicitError(info1: ImplicitInfo, info2: ImplicitInfo,
+ pre1: String, pre2: String, trailer: String) = {
+ val coreMsg =
pre1+" "+info1.sym+info1.sym.locationString+" of type "+info1.tpe+"\n "+
pre2+" "+info2.sym+info2.sym.locationString+" of type "+info2.tpe+"\n "+
- trailer+
- (if (isView) "are possible conversion functions from "+ pt.typeArgs(0)+" to "+pt.typeArgs(1)
- else "match expected type "+pt))
+ trailer
+ error(pos,
+ if (isView) {
+ val found = pt.typeArgs(0)
+ val req = pt.typeArgs(1)
+ typeErrorMsg(found, req)+
+ "\nNote that implicit conversions are not applicable because they are ambiguous:\n "+
+ coreMsg+"are possible conversion functions from "+ found+" to "+req
+ } else {
+ "ambiguous implicit values:\n "+coreMsg + "match expected type "+pt
+ })
+ }
/** Search list of implicit info lists for one matching prototype
* <code>pt</code>. If found return a tree from found implicit info
@@ -2439,10 +2450,10 @@ trait Typers requires Analyzer {
if (best == NoImplicitInfo) EmptyTree
else {
val competing = applicable dropWhile (alt => best == alt || improves(best, alt))
- if (!competing.isEmpty) ambiguousError(best, competing.head, "both", "and", "")
+ if (!competing.isEmpty) ambiguousImplicitError(best, competing.head, "both", "and", "")
for (val alt <- applicable)
if (alt.sym.owner != best.sym.owner && isSubClassOrObject(alt.sym.owner, best.sym.owner)) {
- ambiguousError(best, alt,
+ ambiguousImplicitError(best, alt,
"most specific definition is:",
"yet alternative definition ",
"is defined in a subclass.\n Both definitions ")
diff --git a/src/library/scala/util/parsing/Parsers.scala b/src/library/scala/util/parsing/Parsers.scala
index b016d0b6d1..6bc3f4a3ba 100644
--- a/src/library/scala/util/parsing/Parsers.scala
+++ b/src/library/scala/util/parsing/Parsers.scala
@@ -11,7 +11,9 @@
package scala.util.parsing
-/** This class ...
+/** Documentation for this class is currently missing.
+ * However, the Scala By Examples document contains a
+ * chapter on combinator parsing that comes close.
*
* @author Burak Emir
* @version 1.0