From 40932f84c8639681e0b47f0d5286158ccb2f14c7 Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Wed, 17 Sep 2014 16:07:17 +0400 Subject: [PATCH] isFlexible() turned into a method in JetType Otherwise delegated types were never recognized as flexible --- .../results/OverloadingConflictResolver.java | 5 +-- .../lang/resolve/lazy/ForceResolveUtil.java | 8 ++-- .../calls/inference/ConstraintSystemImpl.java | 2 +- .../jet/lang/types/AbstractJetType.java | 2 +- .../jet/lang/types/CommonSupertypes.java | 9 ++--- .../jet/lang/types/DelegatingType.java | 17 +++++++++ .../jetbrains/jet/lang/types/ErrorUtils.java | 2 +- .../jet/lang/types/InflexibleType.java | 38 +++++++++++++++++++ .../org/jetbrains/jet/lang/types/JetType.java | 10 +++++ .../jet/lang/types/TypeSubstitutor.java | 7 ++-- .../jetbrains/jet/lang/types/TypeUtils.java | 4 +- .../types/checker/TypeCheckingProcedure.java | 29 +++++++------- .../jetbrains/jet/lang/types/flexibleTypes.kt | 35 ++++++++--------- .../jet/renderer/DescriptorRendererImpl.java | 11 +++--- .../jetbrains/jet/plugin/util/TypeUtils.kt | 9 ++--- 15 files changed, 120 insertions(+), 68 deletions(-) create mode 100644 core/descriptors/src/org/jetbrains/jet/lang/types/InflexibleType.java diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/results/OverloadingConflictResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/results/OverloadingConflictResolver.java index 1a177b796fd..05f0a91d569 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/results/OverloadingConflictResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/results/OverloadingConflictResolver.java @@ -28,7 +28,6 @@ import org.jetbrains.jet.lang.resolve.calls.model.VariableAsFunctionResolvedCall import org.jetbrains.jet.lang.types.BoundsSubstitutor; import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.TypeUtils; -import org.jetbrains.jet.lang.types.TypesPackage; import org.jetbrains.jet.lang.types.checker.JetTypeChecker; import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; @@ -244,8 +243,8 @@ public class OverloadingConflictResolver { numericTypeMoreSpecific(specific, general); if (!isSubtype) return false; - boolean specificIsFlexible = TypesPackage.isFlexible(specific); - boolean generalIsFlexible = TypesPackage.isFlexible(general); + boolean specificIsFlexible = specific.isFlexible(); + boolean generalIsFlexible = general.isFlexible(); if (specificIsFlexible && !generalIsFlexible) { // Int! lessSpecific Int diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/ForceResolveUtil.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/ForceResolveUtil.java index d42a9d74d6e..ad1fec8a8d3 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/ForceResolveUtil.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/ForceResolveUtil.java @@ -24,7 +24,6 @@ import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; import org.jetbrains.jet.lang.descriptors.annotations.Annotations; import org.jetbrains.jet.lang.resolve.scopes.JetScope; -import org.jetbrains.jet.lang.types.FlexibleType; import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.TypeConstructor; import org.jetbrains.jet.lang.types.TypeProjection; @@ -87,10 +86,9 @@ public class ForceResolveUtil { public static JetType forceResolveAllContents(@Nullable JetType type) { if (type == null) return null; - if (type instanceof FlexibleType) { - FlexibleType flexibleType = (FlexibleType) type; - forceResolveAllContents(flexibleType.getLowerBound()); - forceResolveAllContents(flexibleType.getUpperBound()); + if (type.isFlexible()) { + forceResolveAllContents(type.getLowerBound()); + forceResolveAllContents(type.getUpperBound()); } else { forceResolveAllContents(type.getConstructor()); diff --git a/core/descriptors/src/org/jetbrains/jet/lang/resolve/calls/inference/ConstraintSystemImpl.java b/core/descriptors/src/org/jetbrains/jet/lang/resolve/calls/inference/ConstraintSystemImpl.java index 5a92aa40438..2394e91f85d 100644 --- a/core/descriptors/src/org/jetbrains/jet/lang/resolve/calls/inference/ConstraintSystemImpl.java +++ b/core/descriptors/src/org/jetbrains/jet/lang/resolve/calls/inference/ConstraintSystemImpl.java @@ -421,7 +421,7 @@ public class ConstraintSystemImpl implements ConstraintSystem { // Foo? <: T! // Foo >: T! // both Foo and Foo? transform to Foo! here - if (TypesPackage.isFlexible(parameterType)) { + if (parameterType.isFlexible()) { if (parameterType instanceof CustomTypeVariable) { CustomTypeVariable typeVariable = (CustomTypeVariable) parameterType; if (typeVariable.getIsTypeVariable()) { diff --git a/core/descriptors/src/org/jetbrains/jet/lang/types/AbstractJetType.java b/core/descriptors/src/org/jetbrains/jet/lang/types/AbstractJetType.java index 4cbed4bca24..d72b6c6655f 100644 --- a/core/descriptors/src/org/jetbrains/jet/lang/types/AbstractJetType.java +++ b/core/descriptors/src/org/jetbrains/jet/lang/types/AbstractJetType.java @@ -21,7 +21,7 @@ import org.jetbrains.jet.lang.types.checker.JetTypeChecker; import java.util.Iterator; import java.util.List; -public abstract class AbstractJetType implements JetType { +public abstract class AbstractJetType extends InflexibleType { @Override public final int hashCode() { int result = getConstructor().hashCode(); diff --git a/core/descriptors/src/org/jetbrains/jet/lang/types/CommonSupertypes.java b/core/descriptors/src/org/jetbrains/jet/lang/types/CommonSupertypes.java index 48da04a18f9..694e45395d2 100644 --- a/core/descriptors/src/org/jetbrains/jet/lang/types/CommonSupertypes.java +++ b/core/descriptors/src/org/jetbrains/jet/lang/types/CommonSupertypes.java @@ -81,11 +81,10 @@ public class CommonSupertypes { List upper = new ArrayList(types.size()); List lower = new ArrayList(types.size()); for (JetType type : types) { - if (TypesPackage.isFlexible(type)) { + if (type.isFlexible()) { hasFlexible = true; - FlexibleType flexibleType = (FlexibleType) type; - upper.add(flexibleType.getUpperBound()); - lower.add(flexibleType.getLowerBound()); + upper.add(type.getUpperBound()); + lower.add(type.getLowerBound()); } else { upper.add(type); @@ -112,7 +111,7 @@ public class CommonSupertypes { for (Iterator iterator = typeSet.iterator(); iterator.hasNext();) { JetType type = iterator.next(); assert type != null; - assert !TypesPackage.isFlexible(type) : "Flexible type " + type + " passed to commonSuperTypeForInflexible"; + assert !type.isFlexible() : "Flexible type " + type + " passed to commonSuperTypeForInflexible"; if (KotlinBuiltIns.getInstance().isNothingOrNullableNothing(type)) { iterator.remove(); } diff --git a/core/descriptors/src/org/jetbrains/jet/lang/types/DelegatingType.java b/core/descriptors/src/org/jetbrains/jet/lang/types/DelegatingType.java index 177a7a5046f..4217a45c566 100644 --- a/core/descriptors/src/org/jetbrains/jet/lang/types/DelegatingType.java +++ b/core/descriptors/src/org/jetbrains/jet/lang/types/DelegatingType.java @@ -31,6 +31,23 @@ public abstract class DelegatingType implements JetType { return getDelegate().getConstructor(); } + @Override + @NotNull + public JetType getUpperBound() { + return getDelegate().getUpperBound(); + } + + @Override + @NotNull + public JetType getLowerBound() { + return getDelegate().getLowerBound(); + } + + @Override + public boolean isFlexible() { + return getDelegate().isFlexible(); + } + @NotNull @Override public List getArguments() { diff --git a/core/descriptors/src/org/jetbrains/jet/lang/types/ErrorUtils.java b/core/descriptors/src/org/jetbrains/jet/lang/types/ErrorUtils.java index 63b8112542f..5f52963d46d 100644 --- a/core/descriptors/src/org/jetbrains/jet/lang/types/ErrorUtils.java +++ b/core/descriptors/src/org/jetbrains/jet/lang/types/ErrorUtils.java @@ -378,7 +378,7 @@ public class ErrorUtils { ); } - private static class ErrorTypeImpl implements JetType { + private static class ErrorTypeImpl extends InflexibleType implements JetType { private final TypeConstructor constructor; private final JetScope memberScope; diff --git a/core/descriptors/src/org/jetbrains/jet/lang/types/InflexibleType.java b/core/descriptors/src/org/jetbrains/jet/lang/types/InflexibleType.java new file mode 100644 index 00000000000..a988d86f979 --- /dev/null +++ b/core/descriptors/src/org/jetbrains/jet/lang/types/InflexibleType.java @@ -0,0 +1,38 @@ +/* + * Copyright 2010-2014 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.lang.types; + +import org.jetbrains.annotations.NotNull; + +public abstract class InflexibleType implements JetType { + @NotNull + @Override + public JetType getUpperBound() { + return this; + } + + @NotNull + @Override + public JetType getLowerBound() { + return this; + } + + @Override + public boolean isFlexible() { + return false; + } +} diff --git a/core/descriptors/src/org/jetbrains/jet/lang/types/JetType.java b/core/descriptors/src/org/jetbrains/jet/lang/types/JetType.java index 2b7f96b1196..9d2d4348273 100644 --- a/core/descriptors/src/org/jetbrains/jet/lang/types/JetType.java +++ b/core/descriptors/src/org/jetbrains/jet/lang/types/JetType.java @@ -43,4 +43,14 @@ public interface JetType extends Annotated { @Override boolean equals(Object other); + + // lowerBound is a subtype of upperBound + @NotNull + JetType getUpperBound(); + + @NotNull + JetType getLowerBound(); + + // isFlexible() == false <=> getLowerBound() == getUpperBound() + boolean isFlexible(); } diff --git a/core/descriptors/src/org/jetbrains/jet/lang/types/TypeSubstitutor.java b/core/descriptors/src/org/jetbrains/jet/lang/types/TypeSubstitutor.java index 85fd40143b5..2bf5a63b270 100644 --- a/core/descriptors/src/org/jetbrains/jet/lang/types/TypeSubstitutor.java +++ b/core/descriptors/src/org/jetbrains/jet/lang/types/TypeSubstitutor.java @@ -155,12 +155,11 @@ public class TypeSubstitutor { // The type is within the substitution range, i.e. T or T? JetType type = originalProjection.getType(); Variance originalProjectionKind = originalProjection.getProjectionKind(); - if (type instanceof FlexibleType && !TypesPackage.isCustomTypeVariable(type)) { - FlexibleType flexibleType = (FlexibleType) type; + if (type.isFlexible() && !TypesPackage.isCustomTypeVariable(type)) { TypeProjection substitutedLower = - unsafeSubstitute(new TypeProjectionImpl(originalProjectionKind, flexibleType.getLowerBound()), recursionDepth + 1); + unsafeSubstitute(new TypeProjectionImpl(originalProjectionKind, type.getLowerBound()), recursionDepth + 1); TypeProjection substitutedUpper = - unsafeSubstitute(new TypeProjectionImpl(originalProjectionKind, flexibleType.getUpperBound()), recursionDepth + 1); + unsafeSubstitute(new TypeProjectionImpl(originalProjectionKind, type.getUpperBound()), recursionDepth + 1); // todo: projection kind is neglected return new TypeProjectionImpl(originalProjectionKind, DelegatingFlexibleType.OBJECT$.create( diff --git a/core/descriptors/src/org/jetbrains/jet/lang/types/TypeUtils.java b/core/descriptors/src/org/jetbrains/jet/lang/types/TypeUtils.java index fe789dae139..33965c7dfdf 100644 --- a/core/descriptors/src/org/jetbrains/jet/lang/types/TypeUtils.java +++ b/core/descriptors/src/org/jetbrains/jet/lang/types/TypeUtils.java @@ -44,7 +44,7 @@ public class TypeUtils { public static final JetType CANT_INFER_LAMBDA_PARAM_TYPE = ErrorUtils.createErrorType("Cannot be inferred"); - public static class SpecialType implements JetType { + public static class SpecialType extends InflexibleType implements JetType { private final String name; public SpecialType(String name) { @@ -424,7 +424,7 @@ public class TypeUtils { if (type.isNullable()) { return true; } - if (TypesPackage.isFlexible(type) && isNullableType(((FlexibleType) type).getUpperBound())) { + if (type.isFlexible() && isNullableType(type.getUpperBound())) { return true; } if (type.getConstructor().getDeclarationDescriptor() instanceof TypeParameterDescriptor) { diff --git a/core/descriptors/src/org/jetbrains/jet/lang/types/checker/TypeCheckingProcedure.java b/core/descriptors/src/org/jetbrains/jet/lang/types/checker/TypeCheckingProcedure.java index e185bbb1ed8..a4aa359d309 100644 --- a/core/descriptors/src/org/jetbrains/jet/lang/types/checker/TypeCheckingProcedure.java +++ b/core/descriptors/src/org/jetbrains/jet/lang/types/checker/TypeCheckingProcedure.java @@ -69,18 +69,15 @@ public class TypeCheckingProcedure { } public boolean equalTypes(@NotNull JetType type1, @NotNull JetType type2) { - if (type1 instanceof FlexibleType) { - FlexibleType flexibleType1 = (FlexibleType) type1; - if (type2 instanceof FlexibleType) { - FlexibleType flexibleType2 = (FlexibleType) type2; - return equalTypes(flexibleType1.getLowerBound(), flexibleType2.getLowerBound()) - && equalTypes(flexibleType1.getUpperBound(), flexibleType2.getUpperBound()); + if (type1.isFlexible()) { + if (type2.isFlexible()) { + return equalTypes(type1.getLowerBound(), type2.getLowerBound()) + && equalTypes(type1.getUpperBound(), type2.getUpperBound()); } - return heterogeneousEquivalence(type2, flexibleType1); + return heterogeneousEquivalence(type2, type1); } - else if (type2 instanceof FlexibleType) { - FlexibleType flexibleType2 = (FlexibleType) type2; - return heterogeneousEquivalence(type1, flexibleType2); + else if (type2.isFlexible()) { + return heterogeneousEquivalence(type1, type2); } if (type1.isNullable() != type2.isNullable()) { @@ -121,9 +118,9 @@ public class TypeCheckingProcedure { return true; } - private boolean heterogeneousEquivalence(JetType inflexibleType, FlexibleType flexibleType) { + private boolean heterogeneousEquivalence(JetType inflexibleType, JetType flexibleType) { // This is to account for the case when we have Collection vs (Mutable)Collection! or K(java.util.Collection) - assert !TypesPackage.isFlexible(inflexibleType) : "Only inflexible types are allowed here: " + inflexibleType; + assert !inflexibleType.isFlexible() : "Only inflexible types are allowed here: " + inflexibleType; return isSubtypeOf(flexibleType.getLowerBound(), inflexibleType) && isSubtypeOf(inflexibleType, flexibleType.getUpperBound()); } @@ -183,11 +180,11 @@ public class TypeCheckingProcedure { } public boolean isSubtypeOf(@NotNull JetType subtype, @NotNull JetType supertype) { - if (subtype instanceof FlexibleType) { - return isSubtypeOf(((FlexibleType) subtype).getLowerBound(), supertype); + if (subtype.isFlexible()) { + return isSubtypeOf(subtype.getLowerBound(), supertype); } - if (supertype instanceof FlexibleType) { - return isSubtypeOf(subtype, ((FlexibleType) supertype).getUpperBound()); + if (supertype.isFlexible()) { + return isSubtypeOf(subtype, supertype.getUpperBound()); } if (subtype.isError() || supertype.isError()) { return true; diff --git a/core/descriptors/src/org/jetbrains/jet/lang/types/flexibleTypes.kt b/core/descriptors/src/org/jetbrains/jet/lang/types/flexibleTypes.kt index 5d957cebc23..0ef5eee499f 100644 --- a/core/descriptors/src/org/jetbrains/jet/lang/types/flexibleTypes.kt +++ b/core/descriptors/src/org/jetbrains/jet/lang/types/flexibleTypes.kt @@ -22,19 +22,12 @@ public trait NullAwareType { public fun makeNullableAsSpecified(nullable: Boolean): JetType } -public trait FlexibleType : JetType { - public val lowerBound: JetType - public val upperBound: JetType -} - -public fun JetType.isFlexible(): Boolean = this is FlexibleType - -public fun JetType.lowerIfFlexible(): JetType = if (this is FlexibleType) lowerBound else this +public fun JetType.lowerIfFlexible(): JetType = if (this.isFlexible()) getLowerBound() else this public open class DelegatingFlexibleType protected ( - override val lowerBound: JetType, - override val upperBound: JetType -) : DelegatingType(), FlexibleType, NullAwareType { + private val _lowerBound: JetType, + private val _upperBound: JetType +) : DelegatingType(), NullAwareType { class object { public fun create(lowerBound: JetType, upperBound: JetType): JetType { if (lowerBound == upperBound) return lowerBound @@ -43,23 +36,27 @@ public open class DelegatingFlexibleType protected ( } { - assert (!lowerBound.isFlexible()) { "Lower bound of a flexible type can not be flexible: $lowerBound" } - assert (!upperBound.isFlexible()) { "Upper bound of a flexible type can not be flexible: $upperBound" } - assert (lowerBound != upperBound) { "Lower and upper bounds are equal: $lowerBound == $upperBound" } - assert (JetTypeChecker.DEFAULT.isSubtypeOf(lowerBound, upperBound)) { - "Lower bound $lowerBound of a flexible type must be a subtype of the upper bound $upperBound" + assert (!_lowerBound.isFlexible()) { "Lower bound of a flexible type can not be flexible: $_lowerBound" } + assert (!_upperBound.isFlexible()) { "Upper bound of a flexible type can not be flexible: $_upperBound" } + assert (_lowerBound != _upperBound) { "Lower and upper bounds are equal: $_lowerBound == $_upperBound" } + assert (JetTypeChecker.DEFAULT.isSubtypeOf(_lowerBound, _upperBound)) { + "Lower bound $_lowerBound of a flexible type must be a subtype of the upper bound $_upperBound" } } + override fun isFlexible(): Boolean = true + override fun getUpperBound(): JetType = _upperBound + override fun getLowerBound(): JetType = _lowerBound + protected open fun create(lowerBound: JetType, upperBound: JetType): JetType { return DelegatingFlexibleType.create(lowerBound, upperBound) } override fun makeNullableAsSpecified(nullable: Boolean): JetType { - return create(TypeUtils.makeNullableAsSpecified(lowerBound, nullable), TypeUtils.makeNullableAsSpecified(upperBound, nullable)) + return create(TypeUtils.makeNullableAsSpecified(_lowerBound, nullable), TypeUtils.makeNullableAsSpecified(_upperBound, nullable)) } - override fun getDelegate() = lowerBound + override fun getDelegate() = _lowerBound - override fun toString() = "('$lowerBound'..'$upperBound')" + override fun toString() = "('$_lowerBound'..'$_upperBound')" } diff --git a/core/descriptors/src/org/jetbrains/jet/renderer/DescriptorRendererImpl.java b/core/descriptors/src/org/jetbrains/jet/renderer/DescriptorRendererImpl.java index d400912ba99..32719d524dd 100644 --- a/core/descriptors/src/org/jetbrains/jet/renderer/DescriptorRendererImpl.java +++ b/core/descriptors/src/org/jetbrains/jet/renderer/DescriptorRendererImpl.java @@ -293,20 +293,19 @@ public class DescriptorRendererImpl implements DescriptorRenderer { @NotNull @Override public String renderType(@NotNull JetType type) { - if (type instanceof FlexibleType) { - FlexibleType flexibleType = (FlexibleType) type; + if (type.isFlexible()) { if (!debugMode) { - return renderFlexibleType(flexibleType); + return renderFlexibleType(type); } else { - return "(" + renderType(flexibleType.getLowerBound()) + ".." + renderType(flexibleType.getUpperBound()) + ")"; + return "(" + renderType(type.getLowerBound()) + ".." + renderType(type.getUpperBound()) + ")"; } } return renderInflexibleType(type); } private String renderInflexibleType(@NotNull JetType type) { - assert !TypesPackage.isFlexible(type) : "Flexible types not allowed here: " + renderType(type); + assert !type.isFlexible() : "Flexible types not allowed here: " + renderType(type); if (type == CANT_INFER_LAMBDA_PARAM_TYPE || type == DONT_CARE) { return "???"; @@ -330,7 +329,7 @@ public class DescriptorRendererImpl implements DescriptorRenderer { } @NotNull - private String renderFlexibleType(@NotNull FlexibleType type) { + private String renderFlexibleType(@NotNull JetType type) { JetType lower = type.getLowerBound(); JetType upper = type.getUpperBound(); diff --git a/idea/src/org/jetbrains/jet/plugin/util/TypeUtils.kt b/idea/src/org/jetbrains/jet/plugin/util/TypeUtils.kt index 4f161b0f4c8..bcc549e42bf 100644 --- a/idea/src/org/jetbrains/jet/plugin/util/TypeUtils.kt +++ b/idea/src/org/jetbrains/jet/plugin/util/TypeUtils.kt @@ -24,7 +24,6 @@ import org.jetbrains.jet.lang.types.TypeProjectionImpl import org.jetbrains.jet.lang.types.ErrorUtils import org.jetbrains.jet.lang.resolve.java.kotlinSignature.CollectionClassMapping import org.jetbrains.jet.lang.descriptors.ClassDescriptor -import org.jetbrains.jet.lang.types.FlexibleType import org.jetbrains.jet.lang.resolve.java.JvmAnnotationNames fun JetType.makeNullable() = TypeUtils.makeNullable(this) @@ -35,8 +34,8 @@ fun JetType.supertypes(): Set = TypeUtils.getAllSupertypes(this) fun JetType.isUnit(): Boolean = KotlinBuiltIns.getInstance().isUnit(this) public fun approximateFlexibleTypes(jetType: JetType, outermost: Boolean = true): JetType { - if (jetType is FlexibleType) { - val lowerClass = jetType.lowerBound.getConstructor().getDeclarationDescriptor() as? ClassDescriptor? + if (jetType.isFlexible()) { + val lowerClass = jetType.getLowerBound().getConstructor().getDeclarationDescriptor() as? ClassDescriptor? val isCollection = lowerClass != null && CollectionClassMapping.getInstance().isMutableCollection(lowerClass) // (Mutable)Collection! -> MutableCollection? // Foo<(Mutable)Collection!>! -> Foo>? @@ -44,9 +43,9 @@ public fun approximateFlexibleTypes(jetType: JetType, outermost: Boolean = true) // Foo! -> Foo? val approximation = if (isCollection) - TypeUtils.makeNullableAsSpecified(if (jetType.isMarkedReadOnly()) jetType.upperBound else jetType.lowerBound, outermost) + TypeUtils.makeNullableAsSpecified(if (jetType.isMarkedReadOnly()) jetType.getUpperBound() else jetType.getLowerBound(), outermost) else - if (outermost) jetType.upperBound else jetType.lowerBound + if (outermost) jetType.getUpperBound() else jetType.getLowerBound() val approximated = approximateFlexibleTypes(approximation) return if (jetType.isMarkedNotNull()) approximated.makeNotNullable() else approximated }