diff --git a/compiler/src/dotty/tools/dotc/core/TypeOps.scala b/compiler/src/dotty/tools/dotc/core/TypeOps.scala index 3d5482701ce8..3b01eabf4d41 100644 --- a/compiler/src/dotty/tools/dotc/core/TypeOps.scala +++ b/compiler/src/dotty/tools/dotc/core/TypeOps.scala @@ -379,29 +379,31 @@ trait TypeOps { this: Context => // TODO: Make standalone object. * where is the full name of the owner followed by a "." minus * the prefix "dotty.language.". */ - def featureEnabled(owner: ClassSymbol, feature: TermName): Boolean = { - val hasImport = + def featureEnabled(feature: TermName, owner: Symbol = NoSymbol): Boolean = { + def hasImport = { + val owner1 = if (!owner.exists) defn.LanguageModuleClass else owner ctx.importInfo != null && - ctx.importInfo.featureImported(owner, feature)(ctx.withPhase(ctx.typerPhase)) - def hasOption = { + ctx.importInfo.featureImported(feature, owner1)(ctx.withPhase(ctx.typerPhase)) + } + val hasOption = { def toPrefix(sym: Symbol): String = - if (!sym.exists || (sym eq defn.LanguageModuleClass)) "" + if (!sym.exists) "" else toPrefix(sym.owner) + sym.name + "." val featureName = toPrefix(owner) + feature ctx.base.settings.language.value exists (s => s == featureName || s == "_") } - hasImport || hasOption + hasOption || hasImport } /** Is auto-tupling enabled? */ def canAutoTuple: Boolean = - !featureEnabled(defn.LanguageModuleClass, nme.noAutoTupling) + !featureEnabled(nme.noAutoTupling) def scala2Mode: Boolean = - featureEnabled(defn.LanguageModuleClass, nme.Scala2) + featureEnabled(nme.Scala2) def dynamicsEnabled: Boolean = - featureEnabled(defn.LanguageModuleClass, nme.dynamics) + featureEnabled(nme.dynamics) def testScala2Mode(msg: => Message, pos: SourcePosition, replace: => Unit = ()): Boolean = { if (scala2Mode) { @@ -414,7 +416,8 @@ trait TypeOps { this: Context => // TODO: Make standalone object. /** Is option -language:Scala2 set? * This test is used when we are too early in the pipeline to consider imports. */ - def scala2Setting = ctx.settings.language.value.contains(nme.Scala2.toString) + def scala2Setting: Boolean = + ctx.settings.language.value.contains(nme.Scala2.toString) /** Refine child based on parent * diff --git a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala index 93a3a1e9c9d5..a20298d0a68e 100644 --- a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala +++ b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala @@ -296,6 +296,9 @@ object Parsers { def deprecationWarning(msg: => Message, offset: Int = in.offset): Unit = ctx.deprecationWarning(msg, source.atSpan(Span(offset))) + def errorOrMigrationWarning(msg: => Message, offset: Int = in.offset): Unit = + ctx.errorOrMigrationWarning(msg, source.atSpan(Span(offset))) + /** Issue an error at current offset that input is incomplete */ def incompleteInputError(msg: => Message): Unit = ctx.incompleteInputError(msg, source.atSpan(Span(in.offset))) @@ -1135,7 +1138,7 @@ object Parsers { AppliedTypeTree(toplevelTyp(), Ident(pname)) } :: contextBounds(pname) case VIEWBOUND => - deprecationWarning("view bounds `<%' are deprecated, use a context bound `:' instead") + errorOrMigrationWarning("view bounds `<%' are deprecated, use a context bound `:' instead") atSpan(in.skipToken()) { Function(Ident(pname) :: Nil, toplevelTyp()) } :: contextBounds(pname) diff --git a/compiler/src/dotty/tools/dotc/parsing/Tokens.scala b/compiler/src/dotty/tools/dotc/parsing/Tokens.scala index 936663eb9b14..3bebe4a6f6cd 100644 --- a/compiler/src/dotty/tools/dotc/parsing/Tokens.scala +++ b/compiler/src/dotty/tools/dotc/parsing/Tokens.scala @@ -112,7 +112,7 @@ abstract class TokensCommon { //final val SUPERTYPE = 81; enter(SUPERTYPE, ">:") //final val HASH = 82; enter(HASH, "#") final val AT = 83; enter(AT, "@") - //final val VIEWBOUND = 84; enter(VIEWBOUND, "<%") // TODO: deprecate + //final val VIEWBOUND = 84; enter(VIEWBOUND, "<%") val keywords: TokenSet @@ -193,7 +193,7 @@ object Tokens extends TokensCommon { final val SUBTYPE = 80; enter(SUBTYPE, "<:") final val SUPERTYPE = 81; enter(SUPERTYPE, ">:") final val HASH = 82; enter(HASH, "#") - final val VIEWBOUND = 84; enter(VIEWBOUND, "<%") // TODO: deprecate + final val VIEWBOUND = 84; enter(VIEWBOUND, "<%") final val QUOTE = 85; enter(QUOTE, "'") /** XML mode */ diff --git a/compiler/src/dotty/tools/dotc/reporting/Reporter.scala b/compiler/src/dotty/tools/dotc/reporting/Reporter.scala index e0b3af4ad99b..f03e39963663 100644 --- a/compiler/src/dotty/tools/dotc/reporting/Reporter.scala +++ b/compiler/src/dotty/tools/dotc/reporting/Reporter.scala @@ -66,11 +66,10 @@ trait Reporting { this: Context => def featureWarning(msg: => Message, pos: SourcePosition = NoSourcePosition): Unit = reportWarning(new FeatureWarning(msg, pos)) - def featureWarning(feature: String, featureDescription: String, isScala2Feature: Boolean, + def featureWarning(feature: String, featureDescription: String, featureUseSite: Symbol, required: Boolean, pos: SourcePosition): Unit = { val req = if (required) "needs to" else "should" - val prefix = if (isScala2Feature) "scala." else "dotty." - val fqname = prefix + "language." + feature + val fqname = s"scala.language.$feature" val explain = { if (reporter.isReportedFeatureUseSite(featureUseSite)) "" diff --git a/compiler/src/dotty/tools/dotc/typer/Checking.scala b/compiler/src/dotty/tools/dotc/typer/Checking.scala index 8d197bf7fbf3..c6d4f0fbd0e4 100644 --- a/compiler/src/dotty/tools/dotc/typer/Checking.scala +++ b/compiler/src/dotty/tools/dotc/typer/Checking.scala @@ -617,7 +617,7 @@ trait Checking { def checkImplicitConversionDefOK(sym: Symbol)(implicit ctx: Context): Unit = { def check(): Unit = { checkFeature( - defn.LanguageModuleClass, nme.implicitConversions, + nme.implicitConversions, i"Definition of implicit conversion $sym", ctx.owner.topLevelClass, sym.sourcePos) @@ -654,20 +654,17 @@ trait Checking { defn.isPredefClass(conv.owner) || conv.name == nme.reflectiveSelectable && conv.maybeOwner.maybeOwner.maybeOwner == defn.ScalaPackageClass if (!conversionOK) - checkFeature(defn.LanguageModuleClass, nme.implicitConversions, + checkFeature(nme.implicitConversions, i"Use of implicit conversion ${conv.showLocated}", NoSymbol, posd.sourcePos) } /** Issue a feature warning if feature is not enabled */ - def checkFeature(base: ClassSymbol, - name: TermName, + def checkFeature(name: TermName, description: => String, featureUseSite: Symbol, pos: SourcePosition)(implicit ctx: Context): Unit = - if (!ctx.featureEnabled(base, name)) - ctx.featureWarning(name.toString, description, - isScala2Feature = base.isContainedIn(defn.LanguageModuleClass), - featureUseSite, required = false, pos) + if (!ctx.featureEnabled(name)) + ctx.featureWarning(name.toString, description, featureUseSite, required = false, pos) /** Check that `tp` is a class type and that any top-level type arguments in this type * are feasible, i.e. that their lower bound conforms to their upper bound. If a type @@ -1048,5 +1045,5 @@ trait NoChecking extends ReChecking { override def checkNoForwardDependencies(vparams: List[ValDef])(implicit ctx: Context): Unit = () override def checkMembersOK(tp: Type, pos: SourcePosition)(implicit ctx: Context): Type = tp override def checkInInlineContext(what: String, posd: Positioned)(implicit ctx: Context): Unit = () - override def checkFeature(base: ClassSymbol, name: TermName, description: => String, featureUseSite: Symbol, pos: SourcePosition)(implicit ctx: Context): Unit = () + override def checkFeature(name: TermName, description: => String, featureUseSite: Symbol, pos: SourcePosition)(implicit ctx: Context): Unit = () } diff --git a/compiler/src/dotty/tools/dotc/typer/Implicits.scala b/compiler/src/dotty/tools/dotc/typer/Implicits.scala index 99e6800ad66d..f4df867ef2da 100644 --- a/compiler/src/dotty/tools/dotc/typer/Implicits.scala +++ b/compiler/src/dotty/tools/dotc/typer/Implicits.scala @@ -947,7 +947,7 @@ trait Implicits { self: Typer => private def strictEquality(implicit ctx: Context): Boolean = ctx.mode.is(Mode.StrictEquality) || - ctx.featureEnabled(defn.LanguageModuleClass, nme.strictEquality) + ctx.featureEnabled(nme.strictEquality) /** An Eql[T, U] instance is assumed * - if one of T, U is an error type, or diff --git a/compiler/src/dotty/tools/dotc/typer/ImportInfo.scala b/compiler/src/dotty/tools/dotc/typer/ImportInfo.scala index 33e02fd349a0..0c69d37cd0db 100644 --- a/compiler/src/dotty/tools/dotc/typer/ImportInfo.scala +++ b/compiler/src/dotty/tools/dotc/typer/ImportInfo.scala @@ -146,15 +146,15 @@ class ImportInfo(symf: Context => Symbol, val selectors: List[untpd.Tree], private[this] var myUnimported: Symbol = _ /** Does this import clause or a preceding import clause import `owner.feature`? */ - def featureImported(owner: Symbol, feature: TermName)(implicit ctx: Context): Boolean = { + def featureImported(feature: TermName, owner: Symbol)(implicit ctx: Context): Boolean = { def compute = { - val isImportOwner = site.widen.typeSymbol `eq` owner + val isImportOwner = site.widen.typeSymbol.eq(owner) if (isImportOwner && originals.contains(feature)) true else if (isImportOwner && excluded.contains(feature)) false else { var c = ctx.outer while (c.importInfo eq ctx.importInfo) c = c.outer - (c.importInfo != null) && c.importInfo.featureImported(owner, feature)(c) + (c.importInfo != null) && c.importInfo.featureImported(feature, owner)(c) } } if (lastOwner.ne(owner) || !lastResults.contains(feature)) { diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala index 48171be2327a..3ca8421e88c2 100644 --- a/compiler/src/dotty/tools/dotc/typer/Typer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala @@ -1692,8 +1692,7 @@ class Typer extends Namer !ctx.dynamicsEnabled if (reportDynamicInheritance) { val isRequired = parents1.exists(_.tpe.isRef(defn.DynamicClass)) - ctx.featureWarning(nme.dynamics.toString, "extension of type scala.Dynamic", isScala2Feature = true, - cls, isRequired, cdef.sourcePos) + ctx.featureWarning(nme.dynamics.toString, "extension of type scala.Dynamic", cls, isRequired, cdef.sourcePos) } checkNonCyclicInherited(cls.thisType, cls.classParents, cls.info.decls, cdef.posd) diff --git a/compiler/test/dotty/tools/dotc/CompilationTests.scala b/compiler/test/dotty/tools/dotc/CompilationTests.scala index 772ab1b3b544..c8f34726d2d0 100644 --- a/compiler/test/dotty/tools/dotc/CompilationTests.scala +++ b/compiler/test/dotty/tools/dotc/CompilationTests.scala @@ -34,7 +34,7 @@ class CompilationTests extends ParallelTesting { // @Test // enable to test compileStdLib separately with detailed stats def compileStdLibOnly: Unit = { implicit val testGroup: TestGroup = TestGroup("compileStdLibOnly") - compileList("compileStdLib", TestSources.stdLibSources, scala2Mode.and("-migration", "-Yno-inline", "-Ydetailed-stats")) + compileList("compileStdLib", TestSources.stdLibSources, scala2Mode.and("-migration", "-Yno-inline")) }.checkCompile() @Test def pos: Unit = { diff --git a/docs/docs/internals/syntax.md b/docs/docs/internals/syntax.md index 9e3bf68924c9..6ec6675f9931 100644 --- a/docs/docs/internals/syntax.md +++ b/docs/docs/internals/syntax.md @@ -171,7 +171,7 @@ NamedTypeArg ::= id ‘=’ Type NamedTypeArgs ::= ‘[’ NamedTypeArg {‘,’ NamedTypeArg} ‘]’ nts Refinement ::= ‘{’ [RefineDcl] {semi [RefineDcl]} ‘}’ ds SubtypeBounds ::= [‘>:’ Type] [‘<:’ Type] | INT TypeBoundsTree(lo, hi) -TypeParamBounds ::= SubtypeBounds {‘<%’ Type} {‘:’ Type} ContextBounds(typeBounds, tps) +TypeParamBounds ::= SubtypeBounds {‘:’ Type} ContextBounds(typeBounds, tps) ``` ### Expressions diff --git a/library/src/scalaShadowing/language.scala b/library/src/scalaShadowing/language.scala index a64c985e5a10..f2d655c0fdcf 100644 --- a/library/src/scalaShadowing/language.scala +++ b/library/src/scalaShadowing/language.scala @@ -30,6 +30,7 @@ package scalaShadowing * * - [[Scala2 `Scala2`] backwards compatibility mode for Scala2 * - [[noAtoTupling `noAutoTupling`]] disable auto-tupling + * - [[strictEquality `strictEquality`]] enable strick equality * * @groupname production Language Features * @groupname experimental Experimental Language Features @@ -217,6 +218,6 @@ object language { /** Where imported, auto-tupling is disabled */ object noAutoTupling - /* Where imported loose equality using eqAny is disabled */ + /** Where imported loose equality using eqAny is disabled */ object strictEquality } diff --git a/tests/pos/spec-doubledef-old.scala b/tests/pos-scala2/spec-doubledef-old.scala similarity index 100% rename from tests/pos/spec-doubledef-old.scala rename to tests/pos-scala2/spec-doubledef-old.scala diff --git a/tests/pos/t3688.scala b/tests/pos-scala2/t3688.scala similarity index 100% rename from tests/pos/t3688.scala rename to tests/pos-scala2/t3688.scala