aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2013-08-22 14:24:49 +0200
committerMartin Odersky <odersky@gmail.com>2013-08-22 14:24:49 +0200
commit749934aeafecc65c865d92056467c08540add8cc (patch)
tree7b20ad103b0acb5b08f96c146a5a8c217a8e4b82 /src/dotty/tools
parentcbcdbd6fb8c0bf372a61b4ddd5b6ce181964776d (diff)
downloaddotty-749934aeafecc65c865d92056467c08540add8cc.tar.gz
dotty-749934aeafecc65c865d92056467c08540add8cc.tar.bz2
dotty-749934aeafecc65c865d92056467c08540add8cc.zip
More typer bug fixes and improvements in error messages
Diffstat (limited to 'src/dotty/tools')
-rw-r--r--src/dotty/tools/dotc/ast/Trees.scala13
-rw-r--r--src/dotty/tools/dotc/ast/TypedTrees.scala2
-rw-r--r--src/dotty/tools/dotc/ast/UntypedTrees.scala2
-rw-r--r--src/dotty/tools/dotc/core/Symbols.scala3
-rw-r--r--src/dotty/tools/dotc/core/Types.scala2
-rw-r--r--src/dotty/tools/dotc/parsing/Parsers.scala2
-rw-r--r--src/dotty/tools/dotc/typer/Applications.scala6
-rw-r--r--src/dotty/tools/dotc/typer/ErrorReporting.scala16
-rw-r--r--src/dotty/tools/dotc/typer/Implicits.scala3
-rw-r--r--src/dotty/tools/dotc/typer/Namer.scala3
-rw-r--r--src/dotty/tools/dotc/typer/Typer.scala14
11 files changed, 37 insertions, 29 deletions
diff --git a/src/dotty/tools/dotc/ast/Trees.scala b/src/dotty/tools/dotc/ast/Trees.scala
index 8157c287d..254818b27 100644
--- a/src/dotty/tools/dotc/ast/Trees.scala
+++ b/src/dotty/tools/dotc/ast/Trees.scala
@@ -180,7 +180,13 @@ object Trees {
/** Return a typed tree that's isomorphic to this tree, but has given
* type. (Overridden by empty trees)
*/
- def withType(tpe: Type): ThisTree[Type] = {
+ def withType(tpe: Type)(implicit ctx: Context): ThisTree[Type] = {
+ // temporary solution to catch unreported errors early
+ if (tpe == ErrorType) assert(ctx.reporter.hasErrors)
+ withTypeUnchecked(tpe)
+ }
+
+ def withTypeUnchecked(tpe: Type): ThisTree[Type] = {
val tree =
(if (myTpe == null ||
(myTpe.asInstanceOf[AnyRef] eq tpe.asInstanceOf[AnyRef])) this
@@ -650,7 +656,7 @@ object Trees {
trait WithoutType[-T >: Untyped] extends Tree[T] {
override def tpe: T @uncheckedVariance = NoType.asInstanceOf[T]
- override def withType(tpe: Type) = this.asInstanceOf[ThisTree[Type]]
+ override def withTypeUnchecked(tpe: Type) = this.asInstanceOf[ThisTree[Type]]
}
/** Temporary class that results from translation of ModuleDefs
@@ -816,9 +822,6 @@ object Trees {
def finalize(tree: Tree, copied: untpd.Tree): copied.ThisTree[T] =
postProcess(tree, copied withPos tree.pos)
- private def copyAttrs(t: untpd.Tree, tree: Tree): t.ThisTree[T] =
- t.withType(tree.typeOpt).withPos(tree.pos).asInstanceOf[t.ThisTree[T]]
-
def Ident(tree: Tree, name: Name): Ident = tree match {
case tree: BackquotedIdent =>
if (name == tree.name) tree
diff --git a/src/dotty/tools/dotc/ast/TypedTrees.scala b/src/dotty/tools/dotc/ast/TypedTrees.scala
index 2200e7fe5..a34e015b8 100644
--- a/src/dotty/tools/dotc/ast/TypedTrees.scala
+++ b/src/dotty/tools/dotc/ast/TypedTrees.scala
@@ -356,7 +356,7 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
class TypedTreeCopier extends TreeCopier {
def postProcess(tree: Tree, copied: untpd.Tree): copied.ThisTree[Type] =
- copied.withType(tree.tpe)
+ copied.withTypeUnchecked(tree.tpe)
}
implicit class TreeOps[ThisTree <: tpd.Tree](val tree: ThisTree) extends AnyVal {
diff --git a/src/dotty/tools/dotc/ast/UntypedTrees.scala b/src/dotty/tools/dotc/ast/UntypedTrees.scala
index b3b05dc8b..d7e0a7b3d 100644
--- a/src/dotty/tools/dotc/ast/UntypedTrees.scala
+++ b/src/dotty/tools/dotc/ast/UntypedTrees.scala
@@ -110,7 +110,7 @@ object untpd extends Trees.Instance[Untyped] with TreeInfo[Untyped] {
def AppliedTypeTree(tpt: Tree, arg: Tree): AppliedTypeTree =
AppliedTypeTree(tpt, arg :: Nil)
- def TypeTree(tpe: Type): TypedSplice = TypedSplice(TypeTree().withType(tpe))
+ def TypeTree(tpe: Type): TypedSplice = TypedSplice(TypeTree().withTypeUnchecked(tpe))
def TypeDef(mods: Modifiers, name: TypeName, tparams: List[TypeDef], rhs: Tree): TypeDef =
if (tparams.isEmpty) TypeDef(mods, name, rhs) else new PolyTypeDef(mods, name, tparams, rhs)
diff --git a/src/dotty/tools/dotc/core/Symbols.scala b/src/dotty/tools/dotc/core/Symbols.scala
index 72dcef082..fe39135d9 100644
--- a/src/dotty/tools/dotc/core/Symbols.scala
+++ b/src/dotty/tools/dotc/core/Symbols.scala
@@ -368,9 +368,8 @@ object Symbols {
* the class containing this symbol was generated, null if not applicable.
* Overridden in ClassSymbol
*/
- def associatedFile(implicit ctx: Context): AbstractFile = ctx.traceIndented(s"assocFile($this)") {
+ def associatedFile(implicit ctx: Context): AbstractFile =
denot.topLevelClass.symbol.associatedFile
- }
/** The class file from which this class was generated, null if not applicable. */
final def binaryFile(implicit ctx: Context): AbstractFile =
diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala
index 63ce59995..b9d079a20 100644
--- a/src/dotty/tools/dotc/core/Types.scala
+++ b/src/dotty/tools/dotc/core/Types.scala
@@ -493,7 +493,7 @@ object Types {
}
/** The basetype of this type with given class symbol */
- final def baseType(base: Symbol)(implicit ctx: Context): Type = ctx.traceIndented(s"$this baseType $base") { base.denot match {
+ final def baseType(base: Symbol)(implicit ctx: Context): Type = /*ctx.traceIndented(s"$this baseType $base")*/ { base.denot match {
case classd: ClassDenotation => classd.baseTypeOf(this)
case _ => NoType
}}
diff --git a/src/dotty/tools/dotc/parsing/Parsers.scala b/src/dotty/tools/dotc/parsing/Parsers.scala
index abba1be37..8f8928f58 100644
--- a/src/dotty/tools/dotc/parsing/Parsers.scala
+++ b/src/dotty/tools/dotc/parsing/Parsers.scala
@@ -1666,7 +1666,7 @@ object Parsers {
} else {
equalsExpr()
}
- DefDef(mods, name, tparams, vparamss, restype, rhs)
+ DefDef(mods | Method, name, tparams, vparamss, restype, rhs)
}
}
diff --git a/src/dotty/tools/dotc/typer/Applications.scala b/src/dotty/tools/dotc/typer/Applications.scala
index 05b0c50ce..8af9e0b57 100644
--- a/src/dotty/tools/dotc/typer/Applications.scala
+++ b/src/dotty/tools/dotc/typer/Applications.scala
@@ -118,7 +118,8 @@ trait Applications extends Compatibility { self: Typer =>
case methType: MethodType =>
// apply the result type constraint, unless method type is dependent
if (!methType.isDependent)
- ok = ok && constrainResult(methType.resultType, resultType)
+ if (!constrainResult(methType.resultType, resultType))
+ fail(err.typeMismatchStr(methType.resultType, resultType))
// match all arguments with corresponding formal parameters
matchArgs(orderedArgs, methType.paramTypes, 0)
case _ =>
@@ -484,7 +485,6 @@ trait Applications extends Compatibility { self: Typer =>
typed(assign)
}
- realApply
if (untpd.isOpAssign(tree))
tryEither {
implicit ctx => realApply
@@ -706,7 +706,7 @@ trait Applications extends Compatibility { self: Typer =>
}
private val dummyTree = untpd.Literal(Constant(null))
- def dummyTreeOfType(tp: Type): Tree = dummyTree withType tp
+ def dummyTreeOfType(tp: Type): Tree = dummyTree withTypeUnchecked tp
/** Resolve overloaded alternative `alts`, given expected type `pt`. */
def resolveOverloaded(alts: List[TermRef], pt: Type)(implicit ctx: Context): List[TermRef] = {
diff --git a/src/dotty/tools/dotc/typer/ErrorReporting.scala b/src/dotty/tools/dotc/typer/ErrorReporting.scala
index d95807e3c..177882688 100644
--- a/src/dotty/tools/dotc/typer/ErrorReporting.scala
+++ b/src/dotty/tools/dotc/typer/ErrorReporting.scala
@@ -63,16 +63,16 @@ object ErrorReporting {
def patternConstrStr(tree: Tree): String = ???
- def typeMismatch(tree: Tree, pt: Type): Tree = {
- val result = errorTree(tree,
- i"""type mismatch:
- | found : ${tree.tpe}
- | required: $pt""".stripMargin)
+ def typeMismatch(tree: Tree, pt: Type): Tree =
+ errorTree(tree, typeMismatchStr(tree.tpe, pt))
+
+ def typeMismatchStr(found: Type, expected: Type) = {
if (ctx.settings.explaintypes.value)
- new ExplainingTypeComparer().isSubType(tree.tpe, pt)
- result
+ new ExplainingTypeComparer().isSubType(found, expected)
+ i"""type mismatch:
+ | found : $found
+ | required: $expected""".stripMargin
}
-
}
def err(implicit ctx: Context): Errors = new Errors
diff --git a/src/dotty/tools/dotc/typer/Implicits.scala b/src/dotty/tools/dotc/typer/Implicits.scala
index b98ea5dc9..74a144996 100644
--- a/src/dotty/tools/dotc/typer/Implicits.scala
+++ b/src/dotty/tools/dotc/typer/Implicits.scala
@@ -183,7 +183,8 @@ trait Implicits { self: Typer =>
* @param pos The position where errors should be reported.
* @param reportAmbiguous Should ambiguity errors be reported? False when called from `viewExists`.
*/
- def inferImplicit(pt: Type, argument: Tree, pos: Position, reportAmbiguous: Boolean = true)(implicit ctx: Context): Tree = {
+ def inferImplicit(pt: Type, argument: Tree, pos: Position, reportAmbiguous: Boolean = true)(implicit ctx: Context): Tree =
+ ctx.traceIndented(s"search implicit $pt, arg = ${argument.show}, reportAmbiguous = $reportAmbiguous", show = true) {
new ImplicitSearch(pt, argument, pos).bestImplicit match {
case SearchSuccess(_, tree, tstate) =>
tstate.commit()
diff --git a/src/dotty/tools/dotc/typer/Namer.scala b/src/dotty/tools/dotc/typer/Namer.scala
index bedaf55c3..426213147 100644
--- a/src/dotty/tools/dotc/typer/Namer.scala
+++ b/src/dotty/tools/dotc/typer/Namer.scala
@@ -147,7 +147,6 @@ class Namer { typer: Typer =>
adjustIfModule(new Completer(tree), tree),
privateWithinClass(tree.mods), tree.pos, ctx.source.file))
case tree: MemberDef =>
- var completer = new Completer(tree)
record(tree, ctx.newSymbol(
ctx.owner, tree.name, tree.mods.flags,
adjustIfModule(new Completer(tree), tree),
@@ -385,7 +384,7 @@ class Namer { typer: Typer =>
else tparams map symbolOfTree
def wrapMethType(restpe: Type): Type = {
val monotpe =
- (restpe /: vparamss) { (restpe, params) =>
+ (vparamss :\ restpe) { (params, restpe) =>
val make =
if (params.nonEmpty && (params.head.mods is Implicit)) ImplicitMethodType
else MethodType
diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala
index 82b2e25b6..c693209f4 100644
--- a/src/dotty/tools/dotc/typer/Typer.scala
+++ b/src/dotty/tools/dotc/typer/Typer.scala
@@ -930,6 +930,8 @@ class Typer extends Namer with Applications with Implicits {
*/
def adapt(tree: Tree, pt: Type)(implicit ctx: Context): Tree = ctx.traceIndented(i"adapting $tree of type ${tree.tpe} to $pt", show = false) {
+ def methodStr = err.refStr(methPart(tree).tpe)
+
def adaptOverloaded(ref: TermRef) = {
val altDenots = ref.denot.alternatives
val alts = altDenots map (alt =>
@@ -957,12 +959,11 @@ class Typer extends Namer with Applications with Implicits {
def adaptToArgs(tp: Type, pt: FunProto) = tp match {
case _: MethodType => tree
case _ => tryInsertApply(tree, pt) {
- def fn = err.refStr(methPart(tree).tpe)
val more = tree match {
case Apply(_, _) => " more"
case _ => ""
}
- _ => errorTree(tree, i"$fn does not take$more parameters")
+ _ => errorTree(tree, i"$methodStr does not take$more parameters")
}
}
@@ -970,7 +971,12 @@ class Typer extends Namer with Applications with Implicits {
case tp: ExprType =>
adapt(tree.withType(tp.resultType), pt)
case tp: ImplicitMethodType =>
- val args = tp.paramTypes map (inferImplicit(_, EmptyTree, tree.pos))
+ val args = (tp.paramNames, tp.paramTypes).zipped map { (pname, formal) =>
+ val arg = inferImplicit(formal, EmptyTree, tree.pos.endPos)
+ if (arg.isEmpty)
+ ctx.error(i"no implicit argument of type $formal found for parameter $pname of $methodStr", tree.pos.endPos)
+ arg
+ }
adapt(tpd.Apply(tree, args), pt)
case tp: MethodType =>
if (defn.isFunctionType(pt) && !tree.symbol.isConstructor)
@@ -979,7 +985,7 @@ class Typer extends Namer with Applications with Implicits {
adapt(tpd.Apply(tree, Nil), pt)
else
errorTree(tree,
- i"""missing arguments for ${tree.symbol}
+ i"""missing arguments for $methodStr
|follow this method with `_' if you want to treat it as a partially applied function""".stripMargin)
case _ =>
if (tp <:< pt) tree