Skip to content

Commit a542758

Browse files
committed
Enhance nullification logic: ignore type annotations; ignore some special types
1 parent f2af570 commit a542758

File tree

2 files changed

+15
-14
lines changed

2 files changed

+15
-14
lines changed

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

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1991,13 +1991,11 @@ class Definitions {
19911991
* - the upper bound of a TypeParamRef in the current constraint
19921992
*/
19931993
def asContextFunctionType(tp: Type)(using Context): Type =
1994-
tp.stripTypeVar.dealias match
1994+
tp.stripNull().stripTypeVar.dealias match
19951995
case tp1: TypeParamRef if ctx.typerState.constraint.contains(tp1) =>
19961996
asContextFunctionType(TypeComparer.bounds(tp1).hiBound)
19971997
case tp1 @ PolyFunctionOf(mt: MethodType) if mt.isContextualMethod =>
19981998
tp1
1999-
case tp1: FlexibleType =>
2000-
asContextFunctionType(tp1.underlying)
20011999
case tp1 =>
20022000
if tp1.typeSymbol.name.isContextFunction && isFunctionNType(tp1) then tp1
20032001
else NoType

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

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -102,18 +102,19 @@ object ImplicitNullInterop {
102102

103103
/** Should we nullify `tp` at the outermost level? */
104104
def needsNull(tp: Type): Boolean =
105-
if outermostLevelAlreadyNullable then false
105+
if outermostLevelAlreadyNullable || !tp.hasSimpleKind then false
106106
else tp match
107-
case tp: TypeRef if !tp.hasSimpleKind
107+
case tp: TypeRef =>
108108
// We don't modify value types because they're non-nullable even in Java.
109-
|| tp.symbol.isValueClass
109+
!(tp.symbol.isValueClass
110+
// We don't modify some special types.
110111
|| tp.isRef(defn.NullClass)
111112
|| tp.isRef(defn.NothingClass)
112-
// We don't modify unit types.
113113
|| tp.isRef(defn.UnitClass)
114-
// We don't modify `Any` because it's already nullable.
115-
|| tp.isRef(defn.AnyClass) => false
116-
case tp: TypeParamRef if !tp.hasSimpleKind => false
114+
|| tp.isRef(defn.SingletonClass)
115+
|| tp.isRef(defn.AnyValClass)
116+
|| tp.isRef(defn.AnyKindClass)
117+
|| tp.isRef(defn.AnyClass))
117118
case _ => true
118119

119120
// We don't nullify Java varargs at the top level.
@@ -156,17 +157,19 @@ object ImplicitNullInterop {
156157
outermostLevelAlreadyNullable = true
157158
nullify(derivedAndType(tp, this(tp.tp1), this(tp.tp2)))
158159
case tp: TypeParamRef if needsNull(tp) => nullify(tp)
159-
// In all other cases, return the type unchanged.
160-
// In particular, if the type is a ConstantType, then we don't nullify it because it is the
161-
// type of a final non-nullable field.
162160
case tp: ExprType => mapOver(tp)
163-
case tp: AnnotatedType => mapOver(tp)
161+
case tp: AnnotatedType =>
162+
// We don't nullify the annotation part.
163+
derivedAnnotatedType(tp, this(tp.underlying), tp.annot)
164164
case tp: OrType =>
165165
outermostLevelAlreadyNullable = true
166166
nullify(derivedOrType(tp, this(tp.tp1), this(tp.tp2)))
167167
case tp: RefinedType =>
168168
outermostLevelAlreadyNullable = true
169169
nullify(mapOver(tp))
170+
// In all other cases, return the type unchanged.
171+
// In particular, if the type is a ConstantType, then we don't nullify it because it is the
172+
// type of a final non-nullable field.
170173
case _ => tp
171174
}
172175
}

0 commit comments

Comments
 (0)