aboutsummaryrefslogtreecommitdiff
path: root/compiler/src
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/src')
-rw-r--r--compiler/src/dotty/tools/dotc/config/Config.scala4
-rw-r--r--compiler/src/dotty/tools/dotc/core/TypeOps.scala20
-rw-r--r--compiler/src/dotty/tools/dotc/core/Types.scala6
-rw-r--r--compiler/src/dotty/tools/dotc/parsing/Parsers.scala2
-rw-r--r--compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala26
5 files changed, 49 insertions, 9 deletions
diff --git a/compiler/src/dotty/tools/dotc/config/Config.scala b/compiler/src/dotty/tools/dotc/config/Config.scala
index 7744a5479..119af9483 100644
--- a/compiler/src/dotty/tools/dotc/config/Config.scala
+++ b/compiler/src/dotty/tools/dotc/config/Config.scala
@@ -133,6 +133,8 @@ object Config {
*/
final val LogPendingFindMemberThreshold = 10
- /** Maximal number of outstanding recursive calls to findMember */
+ /** Maximal number of outstanding recursive calls to findMember before backing out
+ * when findMemberLimit is set.
+ */
final val PendingFindMemberLimit = LogPendingFindMemberThreshold * 4
}
diff --git a/compiler/src/dotty/tools/dotc/core/TypeOps.scala b/compiler/src/dotty/tools/dotc/core/TypeOps.scala
index 5f9263009..c2a7d7ea6 100644
--- a/compiler/src/dotty/tools/dotc/core/TypeOps.scala
+++ b/compiler/src/dotty/tools/dotc/core/TypeOps.scala
@@ -10,7 +10,8 @@ import NameOps._
import Decorators._
import StdNames._
import Annotations._
-import util.SimpleMap
+import config.Config
+import util.{SimpleMap, Property}
import collection.mutable
import ast.tpd._
@@ -67,7 +68,10 @@ trait TypeOps { this: Context => // TODO: Make standalone object.
if (thiscls.derivesFrom(cls) && pre.baseTypeRef(thiscls).exists) {
if (theMap != null && theMap.currentVariance <= 0 && !isLegalPrefix(pre)) {
ctx.base.unsafeNonvariant = ctx.runId
- AnnotatedType(pre, Annotation(defn.UnsafeNonvariantAnnot, Nil))
+ pre match {
+ case AnnotatedType(_, ann) if ann.symbol == defn.UnsafeNonvariantAnnot => pre
+ case _ => AnnotatedType(pre, Annotation(defn.UnsafeNonvariantAnnot, Nil))
+ }
}
else pre
}
@@ -85,13 +89,15 @@ trait TypeOps { this: Context => // TODO: Make standalone object.
if (sym.isStatic) tp
else {
val pre1 = asSeenFrom(tp.prefix, pre, cls, theMap)
- if (pre1.isUnsafeNonvariant)
- pre1.member(tp.name).info match {
+ if (pre1.isUnsafeNonvariant) {
+ val safeCtx = ctx.withProperty(TypeOps.findMemberLimit, Some(()))
+ pre1.member(tp.name)(safeCtx).info match {
case TypeAlias(alias) =>
// try to follow aliases of this will avoid skolemization.
return alias
case _ =>
}
+ }
tp.derivedSelect(pre1)
}
case tp: ThisType =>
@@ -554,4 +560,10 @@ trait TypeOps { this: Context => // TODO: Make standalone object.
object TypeOps {
@sharable var track = false // !!!DEBUG
+
+ /** When a property with this key is set in a context, it limit the number
+ * of recursive member searches. If the limit is reached, findMember returns
+ * NoDenotation.
+ */
+ val findMemberLimit = new Property.Key[Unit]
}
diff --git a/compiler/src/dotty/tools/dotc/core/Types.scala b/compiler/src/dotty/tools/dotc/core/Types.scala
index df1e68944..636204f64 100644
--- a/compiler/src/dotty/tools/dotc/core/Types.scala
+++ b/compiler/src/dotty/tools/dotc/core/Types.scala
@@ -581,8 +581,12 @@ object Types {
{ val recCount = ctx.findMemberCount + 1
ctx.findMemberCount = recCount
- if (recCount >= Config.LogPendingFindMemberThreshold)
+ if (recCount >= Config.LogPendingFindMemberThreshold) {
ctx.pendingMemberSearches = name :: ctx.pendingMemberSearches
+ if (ctx.property(TypeOps.findMemberLimit).isDefined &&
+ ctx.findMemberCount > Config.PendingFindMemberLimit)
+ return NoDenotation
+ }
}
//assert(ctx.findMemberCount < 20)
diff --git a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala
index 76f82d8af..57dd1ea20 100644
--- a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala
+++ b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala
@@ -730,7 +730,7 @@ object Parsers {
in.token match {
case ARROW => functionRest(t :: Nil)
- case FORSOME => syntaxError("existential types no longer supported; use a wildcard type or dependent type instead"); t
+ case FORSOME => syntaxError(ExistentialTypesNoLongerSupported()); t
case _ => t
}
}
diff --git a/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala b/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala
index 9dda233bf..b55b7e868 100644
--- a/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala
+++ b/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala
@@ -5,8 +5,7 @@ package diagnostic
import dotc.core._
import Contexts.Context, Decorators._, Symbols._, Names._, NameOps._, Types._
-import util.{SourceFile, NoSource}
-import util.{SourcePosition, NoSourcePosition}
+import util.SourcePosition
import config.Settings.Setting
import interfaces.Diagnostic.{ERROR, WARNING, INFO}
import printing.Highlighting._
@@ -901,4 +900,27 @@ object messages {
val msg = hl"trying to define package with same name as `$existing`"
val explanation = ""
}
+
+ case class ExistentialTypesNoLongerSupported()(implicit ctx: Context) extends Message(34) {
+ val kind = "Syntax"
+ val msg =
+ hl"""|Existential types are no longer supported -
+ |use a wildcard or dependent type instead"""
+ val explanation =
+ hl"""|The use of existential types is no longer supported.
+ |
+ |You should use a wildcard or dependent type instead.
+ |
+ |For example:
+ |
+ |Instead of using ${"forSome"} to specify a type variable
+ |
+ |${"List[T forSome { type T }]"}
+ |
+ |Try using a wildcard type variable
+ |
+ |${"List[_]"}
+ |"""
+ }
+
}