KT-4198 On covariant projection, do not throw whole var's away
#KT-4198 Fixed
This commit is contained in:
@@ -30,6 +30,16 @@ public interface PropertyDescriptor extends VariableDescriptor, CallableMemberDe
|
||||
@Nullable
|
||||
PropertySetterDescriptor getSetter();
|
||||
|
||||
/**
|
||||
* In the following case, the setter is projected out:
|
||||
*
|
||||
* trait Tr<T> { var v: T }
|
||||
* fun test(tr: Tr<out String>) {
|
||||
* tr.v = null!! // the assignment is illegal, although a read would be fine
|
||||
* }
|
||||
*/
|
||||
boolean isSetterProjectedOut();
|
||||
|
||||
@NotNull
|
||||
List<PropertyAccessorDescriptor> getAccessors();
|
||||
|
||||
|
||||
+20
-1
@@ -30,6 +30,7 @@ import org.jetbrains.jet.lang.types.DescriptorSubstitutor;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.jetbrains.jet.lang.types.TypeSubstitutor;
|
||||
import org.jetbrains.jet.lang.types.Variance;
|
||||
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
@@ -49,6 +50,7 @@ public class PropertyDescriptorImpl extends VariableDescriptorImpl implements Pr
|
||||
private List<TypeParameterDescriptor> typeParameters;
|
||||
private PropertyGetterDescriptorImpl getter;
|
||||
private PropertySetterDescriptor setter;
|
||||
private boolean setterProjectedOut;
|
||||
|
||||
private PropertyDescriptorImpl(
|
||||
@Nullable PropertyDescriptor original,
|
||||
@@ -125,6 +127,10 @@ public class PropertyDescriptorImpl extends VariableDescriptorImpl implements Pr
|
||||
this.setter = setter;
|
||||
}
|
||||
|
||||
public void setSetterProjectedOut(boolean setterProjectedOut) {
|
||||
this.setterProjectedOut = setterProjectedOut;
|
||||
}
|
||||
|
||||
public void setVisibility(@NotNull Visibility visibility) {
|
||||
this.visibility = visibility;
|
||||
}
|
||||
@@ -182,6 +188,11 @@ public class PropertyDescriptorImpl extends VariableDescriptorImpl implements Pr
|
||||
return setter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSetterProjectedOut() {
|
||||
return setterProjectedOut;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public List<PropertyAccessorDescriptor> getAccessors() {
|
||||
@@ -253,7 +264,15 @@ public class PropertyDescriptorImpl extends VariableDescriptorImpl implements Pr
|
||||
if (newSetter != null) {
|
||||
List<ValueParameterDescriptor> substitutedValueParameters = FunctionDescriptorImpl.getSubstitutedValueParameters(newSetter, setter, substitutor);
|
||||
if (substitutedValueParameters == null) {
|
||||
return null;
|
||||
// The setter is projected out, e.g. in this case:
|
||||
// trait Tr<T> { var v: T }
|
||||
// fun test(tr: Tr<out Any?>) { ... }
|
||||
// we want to tell the user that although the property is declared as a var,
|
||||
// it can not be assigned to because of the projection
|
||||
substitutedDescriptor.setSetterProjectedOut(true);
|
||||
substitutedValueParameters = Collections.<ValueParameterDescriptor>singletonList(
|
||||
PropertySetterDescriptorImpl.createSetterParameter(newSetter, KotlinBuiltIns.getInstance().getNothingType())
|
||||
);
|
||||
}
|
||||
if (substitutedValueParameters.size() != 1) {
|
||||
throw new IllegalStateException();
|
||||
|
||||
+10
-1
@@ -67,7 +67,16 @@ public class PropertySetterDescriptorImpl extends PropertyAccessorDescriptorImpl
|
||||
|
||||
public void initializeDefault() {
|
||||
assert parameter == null;
|
||||
parameter = new ValueParameterDescriptorImpl(this, 0, Collections.<AnnotationDescriptor>emptyList(), Name.special("<set-?>"), getCorrespondingProperty().getReturnType(), false, null);
|
||||
parameter = createSetterParameter(this, getCorrespondingProperty().getReturnType());
|
||||
}
|
||||
|
||||
public static ValueParameterDescriptorImpl createSetterParameter(
|
||||
@NotNull PropertySetterDescriptor setterDescriptor,
|
||||
@NotNull JetType type
|
||||
) {
|
||||
return new ValueParameterDescriptorImpl(
|
||||
setterDescriptor, 0, Collections.<AnnotationDescriptor>emptyList(), Name.special("<set-?>"), type, false, null
|
||||
);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
Reference in New Issue
Block a user