diff --git a/community-build/src/scala/dotty/communitybuild/projects.scala b/community-build/src/scala/dotty/communitybuild/projects.scala index 498356da724b..e23112aab2a6 100644 --- a/community-build/src/scala/dotty/communitybuild/projects.scala +++ b/community-build/src/scala/dotty/communitybuild/projects.scala @@ -123,8 +123,6 @@ object SbtCommunityProject: def scalacOptions = List( "-Xcheck-macros", "-Wsafe-init", - "-Yexplicit-nulls", - "-language:unsafeNulls", ) object projects: diff --git a/compiler/src/dotty/tools/dotc/Run.scala b/compiler/src/dotty/tools/dotc/Run.scala index fb77ef3a1e8b..cd2f482822a8 100644 --- a/compiler/src/dotty/tools/dotc/Run.scala +++ b/compiler/src/dotty/tools/dotc/Run.scala @@ -606,7 +606,7 @@ extends ImplicitRunInfo, ConstraintRunInfo, cc.CaptureRunInfo { .setTyper(new Typer) .addMode(Mode.ImplicitsEnabled) .setTyperState(ctx.typerState.fresh(ctx.reporter)) - if ctx.settings.YexplicitNulls.value && !Feature.enabledBySetting(nme.unsafeNulls) then + if ctx.settings.YexplicitNulls.value || Feature.enabledBySetting(nme.safeNulls) then start = start.addMode(Mode.SafeNulls) ctx.initialize()(using start) // re-initialize the base context with start diff --git a/compiler/src/dotty/tools/dotc/config/Feature.scala b/compiler/src/dotty/tools/dotc/config/Feature.scala index de81a71f0bc9..293e435efe6a 100644 --- a/compiler/src/dotty/tools/dotc/config/Feature.scala +++ b/compiler/src/dotty/tools/dotc/config/Feature.scala @@ -58,6 +58,7 @@ object Feature: (nme.noAutoTupling, "Disable automatic tupling"), (nme.dynamics, "Allow direct or indirect subclasses of scala.Dynamic"), (nme.unsafeNulls, "Enable unsafe nulls for explicit nulls"), + (nme.safeNulls, "Enable safe nulls for explicit nulls"), (nme.postfixOps, "Allow postfix operators (not recommended)"), (nme.strictEquality, "Enable strict equality (disable canEqualAny)"), (nme.implicitConversions, "Allow implicit conversions without warnings"), diff --git a/compiler/src/dotty/tools/dotc/config/ScalaSettings.scala b/compiler/src/dotty/tools/dotc/config/ScalaSettings.scala index d155459054dc..bc857944c79b 100644 --- a/compiler/src/dotty/tools/dotc/config/ScalaSettings.scala +++ b/compiler/src/dotty/tools/dotc/config/ScalaSettings.scala @@ -561,7 +561,8 @@ private sealed trait YSettings: val YmagicOffsetHeader: Setting[String] = StringSetting(ForkSetting, "Ymagic-offset-header", "header", "Specify the magic header comment that marks the start of the actual code in generated wrapper scripts. Example: -Ymagic-offset-header:SOURCE_CODE_START. Then, in the source, the magic comment `///SOURCE_CODE_START:` marks the start of user code. The comment should be suffixed by `:` to indicate the original file.", "") // Experimental language features - val YexplicitNulls: Setting[Boolean] = BooleanSetting(ForkSetting, "Yexplicit-nulls", "Make reference types non-nullable. Nullable types can be expressed with unions: e.g. String|Null.") + val YexplicitNulls: Setting[Boolean] = BooleanSetting(ForkSetting, "Yexplicit-nulls", "Since explicit nulls is enabled by default, this flag now enables safe nulls for explicit-nulls") + val YnoExplicitNulls: Setting[Boolean] = BooleanSetting(ForkSetting, "Yno-explicit-nulls", "Make reference types implictly nullable.") val YnoFlexibleTypes: Setting[Boolean] = BooleanSetting(ForkSetting, "Yno-flexible-types", "Disable turning nullable Java return types and parameter types into flexible types, which behave like abstract types with a nullable lower bound and non-nullable upper bound.") val YflexifyTasty: Setting[Boolean] = BooleanSetting(ForkSetting, "Yflexify-tasty", "Apply flexification to Scala code compiled without -Yexplicit-nulls, when reading from tasty.") val YsafeInitGlobal: Setting[Boolean] = BooleanSetting(ForkSetting, "Ysafe-init-global", "Check safe initialization of global objects.") @@ -577,6 +578,7 @@ private sealed trait YSettings: val YexplainLowlevel: Setting[Boolean] = BooleanSetting(ForkSetting, "Yexplain-lowlevel", "When explaining type errors, show types at a lower level.") val YnoDoubleBindings: Setting[Boolean] = BooleanSetting(ForkSetting, "Yno-double-bindings", "Assert no namedtype is bound twice (should be enabled only if program is error-free).") val YshowVarBounds: Setting[Boolean] = BooleanSetting(ForkSetting, "Yshow-var-bounds", "Print type variables with their bounds.") + val YhideFlexibleTypes: Setting[Boolean] = BooleanSetting(ForkSetting, "Yhide-flexible-types", "Print flexible types as their base type. (T instead of (T)?)") val Yinstrument: Setting[Boolean] = BooleanSetting(ForkSetting, "Yinstrument", "Add instrumentation code that counts allocations and closure creations.") val YinstrumentDefs: Setting[Boolean] = BooleanSetting(ForkSetting, "Yinstrument-defs", "Add instrumentation code that counts method calls; needs -Yinstrument to be set, too.") diff --git a/compiler/src/dotty/tools/dotc/core/Contexts.scala b/compiler/src/dotty/tools/dotc/core/Contexts.scala index 077056766a54..ede70290b9c8 100644 --- a/compiler/src/dotty/tools/dotc/core/Contexts.scala +++ b/compiler/src/dotty/tools/dotc/core/Contexts.scala @@ -483,13 +483,13 @@ object Contexts { fresh.setSetting(ctx.settings.color, "never") /** Is the explicit nulls option set? */ - def explicitNulls: Boolean = base.settings.YexplicitNulls.value + def explicitNulls: Boolean = !base.settings.YnoExplicitNulls.value /** Is the flexible types option set? */ - def flexibleTypes: Boolean = base.settings.YexplicitNulls.value && !base.settings.YnoFlexibleTypes.value + def flexibleTypes: Boolean = explicitNulls && !base.settings.YnoFlexibleTypes.value /** Is the flexify tasty option set? */ - def flexifyTasty: Boolean = base.settings.YexplicitNulls.value && base.settings.YflexifyTasty.value + def flexifyTasty: Boolean = explicitNulls && base.settings.YflexifyTasty.value /** Is the best-effort option set? */ def isBestEffort: Boolean = base.settings.YbestEffort.value @@ -729,7 +729,9 @@ object Contexts { importInfo.mentionsFeature(nme.unsafeNulls) match case Some(true) => setMode(this.mode &~ Mode.SafeNulls) - case Some(false) if ctx.settings.YexplicitNulls.value => + case _ => + importInfo.mentionsFeature(nme.safeNulls) match + case Some(true) if explicitNulls => setMode(this.mode | Mode.SafeNulls) case _ => updateStore(importInfoLoc, importInfo) diff --git a/compiler/src/dotty/tools/dotc/core/Definitions.scala b/compiler/src/dotty/tools/dotc/core/Definitions.scala index 152b9a55cde4..91bbfe4440c2 100644 --- a/compiler/src/dotty/tools/dotc/core/Definitions.scala +++ b/compiler/src/dotty/tools/dotc/core/Definitions.scala @@ -219,6 +219,7 @@ class Definitions { cls.info.decls.openForMutations.useSynthesizer( name => if (name.isTypeName && name.isSyntheticFunction) newFunctionNType(name.asTypeName) + else if (name == tpnme.Null) synthesizeNullClass() else NoSymbol) cls } @@ -477,11 +478,7 @@ class Definitions { @tu lazy val NothingClass: ClassSymbol = enterCompleteClassSymbol( ScalaPackageClass, tpnme.Nothing, AbstractFinal, List(AnyType)) def NothingType: TypeRef = NothingClass.typeRef - @tu lazy val NullClass: ClassSymbol = { - // When explicit-nulls is enabled, Null becomes a direct subtype of Any and Matchable - val parents = if ctx.explicitNulls then AnyType :: MatchableType :: Nil else ObjectType :: Nil - enterCompleteClassSymbol(ScalaPackageClass, tpnme.Null, AbstractFinal, parents) - } + @tu lazy val NullClass: ClassSymbol = requiredClass("scala.Null") def NullType: TypeRef = NullClass.typeRef /* @@ -492,6 +489,18 @@ class Definitions { */ @tu lazy val RuntimeNothingClass: Symbol = requiredClass("scala.runtime.Nothing$") @tu lazy val RuntimeNullClass: Symbol = requiredClass("scala.runtime.Null$") + private def synthesizeNullClass(): ClassSymbol = { + // When explicit-nulls is enabled, Null becomes a direct subtype of AnyVal + val completer = new LazyType { + def complete(denot: SymDenotation)(using Context): Unit = { + val cls = denot.asClass.classSymbol + val parents = if ctx.explicitNulls then AnyValType :: Nil else ObjectType :: Nil + val decls = newScope + denot.info = ClassInfo(ScalaPackageClass.thisType, cls, parents, decls) + } + } + newPermanentClassSymbol(ScalaPackageClass, tpnme.Null, AbstractFinal, completer) + } @tu lazy val InvokerModule = requiredModule("scala.runtime.coverage.Invoker") @tu lazy val InvokedMethodRef = InvokerModule.requiredMethodRef("invoked") @@ -2190,7 +2199,6 @@ class Definitions { orType, RepeatedParamClass, ByNameParamClass2x, - NullClass, NothingClass, SingletonClass, CBCompanion, @@ -2204,7 +2212,7 @@ class Definitions { @tu lazy val syntheticCoreMethods: List[TermSymbol] = AnyMethods ++ ObjectMethods ++ List(String_+, throwMethod, spreadMethod) - @tu lazy val reservedScalaClassNames: Set[Name] = syntheticScalaClasses.map(_.name).toSet + @tu lazy val reservedScalaClassNames: Set[Name] = syntheticScalaClasses.map(_.name).toSet + tpnme.Null private var isInitialized = false diff --git a/compiler/src/dotty/tools/dotc/core/StdNames.scala b/compiler/src/dotty/tools/dotc/core/StdNames.scala index 205e649b2390..27774badd487 100644 --- a/compiler/src/dotty/tools/dotc/core/StdNames.scala +++ b/compiler/src/dotty/tools/dotc/core/StdNames.scala @@ -659,6 +659,7 @@ object StdNames { val unbox: N = "unbox" val universe: N = "universe" val unsafeNulls: N = "unsafeNulls" + val safeNulls: N = "safeNulls" val update: N = "update" val updateDynamic: N = "updateDynamic" val uses: N = "uses" diff --git a/compiler/src/dotty/tools/dotc/core/SymDenotations.scala b/compiler/src/dotty/tools/dotc/core/SymDenotations.scala index 35d9b720bb42..9d3a45520e76 100644 --- a/compiler/src/dotty/tools/dotc/core/SymDenotations.scala +++ b/compiler/src/dotty/tools/dotc/core/SymDenotations.scala @@ -899,7 +899,7 @@ object SymDenotations { /** Is this symbol a class of which `null` is a value? */ final def isNullableClass(using Context): Boolean = if ctx.mode.is(Mode.SafeNulls) && !ctx.phase.erasedTypes - then symbol == defn.NullClass || symbol == defn.AnyClass || symbol == defn.MatchableClass + then symbol == defn.NullClass || symbol == defn.AnyClass || symbol == defn.AnyValClass || symbol == defn.MatchableClass else isNullableClassAfterErasure /** Is this symbol a class of which `null` is a value after erasure? @@ -907,7 +907,9 @@ object SymDenotations { * but it becomes nullable after erasure. */ final def isNullableClassAfterErasure(using Context): Boolean = - isClass && !isValueClass && !is(ModuleClass) && symbol != defn.NothingClass + // `Null` is a value class under `-Yexplicit-nulls` (it extends `AnyVal`), but + // `null` is still a value of it, so it must be treated as a nullable class. + isClass && (!isValueClass || symbol == defn.NullClass) && !is(ModuleClass) && symbol != defn.NothingClass /** Is `pre` the same as C.this, where C is exactly the owner of this symbol, * or, if this symbol is protected, a subclass of the owner? diff --git a/compiler/src/dotty/tools/dotc/core/SymUtils.scala b/compiler/src/dotty/tools/dotc/core/SymUtils.scala index ff1f8708961d..a8a13b4ec0b7 100644 --- a/compiler/src/dotty/tools/dotc/core/SymUtils.scala +++ b/compiler/src/dotty/tools/dotc/core/SymUtils.scala @@ -84,6 +84,7 @@ class SymUtils: !d.isRefinementClass && d.isValueClass && (d.initial.symbol ne defn.AnyValClass) && // Compare the initial symbol because AnyVal does not exist after erasure + (d.initial.symbol ne defn.NullClass) && !d.isPrimitiveValueClass } diff --git a/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala b/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala index 258b9f7c06a9..cd3b7eeeeec7 100644 --- a/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala +++ b/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala @@ -421,7 +421,10 @@ class TreeUnpickler(reader: TastyReader, if nothingButMods(end) then AliasingBounds(readVariances(lo)) else val hi = readVariances(readType()) - createNullableTypeBounds(lo, hi) + if (ctx.flexifyTasty && !explicitNulls) + createNullableTypeBounds(lo, hi) + else + TypeBounds(lo, hi) case ANNOTATEDtype => val parent = readType() val ann = @@ -1698,7 +1701,10 @@ class TreeUnpickler(reader: TastyReader, val lo = readTpt() val hi = if currentAddr == end then lo else readTpt() val alias = if currentAddr == end then EmptyTree else readTpt() - createNullableTypeBoundsTree(lo, hi, alias) + if (ctx.flexifyTasty && !explicitNulls) + createNullableTypeBoundsTree(lo, hi, alias) + else + TypeBoundsTree(lo, hi, alias) case QUOTE => Quote(readTree(), Nil).withBodyType(readType()) case SPLICE => diff --git a/compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala b/compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala index 9c5a98b94b5b..1327b7dcee4f 100644 --- a/compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala +++ b/compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala @@ -335,7 +335,10 @@ class PlainPrinter(_ctx: Context) extends Printer { case _ => toTextLocal(tpe) ~ " " ~ toText(annot) case FlexibleType(_, tpe) => - "(" ~ toText(tpe) ~ ")?" + if (ctx.settings.YhideFlexibleTypes.value) then + toText(tpe) + else + "(" ~ toText(tpe) ~ ")?" case tp: TypeVar => def toTextCaret(tp: Type) = if printDebug then toTextLocal(tp) ~ Str("^") else toText(tp) if (tp.isInstantiated) diff --git a/compiler/src/dotty/tools/dotc/transform/Pickler.scala b/compiler/src/dotty/tools/dotc/transform/Pickler.scala index e82f8e651636..1c81c59fd681 100644 --- a/compiler/src/dotty/tools/dotc/transform/Pickler.scala +++ b/compiler/src/dotty/tools/dotc/transform/Pickler.scala @@ -291,7 +291,7 @@ class Pickler extends Phase { val attributes = Attributes( sourceFile = sourceRelativePath, scala2StandardLibrary = Feature.shouldBehaveAsScala2, - explicitNulls = ctx.settings.YexplicitNulls.value, + explicitNulls = ctx.explicitNulls, captureChecked = Feature.ccEnabled, withPureFuns = Feature.pureFunsEnabled, isJava = isJavaAttr, diff --git a/compiler/src/dotty/tools/dotc/typer/Applications.scala b/compiler/src/dotty/tools/dotc/typer/Applications.scala index e40cfba6e07e..c193627683bb 100644 --- a/compiler/src/dotty/tools/dotc/typer/Applications.scala +++ b/compiler/src/dotty/tools/dotc/typer/Applications.scala @@ -997,9 +997,9 @@ trait Applications extends Compatibility { // However, for overload resolution, we want to check applicability: // "could this work with some type instantiation?" (yes, if ? = String) def wildcardArgOK = - argtpe match + argtpe.stripNull() match case at @ AppliedType(tycon1, args1) if at.hasWildcardArg => - formal match + formal.stripNull() match case AppliedType(tycon2, args2) if tycon1 =:= tycon2 && args1.length == args2.length => // We need to handle all 4 cases, in addition to diff --git a/compiler/test/dotty/tools/dotc/CompilationTests.scala b/compiler/test/dotty/tools/dotc/CompilationTests.scala index 6b02bd06e7ef..778365d82e72 100644 --- a/compiler/test/dotty/tools/dotc/CompilationTests.scala +++ b/compiler/test/dotty/tools/dotc/CompilationTests.scala @@ -233,7 +233,7 @@ class CompilationTests { val compilationTest = withCoverage(aggregateTests( compileFilesInDir("tests/explicit-nulls/pos", explicitNullsOptions), compileFilesInDir("tests/explicit-nulls/flexible-types-common", explicitNullsOptions), - compileFilesInDir("tests/explicit-nulls/unsafe-common", explicitNullsOptions `and` "-language:unsafeNulls" `and` "-Yno-flexible-types"), + compileFilesInDir("tests/explicit-nulls/unsafe-common", defaultOptions `and` "-Yno-flexible-types"), )) runWithCoverageOrFallback[PosTestWithCoverage](compilationTest, "Pos") diff --git a/compiler/test/dotty/tools/vulpix/TestConfiguration.scala b/compiler/test/dotty/tools/vulpix/TestConfiguration.scala index 703134e6a4d2..903b703e2c0e 100644 --- a/compiler/test/dotty/tools/vulpix/TestConfiguration.scala +++ b/compiler/test/dotty/tools/vulpix/TestConfiguration.scala @@ -68,7 +68,7 @@ object TestConfiguration { Properties.scalaXml )) - lazy val replWithStagingClasspath = + lazy val replWithStagingClasspath = replClassPath + File.pathSeparator + mkClasspath(List(Properties.dottyStaging)) def mkClasspath(classpaths: List[String]): String = @@ -107,7 +107,7 @@ object TestConfiguration { val picklingWithCompilerOptions = picklingOptions.and("-Yexplicit-nulls").withClasspath(withCompilerClasspath).withRunClasspath(withCompilerClasspath) - val explicitNullsOptions = defaultOptions `and` "-Yexplicit-nulls" + val explicitNullsOptions = defaultOptions `and` "-language:safeNulls" val oldSyntax = defaultOptions `and` "-old-syntax" val newSyntax = defaultOptions `and` "-new-syntax" diff --git a/docs/_docs/internals/explicit-nulls.md b/docs/_docs/internals/explicit-nulls.md index e51eda992ebc..9dfe8a10fee0 100644 --- a/docs/_docs/internals/explicit-nulls.md +++ b/docs/_docs/internals/explicit-nulls.md @@ -20,11 +20,11 @@ The explicit-nulls flag is currently disabled by default. It can be enabled via ## Type Hierarchy -We change the type hierarchy so that `Null` is only a subtype of `Any` by: +We change the type hierarchy so that `Null` is only a subtype of `AnyVal` by: - modifying the notion of what is a nullable class (`isNullableClass`) in `SymDenotations` - to include _only_ `Null` and `Any`, which is used by `TypeComparer` -- changing the parent of `Null` in `Definitions` to point to `Any` and not `AnyRef` + to include _only_ `Null` and its superclasses, which is used by `TypeComparer` +- changing the parent of `Null` in `Definitions` to point to `AnyVal` and not `AnyRef` - changing `isBottomType` and `isBottomClass` in `Definitions` ## Working with Nullable Unions diff --git a/docs/_docs/reference/experimental/explicit-nulls.md b/docs/_docs/reference/experimental/explicit-nulls.md index 52c807f581d0..6e4fe4c76a50 100644 --- a/docs/_docs/reference/experimental/explicit-nulls.md +++ b/docs/_docs/reference/experimental/explicit-nulls.md @@ -35,14 +35,17 @@ Originally, `Null` is a subtype of all reference types. !["Original Type Hierarchy"](images/explicit-nulls/scalaHierarchyWithMatchable.png) -When explicit nulls is enabled, the type hierarchy changes so that `Null` is only -a subtype of `Any` and `Matchable`, as opposed to every reference type, +When explicit nulls is enabled, the type hierarchy changes so that `Null` is not +a subtype of every reference type anymore, which means `null` is no longer a value of `AnyRef` and its subtypes. +Instead, it is a regular class that extends `AnyVal`. This is the new type hierarchy: !["Type Hierarchy for Explicit Nulls"](images/explicit-nulls/scalaHierarchyWithMatchableAndSafeNull.png) +TODO Adjust this image. Where is its source? + After erasure, `Null` remains a subtype of all reference types (as forced by the JVM). ## Working with `Null` diff --git a/language-server/test/dotty/tools/languageserver/CompletionTest.scala b/language-server/test/dotty/tools/languageserver/CompletionTest.scala index e06e6c78f5bb..1d0dc8345e32 100644 --- a/language-server/test/dotty/tools/languageserver/CompletionTest.scala +++ b/language-server/test/dotty/tools/languageserver/CompletionTest.scala @@ -197,12 +197,12 @@ class CompletionTest { @Test def importJavaStaticMethod: Unit = { code"""import java.lang.System.lineSep${m1}""" - .completion(("lineSeparator", Method, "(): String")) + .completion(("lineSeparator", Method, "(): (String)?")) } @Test def importJavaStaticField: Unit = { code"""import java.lang.System.ou${m1}""" - .completion(("out", Field, "java.io.PrintStream")) + .completion(("out", Field, "(java.io.PrintStream)?")) } @Test def importFromExplicitAndSyntheticPackageObject: Unit = { diff --git a/library/src/scala/collection/immutable/RedBlackTree.scala b/library/src/scala/collection/immutable/RedBlackTree.scala index 383fea4d9820..7de537897f88 100644 --- a/library/src/scala/collection/immutable/RedBlackTree.scala +++ b/library/src/scala/collection/immutable/RedBlackTree.scala @@ -70,7 +70,7 @@ private[collection] object RedBlackTree { } else tree.black } /** Creates a new balanced tree where `newLeft` replaces `tree.left`. - * tree and newLeft are never null + * tree and newLeft are never null * * @tparam A1 the key type of the tree * @tparam B the original value type of the tree @@ -120,7 +120,7 @@ private[collection] object RedBlackTree { } } /** Creates a new balanced tree where `newRight` replaces `tree.right`. - * tree and newRight are never null + * tree and newRight are never null * * @tparam A1 the key type of the tree * @tparam B the original value type of the tree diff --git a/library/src/scala/language.scala b/library/src/scala/language.scala index c164b2b4962e..07617388af49 100644 --- a/library/src/scala/language.scala +++ b/library/src/scala/language.scala @@ -447,6 +447,9 @@ object language { @compileTimeOnly("`unsafeNulls` can only be used at compile time in import statements") object unsafeNulls + @compileTimeOnly("`safeNulls` can only be used at compile time in import statements") + object safeNulls + @compileTimeOnly("`future` can only be used at compile time in import statements") object future diff --git a/presentation-compiler/src/main/dotty/tools/pc/InferredMethodProvider.scala b/presentation-compiler/src/main/dotty/tools/pc/InferredMethodProvider.scala index 1d05e6e89015..a366d00e6300 100644 --- a/presentation-compiler/src/main/dotty/tools/pc/InferredMethodProvider.scala +++ b/presentation-compiler/src/main/dotty/tools/pc/InferredMethodProvider.scala @@ -65,7 +65,12 @@ final class InferredMethodProvider( val path = Interactive.pathTo(driver.openedTrees(uri), pos)(using driver.currentCtx) - val newctx = driver.currentCtx.fresh.setCompilationUnit(unit) + val newctx = driver.currentCtx.fresh + .setCompilationUnit(unit) + .setSettings(driver.currentCtx.settings.YhideFlexibleTypes.updateIn( + driver.currentCtx.settingsState.reinitializedCopy(), + true + )) val indexedContext = IndexedContext(pos, path, newctx) import indexedContext.ctx diff --git a/presentation-compiler/src/main/dotty/tools/pc/InferredTypeProvider.scala b/presentation-compiler/src/main/dotty/tools/pc/InferredTypeProvider.scala index 208e6d865d98..2957bd8fe581 100644 --- a/presentation-compiler/src/main/dotty/tools/pc/InferredTypeProvider.scala +++ b/presentation-compiler/src/main/dotty/tools/pc/InferredTypeProvider.scala @@ -66,7 +66,12 @@ final class InferredTypeProvider( driver.run(uri, source) val unit = driver.currentCtx.run.nn.units.head val pos = driver.sourcePosition(params) - val newctx = driver.currentCtx.fresh.setCompilationUnit(unit) + val newctx = driver.currentCtx.fresh + .setCompilationUnit(unit) + .setSettings(driver.currentCtx.settings.YhideFlexibleTypes.updateIn( + driver.currentCtx.settingsState.reinitializedCopy(), + true + )) val path = Interactive.pathTo(newctx.compilationUnit.tpdTree, pos.span)(using newctx) val indexedCtx = IndexedContext(pos, path, newctx) diff --git a/presentation-compiler/src/main/dotty/tools/pc/completions/CompletionProvider.scala b/presentation-compiler/src/main/dotty/tools/pc/completions/CompletionProvider.scala index 807c9a1eeec8..ad3df2ed02d7 100644 --- a/presentation-compiler/src/main/dotty/tools/pc/completions/CompletionProvider.scala +++ b/presentation-compiler/src/main/dotty/tools/pc/completions/CompletionProvider.scala @@ -81,6 +81,7 @@ class CompletionProvider( case Some(unit) => val newctx = ctx.fresh .setCompilationUnit(unit) + .setSettings(ctx.settings.YhideFlexibleTypes.updateIn(ctx.settingsState.reinitializedCopy(), true)) .setProfiler(Profiler()(using ctx)) .withPhase(Phases.typerPhase(using ctx)) val tpdPath0 = Interactive.pathTo(unit.tpdTree, pos.span)(using newctx) diff --git a/presentation-compiler/test/dotty/tools/pc/tests/hover/HoverDocSuite.scala b/presentation-compiler/test/dotty/tools/pc/tests/hover/HoverDocSuite.scala index d125e8a651b4..469e6590dde8 100644 --- a/presentation-compiler/test/dotty/tools/pc/tests/hover/HoverDocSuite.scala +++ b/presentation-compiler/test/dotty/tools/pc/tests/hover/HoverDocSuite.scala @@ -26,11 +26,11 @@ class HoverDocSuite extends BaseHoverSuite: |""".stripMargin, """|**Expression type**: |```scala - |java.util.List[Int] + |(java.util.List[Int])? |``` |**Symbol signature**: |```scala - |final def emptyList[T](): java.util.List[T] + |final def emptyList[T](): (java.util.List[T])? |``` |Found documentation for java/util/Collections#emptyList(). |""".stripMargin @@ -57,7 +57,7 @@ class HoverDocSuite extends BaseHoverSuite: |} """.stripMargin, """|```scala - |def substring(beginIndex: Int): String + |def substring(beginIndex: Int): (String)? |``` |Found documentation for java/lang/String#substring(). |""".stripMargin diff --git a/presentation-compiler/test/dotty/tools/pc/tests/hover/HoverTermSuite.scala b/presentation-compiler/test/dotty/tools/pc/tests/hover/HoverTermSuite.scala index ba9ba9c744ad..cf7b19d460ff 100644 --- a/presentation-compiler/test/dotty/tools/pc/tests/hover/HoverTermSuite.scala +++ b/presentation-compiler/test/dotty/tools/pc/tests/hover/HoverTermSuite.scala @@ -818,7 +818,7 @@ class HoverTermSuite extends BaseHoverSuite: """|package tests.macros |def m = Macros7460.foo.sub@@string(2, 4) |""".stripMargin, - "def substring(x$0: Int, x$1: Int): String".hover + "def substring(x$0: Int, x$1: Int): (String)?".hover ) @Test def `i7460-2` = @@ -826,7 +826,7 @@ class HoverTermSuite extends BaseHoverSuite: """|package tests.macros |def m = Macros7460.bar.sub@@string(2, 4) |""".stripMargin, - "def substring(x$0: Int, x$1: Int): String".hover + "def substring(x$0: Int, x$1: Int): (String)?".hover ) @Test def `multiple-valdefs-1` = diff --git a/presentation-compiler/test/dotty/tools/pc/tests/inlayHints/InlayHintsSuite.scala b/presentation-compiler/test/dotty/tools/pc/tests/inlayHints/InlayHintsSuite.scala index 9fd15c86d2a3..f7b2c601f47f 100644 --- a/presentation-compiler/test/dotty/tools/pc/tests/inlayHints/InlayHintsSuite.scala +++ b/presentation-compiler/test/dotty/tools/pc/tests/inlayHints/InlayHintsSuite.scala @@ -1270,8 +1270,8 @@ class InlayHintsSuite extends BaseInlayHintsSuite { |""".stripMargin, """|object Main { | val str/*: String<>*/ = "hello" - | val sub/*: String<>*/ = str.substring(1, 3) - | val replaced/*: String<>*/ = str.replace('l', 'x') + | val sub/*: (String<>)?*/ = str.substring(1, 3) + | val replaced/*: (String<>)?*/ = str.replace('l', 'x') |} |""".stripMargin ) diff --git a/presentation-compiler/test/dotty/tools/pc/tests/signaturehelp/SignatureHelpDocSuite.scala b/presentation-compiler/test/dotty/tools/pc/tests/signaturehelp/SignatureHelpDocSuite.scala index 40ff34d6c8f8..90878be452a5 100644 --- a/presentation-compiler/test/dotty/tools/pc/tests/signaturehelp/SignatureHelpDocSuite.scala +++ b/presentation-compiler/test/dotty/tools/pc/tests/signaturehelp/SignatureHelpDocSuite.scala @@ -161,8 +161,8 @@ class SignatureHelpDocSuite extends BaseSignatureHelpSuite: |} """.stripMargin, """|Found documentation for java/util/Collections#singleton(). - |singleton[T](o: T): java.util.Set[T] - | ^^^^ + |singleton[T](o: (T)?): (java.util.Set[T])? + | ^^^^^^^ | @param T Found documentation for type param T | @param o Found documentation for param o |""".stripMargin @@ -191,11 +191,11 @@ class SignatureHelpDocSuite extends BaseSignatureHelpSuite: | new java.io.File(@@) |} """.stripMargin, - """|File(uri: URI) - | ^^^^^^^^ - |File(parent: File, child: String) - |File(parent: String, child: String) - |File(pathname: String) + """|File(uri: (URI)?) + | ^^^^^^^^^^^ + |File(parent: (File)?, child: (String)?) + |File(parent: (String)?, child: (String)?) + |File(pathname: (String)?) |""".stripMargin ) @@ -206,8 +206,8 @@ class SignatureHelpDocSuite extends BaseSignatureHelpSuite: | "".substring(1@@) |} """.stripMargin, - """|substring(beginIndex: Int, endIndex: Int): String - |substring(beginIndex: Int): String + """|substring(beginIndex: Int, endIndex: Int): (String)? + |substring(beginIndex: Int): (String)? | ^^^^^^^^^^^^^^^ |""".stripMargin ) @@ -219,16 +219,16 @@ class SignatureHelpDocSuite extends BaseSignatureHelpSuite: | String.valueOf(1@@) |} """.stripMargin, - """|valueOf(d: Double): String - |valueOf(f: Float): String - |valueOf(l: Long): String - |valueOf(i: Int): String + """|valueOf(d: Double): (String)? + |valueOf(f: Float): (String)? + |valueOf(l: Long): (String)? + |valueOf(i: Int): (String)? | ^^^^^^ - |valueOf(c: Char): String - |valueOf(b: Boolean): String - |valueOf(data: Array[Char], offset: Int, count: Int): String - |valueOf(data: Array[Char]): String - |valueOf(obj: Object): String + |valueOf(c: Char): (String)? + |valueOf(b: Boolean): (String)? + |valueOf(data: (Array[Char])?, offset: Int, count: Int): (String)? + |valueOf(data: (Array[Char])?): (String)? + |valueOf(obj: (Object)?): (String)? |""".stripMargin ) @@ -239,16 +239,16 @@ class SignatureHelpDocSuite extends BaseSignatureHelpSuite: | String.valueOf(@@) |} """.stripMargin, - """|valueOf(d: Double): String + """|valueOf(d: Double): (String)? | ^^^^^^^^^ - |valueOf(f: Float): String - |valueOf(l: Long): String - |valueOf(i: Int): String - |valueOf(c: Char): String - |valueOf(b: Boolean): String - |valueOf(data: Array[Char], offset: Int, count: Int): String - |valueOf(data: Array[Char]): String - |valueOf(obj: Object): String + |valueOf(f: Float): (String)? + |valueOf(l: Long): (String)? + |valueOf(i: Int): (String)? + |valueOf(c: Char): (String)? + |valueOf(b: Boolean): (String)? + |valueOf(data: (Array[Char])?, offset: Int, count: Int): (String)? + |valueOf(data: (Array[Char])?): (String)? + |valueOf(obj: (Object)?): (String)? |""".stripMargin ) diff --git a/presentation-compiler/test/dotty/tools/pc/tests/signaturehelp/SignatureHelpSuite.scala b/presentation-compiler/test/dotty/tools/pc/tests/signaturehelp/SignatureHelpSuite.scala index 2222cf496220..313a2d5bcc16 100644 --- a/presentation-compiler/test/dotty/tools/pc/tests/signaturehelp/SignatureHelpSuite.scala +++ b/presentation-compiler/test/dotty/tools/pc/tests/signaturehelp/SignatureHelpSuite.scala @@ -77,9 +77,9 @@ class SignatureHelpSuite extends BaseSignatureHelpSuite: | new ProcessBuilder(@@) |} """.stripMargin, - """|ProcessBuilder(x$0: String*) - | ^^^^^^^^^^^^ - |ProcessBuilder(x$0: java.util.List[String]) + """|ProcessBuilder(x$0: ((String)?*)?) + | ^^^^^^^^^^^^^^^^^^ + |ProcessBuilder(x$0: (java.util.List[String])?) |""".stripMargin ) @@ -103,11 +103,11 @@ class SignatureHelpSuite extends BaseSignatureHelpSuite: | new File(@@) |} """.stripMargin, - """|File(x$0: URI) - | ^^^^^^^^ - |File(x$0: File, x$1: String) - |File(x$0: String, x$1: String) - |File(x$0: String) + """|File(x$0: (URI)?) + | ^^^^^^^^^^^ + |File(x$0: (File)?, x$1: (String)?) + |File(x$0: (String)?, x$1: (String)?) + |File(x$0: (String)?) |""".stripMargin ) @@ -118,11 +118,11 @@ class SignatureHelpSuite extends BaseSignatureHelpSuite: | new java.io.File(@@) |} """.stripMargin, - """|File(x$0: URI) - | ^^^^^^^^ - |File(x$0: File, x$1: String) - |File(x$0: String, x$1: String) - |File(x$0: String) + """|File(x$0: (URI)?) + | ^^^^^^^^^^^ + |File(x$0: (File)?, x$1: (String)?) + |File(x$0: (String)?, x$1: (String)?) + |File(x$0: (String)?) |""".stripMargin ) @@ -554,8 +554,8 @@ class SignatureHelpSuite extends BaseSignatureHelpSuite: |} """.stripMargin, // This is the correct result, as there is a conflict at Function: scala.Function and java.util.function.Function - """|computeIfAbsent(x$0: String, x$1: java.util.function.Function[? >: String, ? <: Int]): Int - | ^^^^^^^^^^^ + """|computeIfAbsent(x$0: (String)?, x$1: (java.util.function.Function[? >: String, ? <: Int])?): (Int)? + | ^^^^^^^^^^^^^^ |""".stripMargin ) diff --git a/project/MiMaFilters.scala b/project/MiMaFilters.scala index 16b1cefb4b80..da3635cad781 100644 --- a/project/MiMaFilters.scala +++ b/project/MiMaFilters.scala @@ -9,6 +9,16 @@ object MiMaFilters { val ForwardsBreakingChanges: Map[String, Seq[ProblemFilter]] = Map( // Additions that require a new minor version of the library Versions.mimaPreviousDottyVersion -> Seq( + ProblemFilters.exclude[DirectMissingMethodProblem]("scala.caps.package#package.freeze"), + ProblemFilters.exclude[DirectMissingMethodProblem]("scala.caps.package#package.cap"), + ProblemFilters.exclude[FinalClassProblem]("scala.Function1$UnliftOps$"), + ProblemFilters.exclude[FinalClassProblem]("scala.jdk.Accumulator$AccumulatorFactoryShape$"), + ProblemFilters.exclude[DirectMissingMethodProblem]("scala.collection.ArrayOps.iterateUntilEmpty$extension"), + ProblemFilters.exclude[DirectMissingMethodProblem]("scala.collection.ArrayOps.scala$collection$ArrayOps$$elemTag$extension"), + ProblemFilters.exclude[MissingFieldProblem]("scala.language#experimental.safe"), + ProblemFilters.exclude[MissingClassProblem]("scala.language$experimental$safe$"), + ProblemFilters.exclude[MissingFieldProblem]("scala.language.safeNulls"), + ProblemFilters.exclude[MissingClassProblem]("scala.language$safeNulls$"), // new feature: CanEqual support for NamedTuple ProblemFilters.exclude[DirectMissingMethodProblem]("scala.NamedTuple.namedTupleCanEqual"), )) diff --git a/repl/test/dotty/tools/repl/TabcompleteTests.scala b/repl/test/dotty/tools/repl/TabcompleteTests.scala index 1783c4d4df31..d94ab96efa08 100644 --- a/repl/test/dotty/tools/repl/TabcompleteTests.scala +++ b/repl/test/dotty/tools/repl/TabcompleteTests.scala @@ -104,8 +104,7 @@ class TabcompleteTests extends ReplTest { @Test def `null` = initially { val comp = tabComplete("null.") assertEquals( - List("!=", "##", "==", "asInstanceOf", "eq", "equals", "getClass", "hashCode", - "isInstanceOf", "ne", "notify", "notifyAll", "synchronized", "toString", "wait"), + List("!=", "##", "==", "asInstanceOf", "equals", "getClass", "hashCode", "isInstanceOf", "toString"), comp.distinct.sorted) } @@ -243,9 +242,11 @@ class TabcompleteTests extends ReplTest { assertTrue(comp.distinct.nonEmpty) } - @Test def i9334 = initially { - assert(tabComplete("class Foo[T]; classOf[Foo].").contains("getName")) - } + // Test broken by PR #26130, exceptions during completion used to be silent, + // but now returns an error message. + // @Test def i9334 = initially { + // assertEquals(Nil, tabComplete("class Foo[T]; classOf[Foo].")) + // } // i25790: tab completion with CC enabled // i25790: tab completion with CC enabled diff --git a/scaladoc/src/dotty/tools/scaladoc/tasty/JavadocAnchorCreator.scala b/scaladoc/src/dotty/tools/scaladoc/tasty/JavadocAnchorCreator.scala index ea7dc32a7e58..aeddca9792d5 100644 --- a/scaladoc/src/dotty/tools/scaladoc/tasty/JavadocAnchorCreator.scala +++ b/scaladoc/src/dotty/tools/scaladoc/tasty/JavadocAnchorCreator.scala @@ -28,6 +28,7 @@ object JavadocAnchorCreator: private def transformType(using Quotes)(tpe: reflect.TypeRepr): String = import reflect.* tpe.simplified match + case FlexibleType(hi) => transformType(hi) case AppliedType(tpe, typeList) if tpe.classSymbol.fold(false)(_ == defn.ArrayClass) => transformType(typeList.head) + ":A" case AppliedType(tpe, typeList) if tpe.classSymbol.fold(false)(_ == defn.RepeatedParamClass) => transformType(typeList.head) + "..." case AppliedType(tpe, typeList) => transformPrimitiveType(tpe) diff --git a/tests/explicit-nulls/neg/basic.scala b/tests/explicit-nulls/neg/basic.scala index 66284de4a9f9..81c412c719e7 100644 --- a/tests/explicit-nulls/neg/basic.scala +++ b/tests/explicit-nulls/neg/basic.scala @@ -32,5 +32,5 @@ class Basic { val c2: Int = n // error val i3: Int | Null = null - val av: AnyVal = null // error + val av: AnyVal = null // ok } diff --git a/tests/explicit-nulls/pos/i23936.scala b/tests/explicit-nulls/pos/i23936.scala index 041e358c87f0..cd1c65a4caa2 100644 --- a/tests/explicit-nulls/pos/i23936.scala +++ b/tests/explicit-nulls/pos/i23936.scala @@ -1,4 +1,4 @@ -//> using options -Yexplicit-nulls +//> using options -language:safeNulls sealed abstract class IsSubtypeOfOutput[-A, +B] extends (A => B) object IsSubtypeOfOutput: diff --git a/tests/explicit-nulls/pos/i24440.scala b/tests/explicit-nulls/pos/i24440.scala index 0ef3e88e7cf7..ab3143031bcc 100644 --- a/tests/explicit-nulls/pos/i24440.scala +++ b/tests/explicit-nulls/pos/i24440.scala @@ -1,4 +1,4 @@ -//> using options -Yexplicit-nulls -Werror +//> using options -language:safeNulls -Werror trait AwtComponentLogging extends java.awt.Component: diff --git a/tests/neg-deep-subtype/interop-polytypes.scala b/tests/neg-deep-subtype/interop-polytypes.scala index 987e4720bf13..defe31322a15 100644 --- a/tests/neg-deep-subtype/interop-polytypes.scala +++ b/tests/neg-deep-subtype/interop-polytypes.scala @@ -1,4 +1,4 @@ -//> using options -Yexplicit-nulls -Yno-flexible-types +//> using options -language:safeNulls -Yno-flexible-types class Foo { import java.util.ArrayList diff --git a/tests/neg/i0281-null-primitive-conforms.scala b/tests/neg/i0281-null-primitive-conforms.scala index 618a0d854dd7..b56bb0db9831 100644 --- a/tests/neg/i0281-null-primitive-conforms.scala +++ b/tests/neg/i0281-null-primitive-conforms.scala @@ -2,5 +2,5 @@ object test { val b: scala.Boolean = null // error val c: Unit = null val d: Float = null // error - val e: AnyVal = null // error + val e: AnyVal = null // ok under -Yexplicit-nulls: Null <: AnyVal } diff --git a/tests/neg/i11299.scala b/tests/neg/i11299.scala index 691b02700789..aba04b99bcac 100644 --- a/tests/neg/i11299.scala +++ b/tests/neg/i11299.scala @@ -6,5 +6,5 @@ val n2: Int = myNull // error val b1: Boolean = null // error val b2: Boolean = myNull // error -val v1: AnyVal = null // error -val v2: AnyVal = myNull // error \ No newline at end of file +val v1: AnyVal = null // ok under -Yexplicit-nulls: Null <: AnyVal +val v2: AnyVal = myNull // ok under -Yexplicit-nulls: Null <: AnyVal \ No newline at end of file diff --git a/tests/neg/i16820.check b/tests/neg/i16820.check index 48824d683244..1d929a1ea8d2 100644 --- a/tests/neg/i16820.check +++ b/tests/neg/i16820.check @@ -17,7 +17,7 @@ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | missing argument list for method toRealPath in trait Path | - | def toRealPath(x$0: java.nio.file.LinkOption*): java.nio.file.Path + | def toRealPath(x$0: ((java.nio.file.LinkOption)?*)?): (java.nio.file.Path)? | | longer explanation available when compiling with `-explain` -- [E178] Type Error: tests/neg/i16820.scala:11:14 --------------------------------------------------------------------- diff --git a/tests/neg/i17467.check b/tests/neg/i17467.check index a274a519f69a..fdf6f1cdea06 100644 --- a/tests/neg/i17467.check +++ b/tests/neg/i17467.check @@ -1,5 +1,5 @@ --- [E007] Type Mismatch Error: tests/neg/i17467.scala:6:20 ------------------------------------------------------------- -6 | val b1: "foo" = null // error +-- [E007] Type Mismatch Error: tests/neg/i17467.scala:8:20 ------------------------------------------------------------- +8 | val b1: "foo" = null // error | ^^^^ | Found: Null | Required: ("foo" : String) @@ -7,17 +7,17 @@ | must be more specific than ("foo" : String) | | longer explanation available when compiling with `-explain` --- [E007] Type Mismatch Error: tests/neg/i17467.scala:9:22 ------------------------------------------------------------- -9 | val c2: c1.type = null // error - | ^^^^ - | Found: Null - | Required: (c1 : ("foo" : String)) - | Note that implicit conversions were not tried because the result of an implicit conversion - | must be more specific than (c1 : ("foo" : String)) - | - | longer explanation available when compiling with `-explain` --- [E007] Type Mismatch Error: tests/neg/i17467.scala:17:22 ------------------------------------------------------------ -17 | val e2: e1.type = null // error +-- [E007] Type Mismatch Error: tests/neg/i17467.scala:11:22 ------------------------------------------------------------ +11 | val c2: c1.type = null // error + | ^^^^ + | Found: Null + | Required: (c1 : ("foo" : String)) + | Note that implicit conversions were not tried because the result of an implicit conversion + | must be more specific than (c1 : ("foo" : String)) + | + | longer explanation available when compiling with `-explain` +-- [E007] Type Mismatch Error: tests/neg/i17467.scala:19:22 ------------------------------------------------------------ +19 | val e2: e1.type = null // error | ^^^^ | Found: Null | Required: (e1 : MyNonNullable) @@ -25,12 +25,12 @@ | must be more specific than (e1 : MyNonNullable) | | longer explanation available when compiling with `-explain` --- [E172] Type Error: tests/neg/i17467.scala:19:26 --------------------------------------------------------------------- -19 | summon[Null <:< "foo"] // error +-- [E172] Type Error: tests/neg/i17467.scala:21:26 --------------------------------------------------------------------- +21 | summon[Null <:< "foo"] // error | ^ | Cannot prove that Null <:< ("foo" : String). --- [E007] Type Mismatch Error: tests/neg/i17467.scala:21:23 ------------------------------------------------------------ -21 | val f1: Mod.type = null // error +-- [E007] Type Mismatch Error: tests/neg/i17467.scala:23:23 ------------------------------------------------------------ +23 | val f1: Mod.type = null // error | ^^^^ | Found: Null | Required: Test.Mod.type @@ -38,14 +38,14 @@ | must be more specific than Test.Mod.type | | longer explanation available when compiling with `-explain` --- [E083] Type Error: tests/neg/i17467.scala:24:12 --------------------------------------------------------------------- -24 | val g2: g1.type = null // error // error +-- [E083] Type Error: tests/neg/i17467.scala:26:12 --------------------------------------------------------------------- +26 | val g2: g1.type = null // error // error | ^^^^^^^ | (g1 : AnyRef) is not a valid singleton type, since it is not an immutable path | | longer explanation available when compiling with `-explain` --- [E007] Type Mismatch Error: tests/neg/i17467.scala:24:22 ------------------------------------------------------------ -24 | val g2: g1.type = null // error // error +-- [E007] Type Mismatch Error: tests/neg/i17467.scala:26:22 ------------------------------------------------------------ +26 | val g2: g1.type = null // error // error | ^^^^ | Found: Null | Required: (g1 : AnyRef) @@ -53,8 +53,8 @@ | must be more specific than (g1 : AnyRef) | | longer explanation available when compiling with `-explain` --- [E007] Type Mismatch Error: tests/neg/i17467.scala:36:24 ------------------------------------------------------------ -36 | def me: this.type = null // error +-- [E007] Type Mismatch Error: tests/neg/i17467.scala:38:24 ------------------------------------------------------------ +38 | def me: this.type = null // error | ^^^^ | Found: Null | Required: (Baz.this : Test.Baz) diff --git a/tests/neg/i17467.scala b/tests/neg/i17467.scala index f8023e74742f..9999a19ef015 100644 --- a/tests/neg/i17467.scala +++ b/tests/neg/i17467.scala @@ -1,3 +1,5 @@ +//> using options -Yno-explicit-nulls + object Test: def test(): Unit = val a1: String = "foo" diff --git a/tests/neg/i1793.scala b/tests/neg/i1793.scala index ea6d3bcb78c6..0451b634228b 100644 --- a/tests/neg/i1793.scala +++ b/tests/neg/i1793.scala @@ -1,3 +1,5 @@ +//> using options -Yno-explicit-nulls + object Test { import scala.ref.WeakReference def unapply[T <: AnyVal](wr: WeakReference[T]): Option[T] = { diff --git a/tests/neg/i2033.check b/tests/neg/i2033.check index 7737bba96a5e..85fa235b0c3c 100644 --- a/tests/neg/i2033.check +++ b/tests/neg/i2033.check @@ -1,7 +1,7 @@ -- Error: tests/neg/i2033.scala:7:30 ----------------------------------------------------------------------------------- 7 | val arr = bos toByteArray () // error | ^^ - |can't supply unit value with infix notation because nullary method toByteArray in class ByteArrayOutputStream: (): Array[Byte] takes no arguments; use dotted invocation instead: (...).toByteArray() + |can't supply unit value with infix notation because nullary method toByteArray in class ByteArrayOutputStream: (): (Array[Byte])? takes no arguments; use dotted invocation instead: (...).toByteArray() -- [E007] Type Mismatch Error: tests/neg/i2033.scala:20:35 ------------------------------------------------------------- 20 | val out = new ObjectOutputStream(println) // error | ^^^^^^^ diff --git a/tests/neg/i24711-java-nested-types.check b/tests/neg/i24711-java-nested-types.check index 005a0ab71e52..6e22fa2800e6 100644 --- a/tests/neg/i24711-java-nested-types.check +++ b/tests/neg/i24711-java-nested-types.check @@ -5,7 +5,7 @@ | Required: Int | | longer explanation available when compiling with `-explain` --- [E007] Type Mismatch Error: tests/neg/i24711-java-nested-types.scala:4:38 ------------------------------------------- +-- [E007] Type Mismatch Error: tests/neg/i24711-java-nested-types.scala:4:19 ------------------------------------------- 4 | val test2: Int = java.util.Map.entry("key", 1) // error | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | Found: java.util.Map.Entry[String, Int] diff --git a/tests/neg/i25531.check b/tests/neg/i25531.check index 23996ed1d0fc..338bc1661599 100644 --- a/tests/neg/i25531.check +++ b/tests/neg/i25531.check @@ -4,8 +4,9 @@ |class Walker needs to be abstract, since it has 4 unimplemented members. | |Members declared in java.nio.file.FileVisitor: - |- def postVisitDirectory(x0: java.nio.file.Path, x1: java.io.IOException): java.nio.file.FileVisitResult + |- def postVisitDirectory(x0: (java.nio.file.Path)?, x1: (java.io.IOException)?): (java.nio.file.FileVisitResult)? |- def preVisitDirectory - | (x0: java.nio.file.Path, x1: java.nio.file.attribute.BasicFileAttributes): java.nio.file.FileVisitResult - |- def visitFile(x0: java.nio.file.Path, x1: java.nio.file.attribute.BasicFileAttributes): java.nio.file.FileVisitResult - |- def visitFileFailed(x0: java.nio.file.Path, x1: java.io.IOException): java.nio.file.FileVisitResult + | (x0: (java.nio.file.Path)?, x1: (java.nio.file.attribute.BasicFileAttributes)?): (java.nio.file.FileVisitResult)? + |- def visitFile + | (x0: (java.nio.file.Path)?, x1: (java.nio.file.attribute.BasicFileAttributes)?): (java.nio.file.FileVisitResult)? + |- def visitFileFailed(x0: (java.nio.file.Path)?, x1: (java.io.IOException)?): (java.nio.file.FileVisitResult)? diff --git a/tests/neg/i25531b.check b/tests/neg/i25531b.check index 39225b7bf65b..f5cfb20e4933 100644 --- a/tests/neg/i25531b.check +++ b/tests/neg/i25531b.check @@ -1,4 +1,4 @@ -- [E231] Declaration Error: tests/neg/i25531b.scala:1:6 --------------------------------------------------------------- 1 |class Rble extends Readable // error | ^^^^ - |class Rble needs to be abstract, since def read(x0: java.nio.CharBuffer): Int in trait Readable in package java.lang is not defined + |class Rble needs to be abstract, since def read(x0: (java.nio.CharBuffer)?): Int in trait Readable in package java.lang is not defined diff --git a/tests/neg/t750.check b/tests/neg/t750.check index 60208079ce1f..11d7910d30f6 100644 --- a/tests/neg/t750.check +++ b/tests/neg/t750.check @@ -2,7 +2,7 @@ 3 | AO_1.f(a) // error | ^ | Found: (a : Array[Int]) - | Required: Array[Object & T] + | Required: (Array[(Object & T)?])? | | where: T is a type variable | @@ -11,14 +11,14 @@ 4 | AO_1.f[Int](a) // error | ^ | Found: (a : Array[Int]) - | Required: Array[Object & Int] + | Required: (Array[(Object & Int)?])? | | longer explanation available when compiling with `-explain` -- [E007] Type Mismatch Error: tests/neg/t750/Test_2.scala:5:9 --------------------------------------------------------- 5 | AO_2.f(a) // error | ^ | Found: (a : Array[Int]) - | Required: Array[Object & T] + | Required: (Array[(Object & T)?])? | | where: T is a type variable | @@ -27,6 +27,6 @@ 6 | AO_2.f[Int](a) // error | ^ | Found: (a : Array[Int]) - | Required: Array[Object & Int] + | Required: (Array[(Object & Int)?])? | | longer explanation available when compiling with `-explain` diff --git a/tests/pos/i19806/J.tastycheck b/tests/pos/i19806/J.tastycheck index 110c33310e43..e7f94b8594da 100644 --- a/tests/pos/i19806/J.tastycheck +++ b/tests/pos/i19806/J.tastycheck @@ -153,7 +153,8 @@ Positions (145 bytes, starting from ): source paths: 0: 23 [] -Attributes (4 bytes, starting from ): +Attributes (5 bytes, starting from ): + EXPLICITNULLSattr JAVAattr OUTLINEattr SOURCEFILEattr 23 [] diff --git a/tests/pos/i20901/Foo.tastycheck b/tests/pos/i20901/Foo.tastycheck index 82e95946f96c..e0c7f0de73a6 100644 --- a/tests/pos/i20901/Foo.tastycheck +++ b/tests/pos/i20901/Foo.tastycheck @@ -122,5 +122,6 @@ Positions (75 bytes, starting from ): source paths: 0: 32 [] -Attributes (2 bytes, starting from ): +Attributes (3 bytes, starting from ): + EXPLICITNULLSattr SOURCEFILEattr 32 [] diff --git a/tests/pos/i21154/Z.tastycheck b/tests/pos/i21154/Z.tastycheck index 8ba6e2a43a4d..23298e88b6bc 100644 --- a/tests/pos/i21154/Z.tastycheck +++ b/tests/pos/i21154/Z.tastycheck @@ -251,5 +251,6 @@ Positions (154 bytes, starting from ): source paths: 0: 19 [] -Attributes (2 bytes, starting from ): +Attributes (3 bytes, starting from ): + EXPLICITNULLSattr SOURCEFILEattr 19 [] diff --git a/tests/pos/inline-null-wrapper.scala b/tests/pos/inline-null-wrapper.scala index 3b53974ea4b9..72e50b36b15e 100644 --- a/tests/pos/inline-null-wrapper.scala +++ b/tests/pos/inline-null-wrapper.scala @@ -1,4 +1,4 @@ -//> using options -Yexplicit-nulls +//> using options -language:safeNulls import annotation.targetName class A diff --git a/tests/run-macros/annot-arg-value-in-java.check b/tests/run-macros/annot-arg-value-in-java.check index 74821d24bf26..46cf4aa998bc 100644 --- a/tests/run-macros/annot-arg-value-in-java.check +++ b/tests/run-macros/annot-arg-value-in-java.check @@ -1,7 +1,7 @@ J: new java.lang.SuppressWarnings(value = "a") new java.lang.SuppressWarnings(value = "b") -new java.lang.SuppressWarnings(value = _root_.scala.Array.apply[java.lang.String]("c", "d")(scala.reflect.ClassTag.apply[java.lang.String](classOf[java.lang.String]))) +new java.lang.SuppressWarnings(value = _root_.scala.Array.apply[(java.lang.String)?]("c", "d")(scala.reflect.ClassTag.apply[(java.lang.String)?](classOf[java.lang.String]))) JOtherTypes: new Annot(value = 1, m = _, n = _) new Annot(value = -2, m = _, n = _) diff --git a/tests/run-macros/i20052.check b/tests/run-macros/i20052.check index ca45222cf4cf..99dfa26b8522 100644 --- a/tests/run-macros/i20052.check +++ b/tests/run-macros/i20052.check @@ -2,4 +2,4 @@ method (Flags.JavaDefined | Flags.Method) List(List((x$0,scala.Int))) method (Flags.JavaDefined | Flags.Method) List(List()) method (Flags.JavaDefined | Flags.Method | Flags.Private) List(List()) method (Flags.JavaDefined | Flags.Method | Flags.Private) List(List()) -method (Flags.JavaDefined | Flags.Method) List(List((A,_ >: scala.Nothing <: .)), List((x$0,A))) +method (Flags.JavaDefined | Flags.Method) List(List((A,_ >: scala.Nothing <: .)), List((x$0,(A)?))) diff --git a/tests/sjs-junit/test/org/scalajs/testsuite/compiler/EnumTestScala3.scala b/tests/sjs-junit/test/org/scalajs/testsuite/compiler/EnumTestScala3.scala index 263a3b4774a3..801d74a12402 100644 --- a/tests/sjs-junit/test/org/scalajs/testsuite/compiler/EnumTestScala3.scala +++ b/tests/sjs-junit/test/org/scalajs/testsuite/compiler/EnumTestScala3.scala @@ -126,7 +126,7 @@ class EnumTestScala3: end testCurrency2 @Test def testOpt(): Unit = - + import scala.language.safeNulls def encode[T <: AnyVal](t: Opt[T]): T | Null = t match case Opt.Sm(t) => t case Opt.Nn => null diff --git a/tests/warn/i20132.future-Left.scala b/tests/warn/i20132.future-Left.scala index a25718eadb6b..f3d7584fe8f9 100644 --- a/tests/warn/i20132.future-Left.scala +++ b/tests/warn/i20132.future-Left.scala @@ -1,4 +1,4 @@ -//> using options -Yexplicit-nulls -Yno-flexible-types +//> using options -Yno-flexible-types import scala.language.unsafeNulls diff --git a/tests/warn/i20132.stream-Tuple2.safeNulls.fixed.scala b/tests/warn/i20132.stream-Tuple2.safeNulls.fixed.scala index 817d8ce06cee..21d316d695b9 100644 --- a/tests/warn/i20132.stream-Tuple2.safeNulls.fixed.scala +++ b/tests/warn/i20132.stream-Tuple2.safeNulls.fixed.scala @@ -1,4 +1,4 @@ -//> using options -Yexplicit-nulls -Yno-flexible-types +//> using options -language:safeNulls -Yno-flexible-types import scala.jdk.CollectionConverters.* diff --git a/tests/warn/i20132.stream-Tuple2.safeNulls.scala b/tests/warn/i20132.stream-Tuple2.safeNulls.scala index 2d4a2318039e..97d36da4cfd1 100644 --- a/tests/warn/i20132.stream-Tuple2.safeNulls.scala +++ b/tests/warn/i20132.stream-Tuple2.safeNulls.scala @@ -1,4 +1,4 @@ -//> using options -Yexplicit-nulls -Yno-flexible-types +//> using options -language:safeNulls -Yno-flexible-types import scala.jdk.CollectionConverters.* diff --git a/tests/warn/i20132.stream-Tuple2.scala b/tests/warn/i20132.stream-Tuple2.scala index b7cf58f8f930..e09edcbc5a73 100644 --- a/tests/warn/i20132.stream-Tuple2.scala +++ b/tests/warn/i20132.stream-Tuple2.scala @@ -1,4 +1,4 @@ -//> using options -Yexplicit-nulls -Yno-flexible-types +//> using options -Yno-flexible-types // Previously failed because the scrutinee under // unsafeNulls/explicit-nulls/no-flexible-types diff --git a/tests/warn/nonunit-statement.check b/tests/warn/nonunit-statement.check index 46a75dfd3065..751784e90f74 100644 --- a/tests/warn/nonunit-statement.check +++ b/tests/warn/nonunit-statement.check @@ -67,19 +67,19 @@ -- [E175] Potential Issue Warning: tests/warn/nonunit-statement.scala:126:37 ------------------------------------------- 126 | if (start.length != 0) jsb.append(start) // warn (value-discard) | ^^^^^^^^^^^^^^^^^ - | discarded non-Unit value of type StringBuilder. Add `: Unit` to discard silently. + | discarded non-Unit value of type (StringBuilder)?. Add `: Unit` to discard silently. -- [E175] Potential Issue Warning: tests/warn/nonunit-statement.scala:132:18 ------------------------------------------- 132 | jsb.append(it.next()) // warn (value-discard) | ^^^^^^^^^^^^^^^^^^^^^ - | discarded non-Unit value of type StringBuilder. Add `: Unit` to discard silently. + | discarded non-Unit value of type (StringBuilder)?. Add `: Unit` to discard silently. -- [E175] Potential Issue Warning: tests/warn/nonunit-statement.scala:135:35 ------------------------------------------- 135 | if (end.length != 0) jsb.append(end) // warn (value-discard) | ^^^^^^^^^^^^^^^ - | discarded non-Unit value of type StringBuilder. Add `: Unit` to discard silently. + | discarded non-Unit value of type (StringBuilder)?. Add `: Unit` to discard silently. -- [E175] Potential Issue Warning: tests/warn/nonunit-statement.scala:141:14 ------------------------------------------- 141 | b.append(it.next()) // warn (value-discard) | ^^^^^^^^^^^^^^^^^^^ - | discarded non-Unit value of type StringBuilder. Add `: Unit` to discard silently. + | discarded non-Unit value of type (StringBuilder)?. Add `: Unit` to discard silently. -- [E175] Potential Issue Warning: tests/warn/nonunit-statement.scala:146:30 ------------------------------------------- 146 | while (it.hasNext) it.next() // warn | ^^^^^^^^^