aboutsummaryrefslogtreecommitdiff
path: root/compiler/src/dotty/tools/dotc
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/src/dotty/tools/dotc')
-rw-r--r--compiler/src/dotty/tools/dotc/ast/Desugar.scala8
-rw-r--r--compiler/src/dotty/tools/dotc/core/Annotations.scala14
-rw-r--r--compiler/src/dotty/tools/dotc/core/Definitions.scala3
-rw-r--r--compiler/src/dotty/tools/dotc/core/TypeComparer.scala2
-rw-r--r--compiler/src/dotty/tools/dotc/core/TypeOps.scala4
-rw-r--r--compiler/src/dotty/tools/dotc/core/Types.scala13
-rw-r--r--compiler/src/dotty/tools/dotc/core/classfile/ClassfileParser.scala2
-rw-r--r--compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala6
-rw-r--r--compiler/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala5
-rw-r--r--compiler/src/dotty/tools/dotc/parsing/Parsers.scala16
-rw-r--r--compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala15
-rw-r--r--compiler/src/dotty/tools/dotc/printing/Printer.scala4
-rw-r--r--compiler/src/dotty/tools/dotc/reporting/Reporter.scala16
-rw-r--r--compiler/src/dotty/tools/dotc/reporting/diagnostic/ErrorMessageID.java4
-rw-r--r--compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala21
-rw-r--r--compiler/src/dotty/tools/dotc/transform/FullParameterization.scala5
-rw-r--r--compiler/src/dotty/tools/dotc/transform/TailRec.scala2
-rw-r--r--compiler/src/dotty/tools/dotc/typer/Applications.scala14
-rw-r--r--compiler/src/dotty/tools/dotc/typer/Checking.scala3
-rw-r--r--compiler/src/dotty/tools/dotc/typer/ErrorReporting.scala16
-rw-r--r--compiler/src/dotty/tools/dotc/typer/Implicits.scala2
-rw-r--r--compiler/src/dotty/tools/dotc/typer/ImportInfo.scala47
-rw-r--r--compiler/src/dotty/tools/dotc/typer/Inliner.scala11
-rw-r--r--compiler/src/dotty/tools/dotc/typer/Namer.scala28
-rw-r--r--compiler/src/dotty/tools/dotc/typer/RefChecks.scala2
-rw-r--r--compiler/src/dotty/tools/dotc/typer/Typer.scala5
26 files changed, 164 insertions, 104 deletions
diff --git a/compiler/src/dotty/tools/dotc/ast/Desugar.scala b/compiler/src/dotty/tools/dotc/ast/Desugar.scala
index deb239143..b5be89440 100644
--- a/compiler/src/dotty/tools/dotc/ast/Desugar.scala
+++ b/compiler/src/dotty/tools/dotc/ast/Desugar.scala
@@ -469,7 +469,13 @@ object desugar {
val originalVparams = constr1.vparamss.toIterator.flatten
val tparamAccessors = derivedTparams.map(_.withMods(originalTparams.next.mods))
val caseAccessor = if (isCaseClass) CaseAccessor else EmptyFlags
- val vparamAccessors = derivedVparamss.flatten.map(_.withMods(originalVparams.next.mods | caseAccessor))
+ val vparamAccessors = derivedVparamss match {
+ case first :: rest =>
+ first.map(_.withMods(originalVparams.next.mods | caseAccessor)) ++
+ rest.flatten.map(_.withMods(originalVparams.next.mods))
+ case _ =>
+ Nil
+ }
cpy.TypeDef(cdef)(
name = className,
rhs = cpy.Template(impl)(constr, parents1, self1,
diff --git a/compiler/src/dotty/tools/dotc/core/Annotations.scala b/compiler/src/dotty/tools/dotc/core/Annotations.scala
index 985b1ea3d..5464dce4f 100644
--- a/compiler/src/dotty/tools/dotc/core/Annotations.scala
+++ b/compiler/src/dotty/tools/dotc/core/Annotations.scala
@@ -117,11 +117,17 @@ object Annotations {
}
/** Create an annotation where the symbol and the tree are computed lazily. */
- def deferredSymAndTree(sym: => Symbol, treeFn: Context => Tree)(implicit ctx: Context): Annotation =
+ def deferredSymAndTree(symf: Context => Symbol, treeFn: Context => Tree)(implicit ctx: Context): Annotation =
new LazyAnnotation {
- lazy val symf = sym
-
- override def symbol(implicit ctx: Context): Symbol = symf
+ private[this] var mySym: Symbol = _
+
+ override def symbol(implicit ctx: Context): Symbol = {
+ if (mySym == null || mySym.defRunId != ctx.runId) {
+ mySym = symf(ctx)
+ assert(mySym != null)
+ }
+ mySym
+ }
def complete(implicit ctx: Context) = treeFn(ctx)
}
diff --git a/compiler/src/dotty/tools/dotc/core/Definitions.scala b/compiler/src/dotty/tools/dotc/core/Definitions.scala
index 9e9e39a84..847177e2f 100644
--- a/compiler/src/dotty/tools/dotc/core/Definitions.scala
+++ b/compiler/src/dotty/tools/dotc/core/Definitions.scala
@@ -9,6 +9,7 @@ import scala.annotation.{ switch, meta }
import scala.collection.{ mutable, immutable }
import PartialFunction._
import collection.mutable
+import util.common.alwaysZero
import scala.reflect.api.{ Universe => ApiUniverse }
object Definitions {
@@ -152,7 +153,7 @@ class Definitions {
resultTypeFn: PolyType => Type, flags: FlagSet = EmptyFlags) = {
val tparamNames = tpnme.syntheticTypeParamNames(typeParamCount)
val tparamBounds = tparamNames map (_ => TypeBounds.empty)
- val ptype = PolyType(tparamNames)(_ => tparamBounds, resultTypeFn)
+ val ptype = PolyType(tparamNames, tparamNames.map(alwaysZero))(_ => tparamBounds, resultTypeFn)
enterMethod(cls, name, ptype, flags)
}
diff --git a/compiler/src/dotty/tools/dotc/core/TypeComparer.scala b/compiler/src/dotty/tools/dotc/core/TypeComparer.scala
index 6063cbf38..fca111702 100644
--- a/compiler/src/dotty/tools/dotc/core/TypeComparer.scala
+++ b/compiler/src/dotty/tools/dotc/core/TypeComparer.scala
@@ -489,7 +489,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
case tp1 @ MethodType(_, formals1) =>
(tp1.signature consistentParams tp2.signature) &&
matchingParams(formals1, formals2, tp1.isJava, tp2.isJava) &&
- (!tp1.isImplicit || tp2.isImplicit) && // non-implicit functions shadow implicit ones
+ (tp1.isImplicit == tp2.isImplicit) &&
isSubType(tp1.resultType, tp2.resultType.subst(tp2, tp1))
case _ =>
false
diff --git a/compiler/src/dotty/tools/dotc/core/TypeOps.scala b/compiler/src/dotty/tools/dotc/core/TypeOps.scala
index c2a7d7ea6..308e6e306 100644
--- a/compiler/src/dotty/tools/dotc/core/TypeOps.scala
+++ b/compiler/src/dotty/tools/dotc/core/TypeOps.scala
@@ -401,12 +401,12 @@ trait TypeOps { this: Context => // TODO: Make standalone object.
def forwardRefs(from: Symbol, to: Type, prefs: List[TypeRef]) = to match {
case to @ TypeBounds(lo1, hi1) if lo1 eq hi1 =>
for (pref <- prefs) {
- def forward(): Unit =
+ def forward()(implicit ctx: Context): Unit =
for (argSym <- pref.decls)
if (argSym is BaseTypeArg)
forwardRef(argSym, from, to, cls, decls)
pref.info match {
- case info: TempClassInfo => info.addSuspension(forward)
+ case info: TempClassInfo => info.addSuspension(implicit ctx => forward())
case _ => forward()
}
}
diff --git a/compiler/src/dotty/tools/dotc/core/Types.scala b/compiler/src/dotty/tools/dotc/core/Types.scala
index ae9122853..200e94a1e 100644
--- a/compiler/src/dotty/tools/dotc/core/Types.scala
+++ b/compiler/src/dotty/tools/dotc/core/Types.scala
@@ -2603,7 +2603,7 @@ object Types {
case t => mapOver(t)
}
}
- PolyType(paramNames ++ that.paramNames)(
+ PolyType(paramNames ++ that.paramNames, variances ++ that.variances)(
x => this.paramBounds.mapConserve(_.subst(this, x).bounds) ++
that.paramBounds.mapConserve(shift(_).subst(that, x).bounds),
x => shift(that.resultType).subst(that, x).subst(this, x))
@@ -2634,11 +2634,10 @@ object Types {
}
object PolyType {
- def apply(paramNames: List[TypeName], variances: List[Int] = Nil)(
+ def apply(paramNames: List[TypeName], variances: List[Int])(
paramBoundsExp: PolyType => List[TypeBounds],
resultTypeExp: PolyType => Type)(implicit ctx: Context): PolyType = {
- val vs = if (variances.isEmpty) paramNames.map(alwaysZero) else variances
- unique(new PolyType(paramNames, vs)(paramBoundsExp, resultTypeExp))
+ unique(new PolyType(paramNames, variances)(paramBoundsExp, resultTypeExp))
}
def unapply(tl: PolyType): Some[(List[LambdaParam], Type)] =
@@ -3089,14 +3088,14 @@ object Types {
* be no longer temporary. These actions will be performed once `cls` gets a real
* ClassInfo.
*/
- private var suspensions: List[() => Unit] = Nil
+ private var suspensions: List[Context => Unit] = Nil
- def addSuspension(suspension: () => Unit): Unit = suspensions ::= suspension
+ def addSuspension(suspension: Context => Unit): Unit = suspensions ::= suspension
/** Install classinfo with known parents in `denot` and resume all suspensions */
def finalize(denot: SymDenotation, parents: List[TypeRef])(implicit ctx: Context) = {
denot.info = derivedClassInfo(classParents = parents)
- suspensions.foreach(_())
+ suspensions.foreach(_(ctx))
}
}
diff --git a/compiler/src/dotty/tools/dotc/core/classfile/ClassfileParser.scala b/compiler/src/dotty/tools/dotc/core/classfile/ClassfileParser.scala
index 5b751ef3c..36d478c6d 100644
--- a/compiler/src/dotty/tools/dotc/core/classfile/ClassfileParser.scala
+++ b/compiler/src/dotty/tools/dotc/core/classfile/ClassfileParser.scala
@@ -806,7 +806,7 @@ class ClassfileParser(
def classSymbol(externalName: Name)(implicit ctx: Context): Symbol = {
/** Return the symbol of `innerName`, having the given `externalName`. */
def innerSymbol(externalName: Name, innerName: Name, static: Boolean): Symbol = {
- def getMember(sym: Symbol, name: Name): Symbol =
+ def getMember(sym: Symbol, name: Name)(implicit ctx: Context): Symbol =
if (static)
if (sym == classRoot.symbol) staticScope.lookup(name)
else sym.companionModule.info.member(name).symbol
diff --git a/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala b/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala
index ffd594454..fcba957c0 100644
--- a/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala
+++ b/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala
@@ -554,7 +554,9 @@ class TreeUnpickler(reader: TastyReader, tastyName: TastyName.Table, posUnpickle
val end = readEnd()
val tp = readType()
val lazyAnnotTree = readLater(end, rdr => ctx => rdr.readTerm()(ctx))
- annots += Annotation.deferredSymAndTree(tp.typeSymbol, _ => lazyAnnotTree.complete)
+ annots += Annotation.deferredSymAndTree(
+ implicit ctx => tp.typeSymbol,
+ implicit ctx => lazyAnnotTree.complete)
case tag =>
assert(false, s"illegal modifier tag $tag at $currentAddr, end = $end")
}
@@ -769,7 +771,7 @@ class TreeUnpickler(reader: TastyReader, tastyName: TastyName.Table, posUnpickle
cls.setApplicableFlags(fork.indexStats(end))
val constr = readIndexedDef().asInstanceOf[DefDef]
- def mergeTypeParamsAndAliases(tparams: List[TypeDef], stats: List[Tree]): (List[Tree], List[Tree]) =
+ def mergeTypeParamsAndAliases(tparams: List[TypeDef], stats: List[Tree])(implicit ctx: Context): (List[Tree], List[Tree]) =
(tparams, stats) match {
case (tparam :: tparams1, (alias: TypeDef) :: stats1)
if tparam.name == alias.name.expandedName(cls) =>
diff --git a/compiler/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala b/compiler/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala
index b01f6cc6a..3a2a45fd2 100644
--- a/compiler/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala
+++ b/compiler/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala
@@ -932,9 +932,10 @@ class Scala2Unpickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClas
protected def deferredAnnot(end: Int)(implicit ctx: Context): Annotation = {
val start = readIndex
val atp = readTypeRef()
+ val phase = ctx.phase
Annotation.deferred(
- atp.typeSymbol, implicit ctx1 =>
- atReadPos(start, () => readAnnotationContents(end)(ctx1.withPhase(ctx.phase))))
+ atp.typeSymbol, implicit ctx =>
+ atReadPos(start, () => readAnnotationContents(end)(ctx.withPhase(phase))))
}
/* Read an abstract syntax tree */
diff --git a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala
index b46bc401d..c14108d2e 100644
--- a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala
+++ b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala
@@ -993,20 +993,22 @@ object Parsers {
else {
val saved = placeholderParams
placeholderParams = Nil
+
+ def wrapPlaceholders(t: Tree) = try
+ if (placeholderParams.isEmpty) t
+ else new WildcardFunction(placeholderParams.reverse, t)
+ finally placeholderParams = saved
+
val t = expr1(location)
if (in.token == ARROW) {
- placeholderParams = saved
- closureRest(start, location, convertToParams(t))
+ placeholderParams = Nil // don't interpret `_' to the left of `=>` as placeholder
+ wrapPlaceholders(closureRest(start, location, convertToParams(t)))
}
else if (isWildcard(t)) {
placeholderParams = placeholderParams ::: saved
t
}
- else
- try
- if (placeholderParams.isEmpty) t
- else new WildcardFunction(placeholderParams.reverse, t)
- finally placeholderParams = saved
+ else wrapPlaceholders(t)
}
}
diff --git a/compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala b/compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala
index ac25f7cfd..0d1068b8c 100644
--- a/compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala
+++ b/compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala
@@ -7,6 +7,7 @@ import Contexts.Context, Scopes.Scope, Denotations.Denotation, Annotations.Annot
import StdNames.{nme, tpnme}
import ast.Trees._, ast._
import typer.Implicits._
+import typer.ImportInfo
import config.Config
import java.lang.Integer.toOctalString
import config.Config.summarizeDepth
@@ -177,7 +178,8 @@ class PlainPrinter(_ctx: Context) extends Printer {
varianceString(variance) ~ name.toString ~ toText(bounds)
changePrec(GlobalPrec) {
"[" ~ Text((tp.variances, tp.paramNames, tp.paramBounds).zipped.map(paramText), ", ") ~
- "] => " ~ toTextGlobal(tp.resultType)
+ "]" ~ (" => " provided !tp.resultType.isInstanceOf[MethodType]) ~
+ toTextGlobal(tp.resultType)
}
case tp: PolyParam =>
polyParamNameString(tp) ~ polyHash(tp.binder)
@@ -502,6 +504,17 @@ class PlainPrinter(_ctx: Context) extends Printer {
"?Unknown Implicit Result?"
}
+ def toText(importInfo: ImportInfo): Text = {
+ val siteStr = importInfo.site.show
+ val exprStr = if (siteStr endsWith ".type") siteStr dropRight 5 else siteStr
+ val selectorStr = importInfo.selectors match {
+ case Ident(name) :: Nil => name.show
+ case _ => "{...}"
+ }
+ s"import $exprStr.$selectorStr"
+ }
+
+
private var maxSummarized = Int.MaxValue
def summarized[T](depth: Int)(op: => T): T = {
diff --git a/compiler/src/dotty/tools/dotc/printing/Printer.scala b/compiler/src/dotty/tools/dotc/printing/Printer.scala
index 506773a4b..e163a83f3 100644
--- a/compiler/src/dotty/tools/dotc/printing/Printer.scala
+++ b/compiler/src/dotty/tools/dotc/printing/Printer.scala
@@ -6,6 +6,7 @@ import Texts._, ast.Trees._
import Types.Type, Symbols.Symbol, Contexts.Context, Scopes.Scope, Constants.Constant,
Names.Name, Denotations._, Annotations.Annotation
import typer.Implicits.SearchResult
+import typer.ImportInfo
/** The base class of all printers
*/
@@ -98,6 +99,9 @@ abstract class Printer {
/** Textual representation of implicit search result */
def toText(result: SearchResult): Text
+ /** Textual representation of info relating to an import clause */
+ def toText(result: ImportInfo): Text
+
/** Perform string or text-producing operation `op` so that only a
* summarized text with given recursion depth is shown
*/
diff --git a/compiler/src/dotty/tools/dotc/reporting/Reporter.scala b/compiler/src/dotty/tools/dotc/reporting/Reporter.scala
index 26c1e5ebc..b2c7abec9 100644
--- a/compiler/src/dotty/tools/dotc/reporting/Reporter.scala
+++ b/compiler/src/dotty/tools/dotc/reporting/Reporter.scala
@@ -171,22 +171,6 @@ trait Reporting { this: Context =>
throw ex
}
}
-
- /** Implements a fold that applies the function `f` to the result of `op` if
- * there are no new errors in the reporter
- *
- * @param op operation checked for errors
- * @param f function applied to result of op
- * @return either the result of `op` if it had errors or the result of `f`
- * applied to it
- */
- def withNoError[A, B >: A](op: => A)(f: A => B): B = {
- val before = reporter.errorCount
- val op0 = op
-
- if (reporter.errorCount > before) op0
- else f(op0)
- }
}
/**
diff --git a/compiler/src/dotty/tools/dotc/reporting/diagnostic/ErrorMessageID.java b/compiler/src/dotty/tools/dotc/reporting/diagnostic/ErrorMessageID.java
index c74130b44..2bf15cb7c 100644
--- a/compiler/src/dotty/tools/dotc/reporting/diagnostic/ErrorMessageID.java
+++ b/compiler/src/dotty/tools/dotc/reporting/diagnostic/ErrorMessageID.java
@@ -49,7 +49,9 @@ public enum ErrorMessageID {
OverridesNothingButNameExistsID,
ForwardReferenceExtendsOverDefinitionID,
ExpectedTokenButFoundID,
- MixedLeftAndRightAssociativeOpsID;
+ MixedLeftAndRightAssociativeOpsID,
+ CantInstantiateAbstractClassOrTraitID,
+ ;
public int errorNumber() {
return ordinal() - 2;
diff --git a/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala b/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala
index 7fccebef9..34190c114 100644
--- a/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala
+++ b/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala
@@ -1062,7 +1062,7 @@ object messages {
|
|Define `${definition.name}` before it is used,
|or move the definition of `${value.name}` so it does not appear between
- |the declartion of `${definition.name}` and its use,
+ |the declaration of `${definition.name}` and its use,
|or define `${value.name}` as lazy.
|""".stripMargin
}
@@ -1127,4 +1127,23 @@ object messages {
|""".stripMargin
}
+ case class CantInstantiateAbstractClassOrTrait(cls: Symbol, isTrait: Boolean)(implicit ctx: Context)
+ extends Message(CantInstantiateAbstractClassOrTraitID) {
+ val kind = "Usage"
+ private val traitOrAbstract = if (isTrait) hl"a trait" else hl"abstract"
+ val msg = hl"""${cls.name} is ${traitOrAbstract}; it cannot be instantiated"""
+ val explanation =
+ hl"""|Abstract classes and traits need to be extended by a concrete class or object
+ |to make their functionality accessible.
+ |
+ |You may want to create an anonymous class extending ${cls.name} with
+ | ${s"class ${cls.name} { }"}
+ |
+ |or add a companion object with
+ | ${s"object ${cls.name} extends ${cls.name}"}
+ |
+ |You need to implement any abstract members in both cases.
+ |""".stripMargin
+ }
+
}
diff --git a/compiler/src/dotty/tools/dotc/transform/FullParameterization.scala b/compiler/src/dotty/tools/dotc/transform/FullParameterization.scala
index 6c69c735b..9e43fc999 100644
--- a/compiler/src/dotty/tools/dotc/transform/FullParameterization.scala
+++ b/compiler/src/dotty/tools/dotc/transform/FullParameterization.scala
@@ -101,6 +101,7 @@ trait FullParameterization {
}
val ctparams = if (abstractOverClass) clazz.typeParams else Nil
val ctnames = ctparams.map(_.name.unexpandedName)
+ val ctvariances = ctparams.map(_.variance)
/** The method result type */
def resultType(mapClassParams: Type => Type) = {
@@ -122,14 +123,14 @@ trait FullParameterization {
info match {
case info: PolyType =>
- PolyType(info.paramNames ++ ctnames)(
+ PolyType(info.paramNames ++ ctnames, info.variances ++ ctvariances)(
pt =>
(info.paramBounds.map(mapClassParams(_, pt).bounds) ++
mappedClassBounds(pt)).mapConserve(_.subst(info, pt).bounds),
pt => resultType(mapClassParams(_, pt)).subst(info, pt))
case _ =>
if (ctparams.isEmpty) resultType(identity)
- else PolyType(ctnames)(mappedClassBounds, pt => resultType(mapClassParams(_, pt)))
+ else PolyType(ctnames, ctvariances)(mappedClassBounds, pt => resultType(mapClassParams(_, pt)))
}
}
diff --git a/compiler/src/dotty/tools/dotc/transform/TailRec.scala b/compiler/src/dotty/tools/dotc/transform/TailRec.scala
index 3e7a7ed89..aa0845605 100644
--- a/compiler/src/dotty/tools/dotc/transform/TailRec.scala
+++ b/compiler/src/dotty/tools/dotc/transform/TailRec.scala
@@ -119,7 +119,7 @@ class TailRec extends MiniPhaseTransform with DenotTransformer with FullParamete
// now this speculatively transforms tree and throws away result in many cases
val rhsSemiTransformed = {
val transformer = new TailRecElimination(origMeth, dd.tparams, owner, thisTpe, mandatory, label, abstractOverClass = defIsTopLevel)
- val rhs = atGroupEnd(transformer.transform(dd.rhs)(_))
+ val rhs = atGroupEnd(implicit ctx => transformer.transform(dd.rhs))
rewrote = transformer.rewrote
rhs
}
diff --git a/compiler/src/dotty/tools/dotc/typer/Applications.scala b/compiler/src/dotty/tools/dotc/typer/Applications.scala
index 284b9e21e..de017961a 100644
--- a/compiler/src/dotty/tools/dotc/typer/Applications.scala
+++ b/compiler/src/dotty/tools/dotc/typer/Applications.scala
@@ -683,7 +683,7 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
*
* { val xs = es; e' = e' + args }
*/
- def typedOpAssign: Tree = track("typedOpAssign") {
+ def typedOpAssign(implicit ctx: Context): Tree = track("typedOpAssign") {
val Apply(Select(lhs, name), rhss) = tree
val lhs1 = typedExpr(lhs)
val liftedDefs = new mutable.ListBuffer[Tree]
@@ -805,16 +805,16 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
* whereas overloaded variants need to have a conforming variant.
*/
def trySelectUnapply(qual: untpd.Tree)(fallBack: Tree => Tree): Tree = {
- val genericProto = new UnapplyFunProto(WildcardType, this)
- def specificProto = new UnapplyFunProto(selType, this)
// try first for non-overloaded, then for overloaded ocurrences
def tryWithName(name: TermName)(fallBack: Tree => Tree)(implicit ctx: Context): Tree =
- tryEither {
- implicit ctx => typedExpr(untpd.Select(qual, name), specificProto)
+ tryEither { implicit ctx =>
+ val specificProto = new UnapplyFunProto(selType, this)
+ typedExpr(untpd.Select(qual, name), specificProto)
} {
(sel, _) =>
- tryEither {
- implicit ctx => typedExpr(untpd.Select(qual, name), genericProto)
+ tryEither { implicit ctx =>
+ val genericProto = new UnapplyFunProto(WildcardType, this)
+ typedExpr(untpd.Select(qual, name), genericProto)
} {
(_, _) => fallBack(sel)
}
diff --git a/compiler/src/dotty/tools/dotc/typer/Checking.scala b/compiler/src/dotty/tools/dotc/typer/Checking.scala
index fb0497c2b..48f9243f7 100644
--- a/compiler/src/dotty/tools/dotc/typer/Checking.scala
+++ b/compiler/src/dotty/tools/dotc/typer/Checking.scala
@@ -29,6 +29,7 @@ import ErrorReporting.{err, errorType}
import config.Printers.typr
import collection.mutable
import SymDenotations.NoCompleter
+import dotty.tools.dotc.reporting.diagnostic.messages.CantInstantiateAbstractClassOrTrait
import dotty.tools.dotc.transform.ValueClasses._
object Checking {
@@ -103,7 +104,7 @@ object Checking {
case tref: TypeRef =>
val cls = tref.symbol
if (cls.is(AbstractOrTrait))
- ctx.error(em"$cls is abstract; cannot be instantiated", pos)
+ ctx.error(CantInstantiateAbstractClassOrTrait(cls, isTrait = cls.is(Trait)), pos)
if (!cls.is(Module)) {
// Create a synthetic singleton type instance, and check whether
// it conforms to the self type of the class as seen from that instance.
diff --git a/compiler/src/dotty/tools/dotc/typer/ErrorReporting.scala b/compiler/src/dotty/tools/dotc/typer/ErrorReporting.scala
index 1238ad568..9d6a01ab7 100644
--- a/compiler/src/dotty/tools/dotc/typer/ErrorReporting.scala
+++ b/compiler/src/dotty/tools/dotc/typer/ErrorReporting.scala
@@ -111,11 +111,23 @@ object ErrorReporting {
errorTree(tree, typeMismatchMsg(normalize(tree.tpe, pt), pt, implicitFailure.postscript))
/** A subtype log explaining why `found` does not conform to `expected` */
- def whyNoMatchStr(found: Type, expected: Type) =
- if (ctx.settings.explaintypes.value)
+ def whyNoMatchStr(found: Type, expected: Type) = {
+ def dropJavaMethod(tp: Type): Type = tp match {
+ case tp: PolyType =>
+ tp.derivedPolyType(resType = dropJavaMethod(tp.resultType))
+ case tp: JavaMethodType =>
+ MethodType(tp.paramNames, tp.paramTypes, dropJavaMethod(tp.resultType))
+ case tp => tp
+ }
+ val found1 = dropJavaMethod(found)
+ val expected1 = dropJavaMethod(expected)
+ if ((found1 eq found) != (expected eq expected1) && (found1 <:< expected1))
+ "\n (Note that Scala's and Java's representation of this type differs)"
+ else if (ctx.settings.explaintypes.value)
"\n" + ctx.typerState.show + "\n" + TypeComparer.explained((found <:< expected)(_))
else
""
+ }
def typeMismatchMsg(found: Type, expected: Type, postScript: String = "") = {
// replace constrained polyparams and their typevars by their bounds where possible
diff --git a/compiler/src/dotty/tools/dotc/typer/Implicits.scala b/compiler/src/dotty/tools/dotc/typer/Implicits.scala
index 6949221fb..48cf0cfac 100644
--- a/compiler/src/dotty/tools/dotc/typer/Implicits.scala
+++ b/compiler/src/dotty/tools/dotc/typer/Implicits.scala
@@ -220,7 +220,7 @@ object Implicits {
}
/** The result of an implicit search */
- abstract class SearchResult extends Showable {
+ sealed abstract class SearchResult extends Showable {
def toText(printer: Printer): Text = printer.toText(this)
}
diff --git a/compiler/src/dotty/tools/dotc/typer/ImportInfo.scala b/compiler/src/dotty/tools/dotc/typer/ImportInfo.scala
index f7efb2ac2..3bee0bbe8 100644
--- a/compiler/src/dotty/tools/dotc/typer/ImportInfo.scala
+++ b/compiler/src/dotty/tools/dotc/typer/ImportInfo.scala
@@ -5,6 +5,7 @@ package typer
import ast.{tpd, untpd}
import ast.Trees._
import core._
+import printing.{Printer, Showable}
import util.SimpleMap
import Symbols._, Names._, Denotations._, Types._, Contexts._, StdNames._, Flags._
import Decorators.StringInterpolators
@@ -13,9 +14,9 @@ object ImportInfo {
/** The import info for a root import from given symbol `sym` */
def rootImport(refFn: () => TermRef)(implicit ctx: Context) = {
val selectors = untpd.Ident(nme.WILDCARD) :: Nil
- def expr = tpd.Ident(refFn())
- def imp = tpd.Import(expr, selectors)
- new ImportInfo(imp.symbol, selectors, None, isRootImport = true)
+ def expr(implicit ctx: Context) = tpd.Ident(refFn())
+ def imp(implicit ctx: Context) = tpd.Import(expr, selectors)
+ new ImportInfo(implicit ctx => imp.symbol, selectors, None, isRootImport = true)
}
}
@@ -27,14 +28,14 @@ object ImportInfo {
* @param isRootImport true if this is one of the implicit imports of scala, java.lang,
* scala.Predef or dotty.DottyPredef in the start context, false otherwise.
*/
-class ImportInfo(symf: => Symbol, val selectors: List[untpd.Tree],
- symNameOpt: Option[TermName], val isRootImport: Boolean = false)(implicit ctx: Context) {
+class ImportInfo(symf: Context => Symbol, val selectors: List[untpd.Tree],
+ symNameOpt: Option[TermName], val isRootImport: Boolean = false) extends Showable {
// Dotty deviation: we cannot use a lazy val here for the same reason
// that we cannot use one for `DottyPredefModuleRef`.
- def sym = {
+ def sym(implicit ctx: Context) = {
if (mySym == null) {
- mySym = symf
+ mySym = symf(ctx)
assert(mySym != null)
}
mySym
@@ -91,7 +92,7 @@ class ImportInfo(symf: => Symbol, val selectors: List[untpd.Tree],
}
/** The implicit references imported by this import clause */
- def importedImplicits: List[TermRef] = {
+ def importedImplicits(implicit ctx: Context): List[TermRef] = {
val pre = site
if (isWildcardImport) {
val refs = pre.implicitMembers
@@ -115,23 +116,21 @@ class ImportInfo(symf: => Symbol, val selectors: List[untpd.Tree],
* override import Predef.{any2stringAdd => _, StringAdd => _, _} // disables String +
* override import java.lang.{} // disables all imports
*/
- lazy val unimported: Symbol = {
- lazy val sym = site.termSymbol
- def maybeShadowsRoot = symNameOpt match {
- case Some(symName) => defn.ShadowableImportNames.contains(symName)
- case None => false
+ def unimported(implicit ctx: Context): Symbol = {
+ if (myUnimported == null) {
+ lazy val sym = site.termSymbol
+ def maybeShadowsRoot = symNameOpt match {
+ case Some(symName) => defn.ShadowableImportNames.contains(symName)
+ case None => false
+ }
+ myUnimported =
+ if (maybeShadowsRoot && defn.RootImportTypes.exists(_.symbol == sym)) sym
+ else NoSymbol
+ assert(myUnimported != null)
}
- if (maybeShadowsRoot && defn.RootImportTypes.exists(_.symbol == sym)) sym
- else NoSymbol
+ myUnimported
}
+ private[this] var myUnimported: Symbol = _
- override def toString = {
- val siteStr = site.show
- val exprStr = if (siteStr endsWith ".type") siteStr dropRight 5 else siteStr
- val selectorStr = selectors match {
- case Ident(name) :: Nil => name.show
- case _ => "{...}"
- }
- i"import $exprStr.$selectorStr"
- }
+ def toText(printer: Printer) = printer.toText(this)
}
diff --git a/compiler/src/dotty/tools/dotc/typer/Inliner.scala b/compiler/src/dotty/tools/dotc/typer/Inliner.scala
index fde304c69..27c7d0c2f 100644
--- a/compiler/src/dotty/tools/dotc/typer/Inliner.scala
+++ b/compiler/src/dotty/tools/dotc/typer/Inliner.scala
@@ -27,7 +27,7 @@ import transform.TypeUtils._
object Inliner {
import tpd._
- /** Adds accessors accessors for all non-public term members accessed
+ /** Adds accessors for all non-public term members accessed
* from `tree`. Non-public type members are currently left as they are.
* This means that references to a private type will lead to typing failures
* on the code when it is inlined. Less than ideal, but hard to do better (see below).
@@ -190,7 +190,8 @@ object Inliner {
val inlineCtx = ctx
sym.updateAnnotation(LazyBodyAnnotation { _ =>
implicit val ctx = inlineCtx
- ctx.withNoError(treeExpr(ctx))(makeInlineable)
+ val body = treeExpr(ctx)
+ if (ctx.reporter.hasErrors) body else makeInlineable(body)
})
}
}
@@ -233,8 +234,10 @@ object Inliner {
* and body that replace it.
*/
def inlineCall(tree: Tree, pt: Type)(implicit ctx: Context): Tree =
- if (enclosingInlineds.length < ctx.settings.xmaxInlines.value)
- new Inliner(tree, bodyToInline(tree.symbol)).inlined(pt)
+ if (enclosingInlineds.length < ctx.settings.xmaxInlines.value) {
+ val body = bodyToInline(tree.symbol) // can typecheck the tree and thereby produce errors
+ if (ctx.reporter.hasErrors) tree else new Inliner(tree, body).inlined(pt)
+ }
else errorTree(
tree,
i"""|Maximal number of successive inlines (${ctx.settings.xmaxInlines.value}) exceeded,
diff --git a/compiler/src/dotty/tools/dotc/typer/Namer.scala b/compiler/src/dotty/tools/dotc/typer/Namer.scala
index 3860ba225..d5f171fe3 100644
--- a/compiler/src/dotty/tools/dotc/typer/Namer.scala
+++ b/compiler/src/dotty/tools/dotc/typer/Namer.scala
@@ -24,6 +24,7 @@ import language.implicitConversions
import reporting.diagnostic.messages._
trait NamerContextOps { this: Context =>
+ import NamerContextOps._
/** Enter symbol into current class, if current class is owner of current context,
* or into current scope, if not. Should always be called instead of scope.enter
@@ -119,22 +120,25 @@ trait NamerContextOps { this: Context =>
else monotpe
}
- /** Find moduleClass/sourceModule in effective scope */
- private def findModuleBuddy(name: Name)(implicit ctx: Context) = {
- val scope = effectiveScope
- val it = scope.lookupAll(name).filter(_ is Module)
- assert(it.hasNext, s"no companion $name in $scope")
- it.next
- }
-
/** Add moduleClass or sourceModule functionality to completer
* for a module or module class
*/
- def adjustModuleCompleter(completer: LazyType, name: Name) =
+ def adjustModuleCompleter(completer: LazyType, name: Name) = {
+ val scope = this.effectiveScope
if (name.isTermName)
- completer withModuleClass (_ => findModuleBuddy(name.moduleClassName))
+ completer withModuleClass (implicit ctx => findModuleBuddy(name.moduleClassName, scope))
else
- completer withSourceModule (_ => findModuleBuddy(name.sourceModuleName))
+ completer withSourceModule (implicit ctx => findModuleBuddy(name.sourceModuleName, scope))
+ }
+}
+
+object NamerContextOps {
+ /** Find moduleClass/sourceModule in effective scope */
+ private def findModuleBuddy(name: Name, scope: Scope)(implicit ctx: Context) = {
+ val it = scope.lookupAll(name).filter(_ is Module)
+ assert(it.hasNext, s"no companion $name in $scope")
+ it.next
+ }
}
/** This class creates symbols from definitions and imports and gives them
@@ -378,7 +382,7 @@ class Namer { typer: Typer =>
case ref: RefTree => Some(ref.name.asTermName)
case _ => None
}
- ctx.fresh.setImportInfo(new ImportInfo(sym, imp.selectors, impNameOpt))
+ ctx.fresh.setImportInfo(new ImportInfo(implicit ctx => sym, imp.selectors, impNameOpt))
}
/** A new context for the interior of a class */
diff --git a/compiler/src/dotty/tools/dotc/typer/RefChecks.scala b/compiler/src/dotty/tools/dotc/typer/RefChecks.scala
index eab91701b..7c573d23c 100644
--- a/compiler/src/dotty/tools/dotc/typer/RefChecks.scala
+++ b/compiler/src/dotty/tools/dotc/typer/RefChecks.scala
@@ -789,7 +789,7 @@ class RefChecks extends MiniPhase { thisTransformer =>
val sym = tree.symbol
if (sym.exists && sym.owner.isTerm && !sym.is(Lazy))
currentLevel.levelAndIndex.get(sym) match {
- case Some((level, symIdx)) if symIdx < level.maxIndex =>
+ case Some((level, symIdx)) if symIdx <= level.maxIndex =>
ctx.error(ForwardReferenceExtendsOverDefinition(sym, level.refSym), level.refPos)
case _ =>
}
diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala
index 498fd001b..06200d3e4 100644
--- a/compiler/src/dotty/tools/dotc/typer/Typer.scala
+++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala
@@ -145,7 +145,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
*/
def bindingString(prec: Int, whereFound: Context, qualifier: String = "") =
if (prec == wildImport || prec == namedImport) {
- ex"""imported$qualifier by ${hl"${whereFound.importInfo.toString}"}"""
+ ex"""imported$qualifier by ${hl"${whereFound.importInfo}"}"""
} else
ex"""defined$qualifier in ${hl"${whereFound.owner.toString}"}"""
@@ -1964,7 +1964,8 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
if (Inliner.hasBodyToInline(tree.symbol) &&
!ctx.owner.ownersIterator.exists(_.isInlineMethod) &&
!ctx.settings.YnoInline.value &&
- !ctx.isAfterTyper)
+ !ctx.isAfterTyper &&
+ !ctx.reporter.hasErrors)
adapt(Inliner.inlineCall(tree, pt), pt)
else if (ctx.typeComparer.GADTused && pt.isValueType)
// Insert an explicit cast, so that -Ycheck in later phases succeeds.