Skip to content

Commit 4e0ddc9

Browse files
committed
Merge branch 'pr/26985' into merge-26985-27004
# Conflicts: # compiler/src/dotty/tools/dotc/core/Types.scala # compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala
2 parents 234d99d + fde3c0e commit 4e0ddc9

63 files changed

Lines changed: 200 additions & 144 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

community-build/src/scala/dotty/communitybuild/projects.scala

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,8 +127,6 @@ object SbtCommunityProject:
127127
def scalacOptions = List(
128128
"-Xcheck-macros",
129129
"-Wsafe-init",
130-
"-Yexplicit-nulls",
131-
"-language:unsafeNulls",
132130
)
133131

134132
object projects:

compiler/src/dotty/tools/dotc/Run.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -615,7 +615,7 @@ extends ImplicitRunInfo, ConstraintRunInfo, cc.CaptureRunInfo {
615615
.setTyper(new Typer)
616616
.addMode(Mode.ImplicitsEnabled)
617617
.setTyperState(ctx.typerState.fresh(ctx.reporter))
618-
if ctx.settings.YexplicitNulls.value && !Feature.enabledBySetting(nme.unsafeNulls) then
618+
if ctx.settings.YexplicitNulls.value || Feature.enabledBySetting(nme.safeNulls) then
619619
start = start.addMode(Mode.SafeNulls)
620620
ctx.initialize()(using start) // re-initialize the base context with start
621621

compiler/src/dotty/tools/dotc/config/Feature.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ object Feature:
6262
(nme.noAutoTupling, "Disable automatic tupling"),
6363
(nme.dynamics, "Allow direct or indirect subclasses of scala.Dynamic"),
6464
(nme.unsafeNulls, "Enable unsafe nulls for explicit nulls"),
65+
(nme.safeNulls, "Enable safe nulls for explicit nulls"),
6566
(nme.postfixOps, "Allow postfix operators (not recommended)"),
6667
(nme.strictEquality, "Enable strict equality (disable canEqualAny)"),
6768
(nme.implicitConversions, "Allow implicit conversions without warnings"),

compiler/src/dotty/tools/dotc/config/ScalaSettings.scala

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -561,7 +561,8 @@ private sealed trait YSettings:
561561
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:<ORIGINAL_FILE_PATH>` marks the start of user code. The comment should be suffixed by `:<ORIGINAL_FILE_PATH>` to indicate the original file.", "")
562562

563563
// Experimental language features
564-
val YexplicitNulls: Setting[Boolean] = BooleanSetting(ForkSetting, "Yexplicit-nulls", "Make reference types non-nullable. Nullable types can be expressed with unions: e.g. String|Null.")
564+
val YexplicitNulls: Setting[Boolean] = BooleanSetting(ForkSetting, "Yexplicit-nulls", "Since explicit nulls is enabled by default, this flag now enables safe nulls for explicit-nulls")
565+
val YnoExplicitNulls: Setting[Boolean] = BooleanSetting(ForkSetting, "Yno-explicit-nulls", "Make reference types implictly nullable.")
565566
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.")
566567
val YflexifyTasty: Setting[Boolean] = BooleanSetting(ForkSetting, "Yflexify-tasty", "Apply flexification to Scala code compiled without -Yexplicit-nulls, when reading from tasty.")
567568
val YsafeInitGlobal: Setting[Boolean] = BooleanSetting(ForkSetting, "Ysafe-init-global", "Check safe initialization of global objects.")
@@ -577,6 +578,7 @@ private sealed trait YSettings:
577578
val YexplainLowlevel: Setting[Boolean] = BooleanSetting(ForkSetting, "Yexplain-lowlevel", "When explaining type errors, show types at a lower level.")
578579
val YnoDoubleBindings: Setting[Boolean] = BooleanSetting(ForkSetting, "Yno-double-bindings", "Assert no namedtype is bound twice (should be enabled only if program is error-free).")
579580
val YshowVarBounds: Setting[Boolean] = BooleanSetting(ForkSetting, "Yshow-var-bounds", "Print type variables with their bounds.")
581+
val YhideFlexibleTypes: Setting[Boolean] = BooleanSetting(ForkSetting, "Yhide-flexible-types", "Print flexible types as their base type. (T instead of (T)?)")
580582

581583
val Yinstrument: Setting[Boolean] = BooleanSetting(ForkSetting, "Yinstrument", "Add instrumentation code that counts allocations and closure creations.")
582584
val YinstrumentDefs: Setting[Boolean] = BooleanSetting(ForkSetting, "Yinstrument-defs", "Add instrumentation code that counts method calls; needs -Yinstrument to be set, too.")

compiler/src/dotty/tools/dotc/core/Contexts.scala

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -489,13 +489,13 @@ object Contexts {
489489
fresh.setSetting(ctx.settings.color, "never")
490490

491491
/** Is the explicit nulls option set? */
492-
def explicitNulls: Boolean = base.settings.YexplicitNulls.value
492+
def explicitNulls: Boolean = !base.settings.YnoExplicitNulls.value
493493

494494
/** Is the flexible types option set? */
495-
def flexibleTypes: Boolean = base.settings.YexplicitNulls.value && !base.settings.YnoFlexibleTypes.value
495+
def flexibleTypes: Boolean = explicitNulls && !base.settings.YnoFlexibleTypes.value
496496

497497
/** Is the flexify tasty option set? */
498-
def flexifyTasty: Boolean = base.settings.YexplicitNulls.value && base.settings.YflexifyTasty.value
498+
def flexifyTasty: Boolean = explicitNulls && base.settings.YflexifyTasty.value
499499

500500
/** Is the best-effort option set? */
501501
def isBestEffort: Boolean = base.settings.YbestEffort.value
@@ -771,7 +771,9 @@ object Contexts {
771771
importInfo.mentionsFeature(nme.unsafeNulls) match
772772
case Some(true) =>
773773
setMode(this.mode &~ Mode.SafeNulls)
774-
case Some(false) if ctx.settings.YexplicitNulls.value =>
774+
case _ =>
775+
importInfo.mentionsFeature(nme.safeNulls) match
776+
case Some(true) if explicitNulls =>
775777
setMode(this.mode | Mode.SafeNulls)
776778
case _ =>
777779
updateStore(importInfoLoc, importInfo)

compiler/src/dotty/tools/dotc/core/StdNames.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -668,6 +668,7 @@ object StdNames {
668668
val unbox: N = "unbox"
669669
val universe: N = "universe"
670670
val unsafeNulls: N = "unsafeNulls"
671+
val safeNulls: N = "safeNulls"
671672
val update: N = "update"
672673
val updateDynamic: N = "updateDynamic"
673674
val uses: N = "uses"

compiler/src/dotty/tools/dotc/core/Types.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,8 @@ object Types extends TypeUtils {
384384
final def isNotNull(using Context): Boolean = this match {
385385
case tp: ConstantType => tp.value.value != null
386386
case FlexibleType(_) => false
387+
case tp: ThisType => true
388+
case tp: SuperType => true
387389
case tp: ClassInfo => !tp.cls.isNullableClass && !tp.isNothingType
388390
case tp: AppliedType => tp.superType.isNotNull
389391
case tp: TypeBounds => tp.hi.isNotNull

compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -420,7 +420,10 @@ class TreeUnpickler(reader: TastyReader,
420420
if nothingButMods(end) then AliasingBounds(readVariances(lo))
421421
else
422422
val hi = readVariances(readType())
423-
createNullableTypeBounds(lo, hi)
423+
if (ctx.flexifyTasty && !explicitNulls)
424+
createNullableTypeBounds(lo, hi)
425+
else
426+
TypeBounds(lo, hi)
424427
case ANNOTATEDtype =>
425428
val parent = readType()
426429
val ann =
@@ -1716,7 +1719,10 @@ class TreeUnpickler(reader: TastyReader,
17161719
val lo = readTpt()
17171720
val hi = if currentAddr == end then lo else readTpt()
17181721
val alias = if currentAddr == end then EmptyTree else readTpt()
1719-
createNullableTypeBoundsTree(lo, hi, alias)
1722+
if (ctx.flexifyTasty && !explicitNulls)
1723+
createNullableTypeBoundsTree(lo, hi, alias)
1724+
else
1725+
TypeBoundsTree(lo, hi, alias)
17201726
case QUOTE =>
17211727
Quote(readTree(), Nil).withBodyType(readType())
17221728
case SPLICE =>

compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,10 @@ class PlainPrinter(_ctx: Context) extends Printer {
244244
case tp: SingletonType =>
245245
toTextSingleton(tp)
246246
case FlexibleType(tpe) =>
247-
"(" ~ toText(tpe) ~ ")?"
247+
if (ctx.settings.YhideFlexibleTypes.value) then
248+
toText(tpe)
249+
else
250+
"(" ~ toText(tpe) ~ ")?"
248251
case AppliedType(tycon, args) =>
249252
(toTextLocal(tycon) ~ "[" ~ argsText(args) ~ "]").close
250253
case tp: RefinedType =>

compiler/src/dotty/tools/dotc/transform/Pickler.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -438,7 +438,7 @@ class Pickler extends Phase {
438438
val attributes = Attributes(
439439
sourceFile = unit.source.pathRelativeToSourceRoot,
440440
scala2StandardLibrary = Feature.shouldBehaveAsScala2,
441-
explicitNulls = ctx.settings.YexplicitNulls.value,
441+
explicitNulls = ctx.explicitNulls,
442442
captureChecked = Feature.ccEnabled,
443443
withPureFuns = Feature.pureFunsEnabled,
444444
isJava = isJavaAttr,

0 commit comments

Comments
 (0)