From 71f5da349ad3cd9fdb3a6b69d4e954dc34764144 Mon Sep 17 00:00:00 2001 From: Jamie Thompson Date: Tue, 15 Mar 2022 13:10:57 +0100 Subject: [PATCH] add 3.2 language mode, treat it like 3.0, 3.1 it is not available to be set by the user. Future PR can make it visible to the user, or behave differently to 3.0 language mode. --- .../src/dotty/tools/dotc/config/Feature.scala | 4 ++-- .../dotty/tools/dotc/config/SourceVersion.scala | 3 +-- .../src/dotty/tools/dotc/parsing/Parsers.scala | 16 ++++++++-------- .../src/dotty/tools/dotc/parsing/Scanners.scala | 8 ++++++-- compiler/src/dotty/tools/dotc/report.scala | 4 ++-- .../src/dotty/tools/dotc/typer/Checking.scala | 7 ++++--- .../src/dotty/tools/dotc/typer/RefChecks.scala | 13 ++++++++----- compiler/src/dotty/tools/dotc/typer/Typer.scala | 9 +++++---- 8 files changed, 36 insertions(+), 28 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/config/Feature.scala b/compiler/src/dotty/tools/dotc/config/Feature.scala index 8564aa88c499..04c7b5872204 100644 --- a/compiler/src/dotty/tools/dotc/config/Feature.scala +++ b/compiler/src/dotty/tools/dotc/config/Feature.scala @@ -89,9 +89,9 @@ object Feature: * and return `true`, otherwise return `false`. */ def warnOnMigration(msg: Message, pos: SrcPos, - version: SourceVersion = defaultSourceVersion)(using Context): Boolean = + version: SourceVersion)(using Context): Boolean = if sourceVersion.isMigrating && sourceVersion.stable == version - || (version == `3.0` || version == `3.1`) && migrateTo3 + || (version == `3.0` || version == `3.1` || version == `3.2`) && migrateTo3 then report.migrationWarning(msg, pos) true diff --git a/compiler/src/dotty/tools/dotc/config/SourceVersion.scala b/compiler/src/dotty/tools/dotc/config/SourceVersion.scala index 466e503e1a66..9361c7e6774d 100644 --- a/compiler/src/dotty/tools/dotc/config/SourceVersion.scala +++ b/compiler/src/dotty/tools/dotc/config/SourceVersion.scala @@ -6,7 +6,7 @@ import core.Decorators.* import util.Property enum SourceVersion: - case `3.0-migration`, `3.0`, `3.1`, `future-migration`, `future` + case `3.0-migration`, `3.0`, `3.1`, `3.2`, `future-migration`, `future` val isMigrating: Boolean = toString.endsWith("-migration") @@ -16,7 +16,6 @@ enum SourceVersion: def isAtLeast(v: SourceVersion) = stable.ordinal >= v.ordinal object SourceVersion extends Property.Key[SourceVersion]: - def defaultSourceVersion = `3.0` val allSourceVersionNames = values.toList.map(_.toString.toTermName) end SourceVersion diff --git a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala index 893f797709e1..7a5620be0415 100644 --- a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala +++ b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala @@ -439,7 +439,7 @@ object Parsers { case t: Typed => report.errorOrMigrationWarning( em"parentheses are required around the parameter of a lambda${rewriteNotice()}", - in.sourcePos()) + in.sourcePos(), from = `3.0`) if migrateTo3 then patch(source, t.span.startPos, "(") patch(source, t.span.endPos, ")") @@ -1180,7 +1180,7 @@ object Parsers { |or enclose in braces '{$name} if you want a quoted expression. |For now, you can also `import language.deprecated.symbolLiterals` to accept |the idiom, but this possibility might no longer be available in the future.""", - in.sourcePos()) + in.sourcePos(), from = `3.0`) if migrateTo3 then patch(source, Span(in.offset, in.offset + 1), "Symbol(\"") patch(source, Span(in.charOffset - 1), "\")") @@ -1272,7 +1272,7 @@ object Parsers { i"""This opening brace will start a new statement in Scala 3. |It needs to be indented to the right to keep being treated as |an argument to the previous expression.${rewriteNotice()}""", - in.sourcePos()) + in.sourcePos(), from = `3.0`) patch(source, Span(in.offset), " ") def possibleTemplateStart(isNew: Boolean = false): Unit = @@ -1826,7 +1826,7 @@ object Parsers { else if in.token == VIEWBOUND then report.errorOrMigrationWarning( "view bounds `<%' are no longer supported, use a context bound `:' instead", - in.sourcePos()) + in.sourcePos(), from = `3.0`) atSpan(in.skipToken()) { Function(Ident(pname) :: Nil, toplevelTyp()) } :: contextBounds(pname) @@ -1976,7 +1976,7 @@ object Parsers { report.errorOrMigrationWarning( i"""`do while ` is no longer supported, |use `while ; do ()` instead.${rewriteNotice()}""", - in.sourcePos()) + in.sourcePos(), from = `3.0`) val start = in.skipToken() atSpan(start) { val body = expr() @@ -2096,7 +2096,7 @@ object Parsers { report.errorOrMigrationWarning( em"""`_*` can be used only for last argument of method application. |It is no longer allowed in operands of infix operations.""", - in.sourcePos(uscoreStart)) + in.sourcePos(uscoreStart), from = `3.0`) else syntaxError(SeqWildcardPatternPos(), uscoreStart) Typed(t, atSpan(uscoreStart) { Ident(tpnme.WILDCARD_STAR) }) @@ -3347,7 +3347,7 @@ object Parsers { if migrateTo3 then report.errorOrMigrationWarning( s"Procedure syntax no longer supported; `$toInsert` should be inserted here", - in.sourcePos()) + in.sourcePos(), from = `3.0`) patch(source, Span(in.lastOffset), toInsert) true else @@ -3756,7 +3756,7 @@ object Parsers { if (in.token == LBRACE || in.token == COLONEOL) { report.errorOrMigrationWarning( "`extends` must be followed by at least one parent", - in.sourcePos()) + in.sourcePos(), from = `3.0`) Nil } else constrApps() diff --git a/compiler/src/dotty/tools/dotc/parsing/Scanners.scala b/compiler/src/dotty/tools/dotc/parsing/Scanners.scala index 4a902907278b..8407ac5f2089 100644 --- a/compiler/src/dotty/tools/dotc/parsing/Scanners.scala +++ b/compiler/src/dotty/tools/dotc/parsing/Scanners.scala @@ -18,6 +18,7 @@ import scala.collection.immutable.SortedMap import rewrites.Rewrites.patch import config.Feature import config.Feature.migrateTo3 +import config.SourceVersion.`3.0` object Scanners { @@ -255,7 +256,10 @@ object Scanners { def handleMigration(keyword: Token): Token = if scala3keywords.contains(keyword) && migrateTo3 then val what = tokenString(keyword) - report.errorOrMigrationWarning(i"$what is now a keyword, write `$what` instead of $what to keep it as an identifier", sourcePos()) + report.errorOrMigrationWarning( + i"$what is now a keyword, write `$what` instead of $what to keep it as an identifier", + sourcePos(), + from = `3.0`) patch(source, Span(offset), "`") patch(source, Span(offset + identifier.length), "`") IDENTIFIER @@ -427,7 +431,7 @@ object Scanners { em"""$what starts with an operator; |it is now treated as a continuation of the $previous, |not as a separate statement.""", - sourcePos()) + sourcePos(), from = `3.0`) true } diff --git a/compiler/src/dotty/tools/dotc/report.scala b/compiler/src/dotty/tools/dotc/report.scala index 36c857b94e37..94a7b4f318fa 100644 --- a/compiler/src/dotty/tools/dotc/report.scala +++ b/compiler/src/dotty/tools/dotc/report.scala @@ -68,7 +68,7 @@ object report: if ctx.settings.YdebugTypeError.value then ex.printStackTrace() def errorOrMigrationWarning(msg: Message, pos: SrcPos = NoSourcePosition, - from: SourceVersion = SourceVersion.defaultSourceVersion)(using Context): Unit = + from: SourceVersion)(using Context): Unit = if sourceVersion.isAtLeast(from) then if sourceVersion.isMigrating && sourceVersion.ordinal <= from.ordinal then migrationWarning(msg, pos) else error(msg, pos) @@ -112,4 +112,4 @@ object report: case Nil => pos recur(pos.sourcePos, tpd.enclosingInlineds) -end report \ No newline at end of file +end report diff --git a/compiler/src/dotty/tools/dotc/typer/Checking.scala b/compiler/src/dotty/tools/dotc/typer/Checking.scala index c01a7504b9bd..0525ce805d2e 100644 --- a/compiler/src/dotty/tools/dotc/typer/Checking.scala +++ b/compiler/src/dotty/tools/dotc/typer/Checking.scala @@ -117,7 +117,7 @@ object Checking { if tp.isUnreducibleWild then report.errorOrMigrationWarning( showInferred(UnreducibleApplication(tycon), tp, tpt), - tree.srcPos) + tree.srcPos, from = `3.0`) case _ => } def checkValidIfApply(using Context): Unit = @@ -189,7 +189,8 @@ object Checking { def checkRealizable(tp: Type, pos: SrcPos, what: String = "path")(using Context): Unit = { val rstatus = realizability(tp) if (rstatus ne Realizable) - report.errorOrMigrationWarning(em"$tp is not a legal $what\nsince it${rstatus.msg}", pos) + report.errorOrMigrationWarning( + em"$tp is not a legal $what\nsince it${rstatus.msg}", pos, from = `3.0`) } /** Given a parent `parent` of a class `cls`, if `parent` is a trait check that @@ -641,7 +642,7 @@ object Checking { } val notPrivate = new NotPrivate val info = notPrivate(sym.info) - notPrivate.errors.foreach(error => report.errorOrMigrationWarning(error(), sym.srcPos)) + notPrivate.errors.foreach(error => report.errorOrMigrationWarning(error(), sym.srcPos, from = `3.0`)) info } diff --git a/compiler/src/dotty/tools/dotc/typer/RefChecks.scala b/compiler/src/dotty/tools/dotc/typer/RefChecks.scala index 000764d43c2b..8d96d256a881 100644 --- a/compiler/src/dotty/tools/dotc/typer/RefChecks.scala +++ b/compiler/src/dotty/tools/dotc/typer/RefChecks.scala @@ -16,6 +16,7 @@ import Decorators._ import OverridingPairs.isOverridingPair import typer.ErrorReporting._ import config.Feature.{warnOnMigration, migrateTo3} +import config.SourceVersion.`3.0` import config.Printers.refcheck import reporting._ import Constants.Constant @@ -345,7 +346,7 @@ object RefChecks { isOverridingPair(member, memberTp, other, otherTp, fallBack = warnOnMigration( overrideErrorMsg("no longer has compatible type"), - (if (member.owner == clazz) member else clazz).srcPos)) + (if (member.owner == clazz) member else clazz).srcPos, version = `3.0`)) catch case ex: MissingType => // can happen when called with upwardsSelf as qualifier of memberTp and otherTp, // because in that case we might access types that are not members of the qualifier. @@ -453,7 +454,9 @@ object RefChecks { // Also excluded under Scala2 mode are overrides of default methods of Java traits. if (autoOverride(member) || other.owner.isAllOf(JavaInterface) && - warnOnMigration("`override` modifier required when a Java 8 default method is re-implemented", member.srcPos)) + warnOnMigration( + "`override` modifier required when a Java 8 default method is re-implemented", + member.srcPos, version = `3.0`)) member.setFlag(Override) else if (member.isType && self.memberInfo(member) =:= self.memberInfo(other)) () // OK, don't complain about type aliases which are equal @@ -484,7 +487,7 @@ object RefChecks { else if (member.is(ModuleVal) && !other.isRealMethod && !other.isOneOf(Deferred | Lazy)) overrideError("may not override a concrete non-lazy value") else if (member.is(Lazy, butNot = Module) && !other.isRealMethod && !other.is(Lazy) && - !warnOnMigration(overrideErrorMsg("may not override a non-lazy value"), member.srcPos)) + !warnOnMigration(overrideErrorMsg("may not override a non-lazy value"), member.srcPos, version = `3.0`)) overrideError("may not override a non-lazy value") else if (other.is(Lazy) && !other.isRealMethod && !member.is(Lazy)) overrideError("must be declared lazy to override a lazy value") @@ -769,7 +772,7 @@ object RefChecks { em"""${mbr.showLocated} is not a legal implementation of `$name` in $clazz | its type $mbrType | does not conform to ${mbrd.info}""", - (if (mbr.owner == clazz) mbr else clazz).srcPos) + (if (mbr.owner == clazz) mbr else clazz).srcPos, from = `3.0`) } } @@ -782,7 +785,7 @@ object RefChecks { for (baseCls <- caseCls.info.baseClasses.tail) if (baseCls.typeParams.exists(_.paramVarianceSign != 0)) for (problem <- variantInheritanceProblems(baseCls, caseCls, "non-variant", "case ")) - report.errorOrMigrationWarning(problem(), clazz.srcPos) + report.errorOrMigrationWarning(problem(), clazz.srcPos, from = `3.0`) checkNoAbstractMembers() if (abstractErrors.isEmpty) checkNoAbstractDecls(clazz) diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala index 29a303ee6718..aba819c06847 100644 --- a/compiler/src/dotty/tools/dotc/typer/Typer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala @@ -385,7 +385,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer if !symsMatch && !suppressErrors then report.errorOrMigrationWarning( AmbiguousReference(name, Definition, Inheritance, prevCtx)(using outer), - pos) + pos, from = `3.0`) if migrateTo3 then patch(Span(pos.span.start), if prevCtx.owner == refctx.owner.enclosingClass then "this." @@ -2661,7 +2661,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer case closure(_, _, _) => case _ => val recovered = typed(qual)(using ctx.fresh.setExploreTyperState()) - report.errorOrMigrationWarning(OnlyFunctionsCanBeFollowedByUnderscore(recovered.tpe.widen), tree.srcPos) + report.errorOrMigrationWarning(OnlyFunctionsCanBeFollowedByUnderscore(recovered.tpe.widen), tree.srcPos, from = `3.0`) if (migrateTo3) { // Under -rewrite, patch `x _` to `(() => x)` patch(Span(tree.span.start), "(() => ") @@ -2813,7 +2813,8 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer then ", use `_` to denote a higher-kinded type parameter" else "" val namePos = tree.sourcePos.withSpan(tree.nameSpan) - report.errorOrMigrationWarning(s"`?` is not a valid type name$addendum", namePos) + report.errorOrMigrationWarning( + s"`?` is not a valid type name$addendum", namePos, from = `3.0`) if tree.isClassDef then typedClassDef(tree, sym.asClass)(using ctx.localContext(tree, sym)) else @@ -3596,7 +3597,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer def isAutoApplied(sym: Symbol): Boolean = sym.isConstructor || sym.matchNullaryLoosely - || Feature.warnOnMigration(MissingEmptyArgumentList(sym.show), tree.srcPos) + || Feature.warnOnMigration(MissingEmptyArgumentList(sym.show), tree.srcPos, version = `3.0`) && { patch(tree.span.endPos, "()"); true } // Reasons NOT to eta expand: