diff --git a/community-build/test/scala/dotty/communitybuild/CommunityBuildTest.scala b/community-build/test/scala/dotty/communitybuild/CommunityBuildTest.scala index 6e3f2681129b..09835d738133 100644 --- a/community-build/test/scala/dotty/communitybuild/CommunityBuildTest.scala +++ b/community-build/test/scala/dotty/communitybuild/CommunityBuildTest.scala @@ -375,7 +375,8 @@ class CommunityBuildTest: @Test def betterfiles = projects.betterfiles.run() @Test def catsEffect2 = projects.catsEffect2.run() @Test def catsEffect3 = projects.catsEffect3.run() - @Test def dottyCpsAsync = projects.dottyCpsAsync.run() + // Temporarily disabled until problem discovered in comments to #9449 is fixed + // @Test def dottyCpsAsync = projects.dottyCpsAsync.run() @Test def effpi = projects.effpi.run() @Test def endpoints4s = projects.endpoints4s.run() @Test def fastparse = projects.fastparse.run() diff --git a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala index 5aba3e43e368..f30874729eb4 100644 --- a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala +++ b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala @@ -357,9 +357,6 @@ object Parsers { offset } - def reportMissing(expected: Token): Unit = - syntaxError(ExpectedTokenButFound(expected, in.token)) - /** semi = nl {nl} | `;' * nl = `\n' // where allowed */ @@ -1825,7 +1822,7 @@ object Parsers { * the initially parsed (...) region? */ def toBeContinued(altToken: Token): Boolean = - if in.token == altToken || in.isNewLine || migrateTo3 then + if in.isNewLine || migrateTo3 then false // a newline token means the expression is finished else if !in.canStartStatTokens.contains(in.token) || in.isLeadingInfixOperator(inConditional = true) @@ -1835,37 +1832,27 @@ object Parsers { followedByToken(altToken) // scan ahead to see whether we find a `then` or `do` def condExpr(altToken: Token): Tree = - if in.token == LPAREN then - var t: Tree = atSpan(in.offset) { Parens(inParens(exprInParens())) } - val enclosedInParens = !toBeContinued(altToken) - if !enclosedInParens then - t = inSepRegion(InCond) { - expr1Rest(postfixExprRest(simpleExprRest(t)), Location.ElseWhere) - } - if in.token == altToken then - if rewriteToOldSyntax() then revertToParens(t) - in.nextToken() + val t: Tree = + if in.token == LPAREN then + var t: Tree = atSpan(in.offset) { Parens(inParens(exprInParens())) } + if in.token != altToken then + if toBeContinued(altToken) then + t = inSepRegion(InCond) { + expr1Rest(postfixExprRest(simpleExprRest(t)), Location.ElseWhere) + } + else + if rewriteToNewSyntax(t.span) then + dropParensOrBraces(t.span.start, s"${tokenString(altToken)}") + in.observeIndented() + return t + t + else if in.isNestedStart then + try expr() finally newLinesOpt() else - if (altToken == THEN || enclosedInParens) && in.isNewLine then - in.observeIndented() - if !enclosedInParens && in.token != INDENT then reportMissing(altToken) - if (rewriteToNewSyntax(t.span)) - dropParensOrBraces(t.span.start, s"${tokenString(altToken)}") - t - else - val t = - if in.isNestedStart then - try expr() finally newLinesOpt() - else - inSepRegion(InCond)(expr()) - if rewriteToOldSyntax(t.span.startPos) then - revertToParens(t) - if altToken == THEN && in.isNewLine then - // don't require a `then` at the end of a line - in.observeIndented() - if in.token != INDENT then accept(altToken) - t - end condExpr + inSepRegion(InCond)(expr()) + if rewriteToOldSyntax(t.span.startPos) then revertToParens(t) + accept(altToken) + t /** Expr ::= [`implicit'] FunParams (‘=>’ | ‘?=>’) Expr * | Expr1 diff --git a/compiler/src/dotty/tools/dotc/semanticdb/ExtractSemanticDB.scala b/compiler/src/dotty/tools/dotc/semanticdb/ExtractSemanticDB.scala index af65a7f45259..29a5c6b67d2c 100644 --- a/compiler/src/dotty/tools/dotc/semanticdb/ExtractSemanticDB.scala +++ b/compiler/src/dotty/tools/dotc/semanticdb/ExtractSemanticDB.scala @@ -546,7 +546,7 @@ class ExtractSemanticDB extends Phase: extension (sym: Symbol): private def adjustIfCtorTyparam(using Context) = - if sym.isType && sym.owner.exists && sym.owner.isConstructor + if sym.isType && sym.owner.exists && sym.owner.isConstructor then matchingMemberType(sym, sym.owner.owner) else sym @@ -557,20 +557,20 @@ class ExtractSemanticDB extends Phase: /**Necessary because not all of the eventual flags are propagated from the Tree to the symbol yet. */ private def symbolKinds(tree: NamedDefTree)(using Context): Set[SymbolKind] = - if tree.symbol.isSelfSym + if tree.symbol.isSelfSym then Set.empty else val symkinds = mutable.HashSet.empty[SymbolKind] tree match case tree: ValDef => - if !tree.symbol.is(Param) + if !tree.symbol.is(Param) then symkinds += (if tree.mods is Mutable then SymbolKind.Var else SymbolKind.Val) - if tree.rhs.isEmpty && !tree.symbol.isOneOf(TermParam | CaseAccessor | ParamAccessor) + if tree.rhs.isEmpty && !tree.symbol.isOneOf(TermParam | CaseAccessor | ParamAccessor) then symkinds += SymbolKind.Abstract case tree: DefDef => - if tree.isSetterDef + if tree.isSetterDef then symkinds += SymbolKind.Setter - else if tree.rhs.isEmpty + else if tree.rhs.isEmpty then symkinds += SymbolKind.Abstract case tree: Bind => symkinds += SymbolKind.Val @@ -584,7 +584,7 @@ class ExtractSemanticDB extends Phase: vparams <- vparamss vparam <- vparams do - if !excludeSymbol(vparam.symbol) + if !excludeSymbol(vparam.symbol) then traverseAnnotsOfDefinition(vparam.symbol) val symkinds = getters.get(vparam.name).fold(SymbolKind.emptySet)(getter => diff --git a/compiler/src/dotty/tools/dotc/semanticdb/Scala3.scala b/compiler/src/dotty/tools/dotc/semanticdb/Scala3.scala index 87030ece370e..74547a2a71a7 100644 --- a/compiler/src/dotty/tools/dotc/semanticdb/Scala3.scala +++ b/compiler/src/dotty/tools/dotc/semanticdb/Scala3.scala @@ -58,9 +58,9 @@ object Scala3: displaySymbol(symbol.owner) else if symbol.is(ModuleClass) then displaySymbol(symbol.sourceModule) - else if symbol == defn.RootPackage + else if symbol == defn.RootPackage then RootPackageName - else if symbol.isEmptyPackage + else if symbol.isEmptyPackage then EmptyPackageName else symbol.name.show @@ -131,7 +131,7 @@ object Scala3: def unapply(symbolInfo: SymbolInformation): Option[Int] = symbolInfo.symbol match case locals(ints) => val bi = BigInt(ints) - if bi.isValidInt + if bi.isValidInt then Some(bi.toInt) else None @@ -242,14 +242,14 @@ object Scala3: while i < len do val a = o1.charAt(i) val b = o2.charAt(i) - if a.isDigit && b.isDigit + if a.isDigit && b.isDigit then val byDigit = Integer.compare(toDigit(o1, i), toDigit(o2, i)) if (byDigit != 0) return byDigit else i = seekNonDigit(o1, i) else val result = Character.compare(a, b) - if result != 0 + if result != 0 then return result i += 1 end while diff --git a/compiler/src/dotty/tools/dotc/transform/Erasure.scala b/compiler/src/dotty/tools/dotc/transform/Erasure.scala index 4a9f9ea4622c..1d628bb75daa 100644 --- a/compiler/src/dotty/tools/dotc/transform/Erasure.scala +++ b/compiler/src/dotty/tools/dotc/transform/Erasure.scala @@ -647,7 +647,7 @@ object Erasure { if defn.specialErasure.contains(owner) then assert(sym.isConstructor, s"${sym.showLocated}") defn.specialErasure(owner) - else if defn.isSyntheticFunctionClass(owner) + else if defn.isSyntheticFunctionClass(owner) then defn.erasedFunctionClass(owner) else owner diff --git a/compiler/src/dotty/tools/dotc/typer/Applications.scala b/compiler/src/dotty/tools/dotc/typer/Applications.scala index 1376199c9162..ce13622a629f 100644 --- a/compiler/src/dotty/tools/dotc/typer/Applications.scala +++ b/compiler/src/dotty/tools/dotc/typer/Applications.scala @@ -1471,7 +1471,7 @@ trait Applications extends Compatibility { case tp1: MethodType => // (1) tp1.paramInfos.isEmpty && tp2.isInstanceOf[LambdaType] || { - if tp1.isVarArgsMethod + if tp1.isVarArgsMethod then tp2.isVarArgsMethod && isApplicableMethodRef(alt2, tp1.paramInfos.map(_.repeatedToSingle), WildcardType) else diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala index a15f3909aae1..f414c0aadf3a 100644 --- a/compiler/src/dotty/tools/dotc/typer/Typer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala @@ -2146,6 +2146,7 @@ class Typer extends Namer && !cls.isAllOf(PrivateLocal) && effectiveOwner.is(Trait) && !effectiveOwner.derivesFrom(defn.ObjectClass) + then report.error(i"$cls cannot be defined in universal $effectiveOwner", cdef.srcPos) // Temporarily set the typed class def as root tree so that we have at least some diff --git a/language-server/src/dotty/tools/languageserver/DottyLanguageServer.scala b/language-server/src/dotty/tools/languageserver/DottyLanguageServer.scala index 80018b324fa0..b95a21e10122 100644 --- a/language-server/src/dotty/tools/languageserver/DottyLanguageServer.scala +++ b/language-server/src/dotty/tools/languageserver/DottyLanguageServer.scala @@ -65,7 +65,7 @@ class DottyLanguageServer extends LanguageServer private[this] var myDependentProjects: mutable.Map[ProjectConfig, mutable.Set[ProjectConfig]] = _ def drivers: Map[ProjectConfig, InteractiveDriver] = thisServer.synchronized { - if myDrivers == null + if myDrivers == null then assert(rootUri != null, "`drivers` cannot be called before `initialize`") val configFile = new File(new URI(rootUri + '/' + IDE_CONFIG_FILE)) val configs: List[ProjectConfig] = (new ObjectMapper).readValue(configFile, classOf[Array[ProjectConfig]]).toList @@ -102,12 +102,12 @@ class DottyLanguageServer extends LanguageServer System.gc() for ((_, driver, opened) <- driverConfigs; (uri, source) <- opened) driver.run(uri, source) - if Memory.isCritical() + if Memory.isCritical() then println(s"WARNING: Insufficient memory to run Scala language server on these projects.") } private def checkMemory() = - if Memory.isCritical() + if Memory.isCritical() then CompletableFutures.computeAsync { _ => restart() } /** The configuration of the project that owns `uri`. */ @@ -149,7 +149,7 @@ class DottyLanguageServer extends LanguageServer /** A mapping from project `p` to the set of projects that transitively depend on `p`. */ def dependentProjects: Map[ProjectConfig, Set[ProjectConfig]] = thisServer.synchronized { - if myDependentProjects == null + if myDependentProjects == null then val idToConfig = drivers.keys.map(k => k.id -> k).toMap val allProjects = drivers.keySet @@ -192,7 +192,7 @@ class DottyLanguageServer extends LanguageServer throw ex } } - if synchronize + if synchronize then thisServer.synchronized { computation() } else computation() @@ -829,15 +829,15 @@ object DottyLanguageServer { def completionItemKind(sym: Symbol)(implicit ctx: Context): lsp4j.CompletionItemKind = { import lsp4j.{CompletionItemKind => CIK} - if sym.is(Package) || sym.is(Module) + if sym.is(Package) || sym.is(Module) then CIK.Module // No CompletionItemKind.Package (https://github.com/Microsoft/language-server-protocol/issues/155) - else if sym.isConstructor + else if sym.isConstructor then CIK.Constructor - else if sym.isClass + else if sym.isClass then CIK.Class - else if sym.is(Mutable) + else if sym.is(Mutable) then CIK.Variable - else if sym.is(Method) + else if sym.is(Method) then CIK.Method else CIK.Field @@ -861,7 +861,7 @@ object DottyLanguageServer { } def markupContent(content: String): lsp4j.MarkupContent = { - if content.isEmpty + if content.isEmpty then null else { val markup = new lsp4j.MarkupContent diff --git a/tests/neg/i8731.scala b/tests/neg/i8731.scala index bda0a4e7325e..97ae8308b20b 100644 --- a/tests/neg/i8731.scala +++ b/tests/neg/i8731.scala @@ -6,7 +6,7 @@ object test: case _ => () // error: missing parameter type end match - if 3 == 3 + if 3 == 3 then () end if else // error: illegal start of definition diff --git a/tests/pos/indent.scala b/tests/pos/indent.scala index da97b9abd7f1..3428011ea4fe 100644 --- a/tests/pos/indent.scala +++ b/tests/pos/indent.scala @@ -19,12 +19,12 @@ object Test: println("world") 33 val y1 = - if x > 0 + if x > 0 then 1 else 2 val y2 = - if (y > 0) && y < 0 + if (y > 0) && y < 0 then 1 else 2