Skip to content

Commit 24d6ba9

Browse files
committed
Update code
1 parent a5177e1 commit 24d6ba9

File tree

28 files changed

+271
-30
lines changed

28 files changed

+271
-30
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -464,7 +464,7 @@ object Contexts {
464464
def explicitNulls: Boolean = base.settings.YexplicitNulls.value
465465

466466
/** Is the flexible types option set? */
467-
def flexibleTypes: Boolean = base.settings.YflexibleTypes.value
467+
def flexibleTypes: Boolean = base.settings.YexplicitNulls.value && base.settings.YflexibleTypes.value
468468

469469
/** A fresh clone of this context embedded in this context. */
470470
def fresh: FreshContext = freshOver(this)

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ object JavaNullInterop {
122122
// We don't make the outmost levels of type arguments nullable if tycon is Java-defined.
123123
// This is because Java classes are _all_ nullified, so both `java.util.List[String]` and
124124
// `java.util.List[String|Null]` contain nullable elements.
125-
outermostLevelAlreadyNullable = tp.classSymbol.is(JavaDefined) && !ctx.flexibleTypes
125+
outermostLevelAlreadyNullable = tp.classSymbol.is(JavaDefined)
126126
val targs2 = targs map this
127127
outermostLevelAlreadyNullable = oldOutermostNullable
128128
val appTp2 = derivedAppliedType(appTp, tycon, targs2)

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ object NullOpsDecorator:
3939
if (tp1s ne tp1) && (tp2s ne tp2) then
4040
tp.derivedAndType(tp1s, tp2s)
4141
else tp
42-
case tp @ FlexibleType(tp1) => strip(tp1)
42+
case tp: FlexibleType => tp.hi
4343
case tp @ TypeBounds(lo, hi) =>
4444
tp.derivedTypeBounds(strip(lo), strip(hi))
4545
case tp => tp

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -545,7 +545,7 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
545545
// invariant: tp2 is NOT a FlexibleType
546546
// is Flex(T) <: tp2?
547547
case tp1: FlexibleType =>
548-
recur(tp1.underlying, tp2)
548+
recur(tp1.hi, tp2)
549549
case CapturingType(parent1, refs1) =>
550550
if tp2.isAny then true
551551
else if subCaptures(refs1, tp2.captureSet, frozenConstraint).isOK && sameBoxed(tp1, tp2, refs1)

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

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3408,19 +3408,28 @@ object Types {
34083408
* in Kotlin. A FlexibleType(T) generally behaves like an abstract type with bad bounds
34093409
* T|Null .. T, so that T|Null <: FlexibleType(T) <: T.
34103410
*/
3411+
case class FlexibleType(underlying: Type, lo: Type, hi: Type) extends CachedGroundType with ValueType {
3412+
def derivedFlexibleType(underlying: Type)(using Context): Type =
3413+
if this.underlying eq underlying then this else FlexibleType(underlying)
3414+
3415+
override def computeHash(bs: Binders): Int = doHash(bs, underlying)
3416+
3417+
override final def baseClasses(using Context): List[ClassSymbol] = underlying.baseClasses
3418+
}
34113419

34123420
object FlexibleType {
3413-
def apply(underlying: Type) = underlying match {
3421+
def apply(underlying: Type)(using Context): FlexibleType = underlying match {
34143422
case ft: FlexibleType => ft
3415-
case _ => new FlexibleType(underlying)
3423+
case _ =>
3424+
val hi = underlying.stripNull
3425+
val lo = if hi eq underlying then OrNull(hi) else underlying
3426+
new FlexibleType(underlying, lo, hi)
3427+
}
3428+
3429+
def unapply(tp: Type)(using Context): Option[Type] = tp match {
3430+
case ft: FlexibleType => Some(ft.underlying)
3431+
case _ => None
34163432
}
3417-
}
3418-
case class FlexibleType(underlying: Type) extends CachedGroundType with ValueType {
3419-
def lo(using Context): Type = OrNull(underlying)
3420-
def derivedFlexibleType(under: Type)(using Context): Type =
3421-
if this.underlying eq under then this else FlexibleType(under)
3422-
override def computeHash(bs: Binders): Int = doHash(bs, underlying)
3423-
override final def baseClasses(using Context): List[ClassSymbol] = underlying.baseClasses
34243433
}
34253434

34263435
// --- AndType/OrType ---------------------------------------------------------------
@@ -5662,8 +5671,8 @@ object Types {
56625671
val args1 = args.zipWithConserve(tparams):
56635672
case (arg @ TypeBounds(lo, hi), tparam) =>
56645673
boundFollowingVariance(lo, hi, tparam)
5665-
case (arg @ FlexibleType(lo, hi), tparam) =>
5666-
boundFollowingVariance(arg.lo, hi, tparam)
5674+
case (arg: FlexibleType, tparam) =>
5675+
boundFollowingVariance(arg.lo, arg.hi, tparam)
56675676
case (arg, _) => arg
56685677
tp.derivedAppliedType(tycon, args1)
56695678
case tp: RefinedType =>

compiler/src/dotty/tools/dotc/typer/Nullables.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ object Nullables:
3535

3636
private def nullifiedHi(lo: Type, hi: Type)(using Context): Type =
3737
if needNullifyHi(lo, hi) then
38-
if ctx.flexibleTypes then FlexibleType(hi) else OrType(hi, defn.NullType, soft = false)
38+
if ctx.flexibleTypes then FlexibleType(hi) else OrNull(hi)
3939
else hi
4040

4141
/** Create a nullable type bound

compiler/test/dotty/tools/dotc/CompilationTests.scala

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -205,16 +205,24 @@ class CompilationTests {
205205
}.checkRuns()
206206

207207
// Flexible types tests
208-
@Test def flexibleTypesRun: Unit = {
209-
implicit val testGroup: TestGroup = TestGroup("flexibleTypesRun")
210-
compileFilesInDir("tests/flexible-types/run", flexibleTypesOptions)
211-
}.checkRuns()
208+
// @Test def flexibleTypesRun: Unit = {
209+
// implicit val testGroup: TestGroup = TestGroup("flexibleTypesRun")
210+
// compileFilesInDir("tests/flexible-types/run", flexibleTypesOptions)
211+
// }.checkRuns()
212+
213+
@Test def flexibleTypesNeg: Unit = {
214+
implicit val testGroup: TestGroup = TestGroup("flexibleTypesNeg")
215+
aggregateTests(
216+
compileFilesInDir("tests/explicit-nulls/flexible-types/neg", defaultOptions and "-Yexplicit-nulls"),
217+
compileFilesInDir("tests/explicit-nulls/flexible-types/common", defaultOptions and "-Yexplicit-nulls"),
218+
)
219+
}.checkExpectedErrors()
212220

213221
@Test def flexibleTypesPos: Unit = {
214222
implicit val testGroup: TestGroup = TestGroup("flexibleTypesPos")
215223
aggregateTests(
216-
compileFilesInDir("tests/flexible-types/pos", flexibleTypesOptions),
217-
compileFilesInDir("tests/flexible-types/pos-separate", flexibleTypesOptions)
224+
compileFilesInDir("tests/explicit-nulls/flexible-types/pos", flexibleTypesOptions),
225+
compileFilesInDir("tests/explicit-nulls/flexible-types/common", flexibleTypesOptions),
218226
)
219227
}.checkCompile()
220228

compiler/test/dotty/tools/vulpix/TestConfiguration.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,8 @@ object TestConfiguration {
8585
val picklingWithCompilerOptions =
8686
picklingOptions.withClasspath(withCompilerClasspath).withRunClasspath(withCompilerClasspath)
8787

88+
val explicitNullsOptions = defaultOptions and "-Yexplicit-nulls"
89+
8890
val flexibleTypesOptions = explicitNullsOptions and "-Yflexible-types"
8991

9092
/** Default target of the generated class files */
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
public class J {
2+
public String f() {
3+
return "";
4+
}
5+
6+
public <T> T g() {
7+
return null;
8+
}
9+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Check Java calls have been cast to non-nullable.
2+
3+
def test[T <: AnyRef] =
4+
val j: J = new J
5+
6+
val s = j.f()
7+
val sn = s == null
8+
val sn2 = s != null
9+
val seqn = s eq null
10+
val seqn2 = null eq s
11+
12+
13+
val t = j.g[T]()
14+
val tn = t == null
15+
val tn2 = t != null
16+
val teqn = t eq null
17+
val teqn2 = null eq t

0 commit comments

Comments
 (0)