From cbcdbd6fb8c0bf372a61b4ddd5b6ce181964776d Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Thu, 22 Aug 2013 09:27:34 +0200 Subject: Various bug fixes for typer. --- src/dotty/tools/dotc/ast/TypedTrees.scala | 2 +- src/dotty/tools/dotc/core/Names.scala | 9 ++++++--- src/dotty/tools/dotc/core/StdNames.scala | 6 ++---- src/dotty/tools/dotc/core/Symbols.scala | 8 ++++++-- src/dotty/tools/dotc/core/Types.scala | 5 +++-- src/dotty/tools/dotc/printing/RefinedPrinter.scala | 4 ++-- src/dotty/tools/dotc/reporting/Reporter.scala | 10 +++++++--- src/dotty/tools/dotc/typer/Applications.scala | 11 ++++++++++- src/dotty/tools/dotc/typer/Namer.scala | 2 +- src/dotty/tools/dotc/typer/Typer.scala | 6 +++--- 10 files changed, 41 insertions(+), 22 deletions(-) diff --git a/src/dotty/tools/dotc/ast/TypedTrees.scala b/src/dotty/tools/dotc/ast/TypedTrees.scala index 8ac37a104..2200e7fe5 100644 --- a/src/dotty/tools/dotc/ast/TypedTrees.scala +++ b/src/dotty/tools/dotc/ast/TypedTrees.scala @@ -437,6 +437,6 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo { // ensure that normal methods are fully applied? def localSyms(stats: List[tpd.Tree])(implicit ctx: Context): List[Symbol] = - for (stat <- stats if (stat.isDef)) yield stat.symbol + for (stat <- stats if stat.isDef) yield stat.symbol } diff --git a/src/dotty/tools/dotc/core/Names.scala b/src/dotty/tools/dotc/core/Names.scala index 77be4843c..5439d2d17 100644 --- a/src/dotty/tools/dotc/core/Names.scala +++ b/src/dotty/tools/dotc/core/Names.scala @@ -106,7 +106,7 @@ object Names { /** Replace operator symbols by corresponding \$op_name's. */ def encode: Name = - if (this eq CONSTRUCTOR) this else NameTransformer.encode(this) + if (dontEncode(toTermName)) this else NameTransformer.encode(this) /** A more efficient version of concatenation */ def ++ (other: Name): ThisName = ++ (other.toString) @@ -320,8 +320,11 @@ object Names { /** The type name represented by the empoty string */ val EmptyTypeName = EmptyTermName.toTypeName - // can't use nme.CONSTRUCTOR in encode because of bootstrap failures. - private val CONSTRUCTOR = termName("") + // can't move CONSTRUCTOR/EMPTY_PACKAGE to `nme` because of bootstrap failures in `encode`. + val CONSTRUCTOR = termName("") + val EMPTY_PACKAGE = termName("") + + val dontEncode = Set(CONSTRUCTOR, EMPTY_PACKAGE) def termNameBuilder: Builder[Char, TermName] = StringBuilder.newBuilder.mapResult(termName) diff --git a/src/dotty/tools/dotc/core/StdNames.scala b/src/dotty/tools/dotc/core/StdNames.scala index 9ae4729f4..e9fea8148 100644 --- a/src/dotty/tools/dotc/core/StdNames.scala +++ b/src/dotty/tools/dotc/core/StdNames.scala @@ -94,7 +94,7 @@ object StdNames { val DEFAULT_GETTER_INIT: N = encode("") val DO_WHILE_PREFIX: N = "doWhile$" val EMPTY: N = "" - val EMPTY_PACKAGE: N = "" + val EMPTY_PACKAGE: N = Names.EMPTY_PACKAGE.toString val EVIDENCE_PARAM_PREFIX: N = "evidence$" val EXCEPTION_RESULT_PREFIX: N = "exceptionResult" val EXPAND_SEPARATOR: N = "$$" @@ -212,7 +212,7 @@ object StdNames { // Compiler-internal val ANYname: N = "" - val CONSTRUCTOR: N = "" + val CONSTRUCTOR: N = Names.CONSTRUCTOR.toString val DEFAULT_CASE: N = "defaultCase$" val EQEQ_LOCAL_VAR: N = "eqEqTemp$" val FAKE_LOCAL_THIS: N = "this$" @@ -276,8 +276,6 @@ object StdNames { val ArrayAnnotArg: N = "ArrayAnnotArg" val Constant: N = "Constant" val ConstantType: N = "ConstantType" - val EmptyPackage: N = "EmptyPackage" - val EmptyPackageClass: N = "EmptyPackageClass" val ExistentialTypeTree: N = "ExistentialTypeTree" val Flag : N = "Flag" val HigherKinded: N = "HigherKinded" diff --git a/src/dotty/tools/dotc/core/Symbols.scala b/src/dotty/tools/dotc/core/Symbols.scala index ac13381e6..72dcef082 100644 --- a/src/dotty/tools/dotc/core/Symbols.scala +++ b/src/dotty/tools/dotc/core/Symbols.scala @@ -318,10 +318,14 @@ object Symbols { denot } - /** The run-id when this symbol was last defined */ - final def defRunId: RunId = + private def defRunId: RunId = if (lastDenot == null) NoRunId else lastDenot.validFor.runId + /** Does this symbol come from a currently compiled source file? */ + final def isDefinedInCurrentRun(implicit ctx: Context): Boolean = { + pos.exists && defRunId == ctx.runId + } + /** Subclass tests and casts */ final def isTerm(implicit ctx: Context): Boolean = denot.isTerm final def isType(implicit ctx: Context): Boolean = denot.isType diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala index 94810a2a2..63ce59995 100644 --- a/src/dotty/tools/dotc/core/Types.scala +++ b/src/dotty/tools/dotc/core/Types.scala @@ -193,6 +193,7 @@ object Types { /** The type symbol associated with the type */ final def typeSymbol(implicit ctx: Context): Symbol = this match { case tp: TypeRef => tp.symbol + case tp: TermRef => NoSymbol case tp: ClassInfo => tp.cls case ThisType(cls) => cls case tp: TypeProxy => tp.underlying.typeSymbol @@ -492,10 +493,10 @@ object Types { } /** The basetype of this type with given class symbol */ - final def baseType(base: Symbol)(implicit ctx: Context): Type = 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 - } + }} def & (that: Type)(implicit ctx: Context): Type = ctx.glb(this, that) diff --git a/src/dotty/tools/dotc/printing/RefinedPrinter.scala b/src/dotty/tools/dotc/printing/RefinedPrinter.scala index fe6711e7f..79641d932 100644 --- a/src/dotty/tools/dotc/printing/RefinedPrinter.scala +++ b/src/dotty/tools/dotc/printing/RefinedPrinter.scala @@ -158,8 +158,8 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) { "new " ~ toTextLocal(tpt) case Pair(l, r) => "(" ~ toTextGlobal(l) ~ ", " ~ toTextGlobal(r) ~ ")" - case Typed(l, tpt) => - changePrec(InfixPrec) { toText(l) ~ ": " ~ toText(tpt) } + case Typed(expr, tpt) => + changePrec(InfixPrec) { toText(expr) ~ ": " ~ toText(tpt) } case NamedArg(name, arg) => toText(name) ~ " = " ~ toText(arg) case Assign(lhs, rhs) => diff --git a/src/dotty/tools/dotc/reporting/Reporter.scala b/src/dotty/tools/dotc/reporting/Reporter.scala index ba463ebce..03249a082 100644 --- a/src/dotty/tools/dotc/reporting/Reporter.scala +++ b/src/dotty/tools/dotc/reporting/Reporter.scala @@ -130,9 +130,13 @@ trait Reporting { this: Context => if (this.settings.debugTrace.value) traceIndented(question)(op) else op - def traceIndented[T](question: => String)(op: => T): T = - traceIndented[T](s"==> $question?", (res: Any) => s"<== $question = $res")(op) - + def traceIndented[T](question: => String, show: Boolean = false)(op: => T): T = { + def resStr(res: Any): String = res match { + case res: printing.Showable if show => res.show + case _ => String.valueOf(res) + } + traceIndented[T](s"==> $question?", (res: Any) => s"<== $question = ${resStr(res)}")(op) + } def traceIndented[T](leading: => String, trailing: Any => String)(op: => T): T = { var finalized = false def finalize(result: Any, note: String) = diff --git a/src/dotty/tools/dotc/typer/Applications.scala b/src/dotty/tools/dotc/typer/Applications.scala index 66fb4c3e1..05b0c50ce 100644 --- a/src/dotty/tools/dotc/typer/Applications.scala +++ b/src/dotty/tools/dotc/typer/Applications.scala @@ -410,6 +410,7 @@ trait Applications extends Compatibility { self: Typer => val result = { var typedArgs = typedArgBuf.toList + println(s"typed args of $methRef = $typedArgs") val ownType = if (!success) ErrorType else { @@ -611,9 +612,17 @@ trait Applications extends Compatibility { self: Typer => /** Is given method reference applicable to argument types `args`? * @param resultType The expected result type of the application */ - def isApplicableToTrees(methRef: TermRef, args: List[Tree], resultType: Type)(implicit ctx: Context) = + def isApplicableToTrees(methRef: TermRef, args: List[Tree], resultType: Type)(implicit ctx: Context): Boolean = new ApplicableToTrees(methRef, args, resultType)(ctx.fresh.withNewTyperState).success + def isApplicableToTrees(tp: Type, args: List[Tree], resultType: Type)(implicit ctx: Context): Boolean = tp match { + case methRef: TermRef => isApplicableToTrees(methRef, args, resultType) + case _ => + val app = tp.member(nme.apply) + app.exists && app.hasAltWith(d => + isApplicableToTrees(TermRef(tp, nme.apply).withDenot(d), args, resultType)) + } + /** Is given method reference applicable to arguments `args`? * @param resultType The expected result type of the application */ diff --git a/src/dotty/tools/dotc/typer/Namer.scala b/src/dotty/tools/dotc/typer/Namer.scala index cc5d041b9..bedaf55c3 100644 --- a/src/dotty/tools/dotc/typer/Namer.scala +++ b/src/dotty/tools/dotc/typer/Namer.scala @@ -168,7 +168,7 @@ class Namer { typer: Typer => println(s"entered: $sym in ${ctx.owner} and ${ctx.effectiveScope}") if (sym.owner is PackageClass) { val preExisting = sym.owner.decls.lookup(sym.name) - if (preExisting.defRunId == ctx.runId) + if (preExisting.isDefinedInCurrentRun) ctx.error(s"${sym.showLocated} is compiled twice", sym.pos) } ctx.enter(sym) diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala index 7702b1750..82b2e25b6 100644 --- a/src/dotty/tools/dotc/typer/Typer.scala +++ b/src/dotty/tools/dotc/typer/Typer.scala @@ -394,7 +394,7 @@ class Typer extends Namer with Applications with Implicits { case _ => val tpt1 = typedType(tree.tpt) val expr1 = typedExpr(tree.expr, tpt1.tpe) - cpy.Typed(tree, tpt1, expr1).withType(tpt1.tpe) + cpy.Typed(tree, expr1, tpt1).withType(tpt1.tpe) } def typedNamedArg(tree: untpd.NamedArg, pt: Type)(implicit ctx: Context) = { @@ -823,7 +823,7 @@ class Typer extends Namer with Applications with Implicits { } } - def typed(tree: untpd.Tree, pt: Type = WildcardType)(implicit ctx: Context): Tree = ctx.traceIndented (i"typing $tree") { + def typed(tree: untpd.Tree, pt: Type = WildcardType)(implicit ctx: Context): Tree = ctx.traceIndented (i"typing $tree", show = true) { def encodeName(tree: untpd.Tree) = tree match { case tree: NameTree => tree.withName(tree.name.encode) @@ -928,7 +928,7 @@ class Typer extends Namer with Applications with Implicits { * (14) When in mode EXPRmode, apply a view * If all this fails, error */ - def adapt(tree: Tree, pt: Type)(implicit ctx: Context): Tree = ctx.traceIndented(i"adapting $tree of type ${tree.tpe} to $pt") { + def adapt(tree: Tree, pt: Type)(implicit ctx: Context): Tree = ctx.traceIndented(i"adapting $tree of type ${tree.tpe} to $pt", show = false) { def adaptOverloaded(ref: TermRef) = { val altDenots = ref.denot.alternatives -- cgit v1.2.3