Do not remove trivial substitutions
to avoid substituting a new type parameter by default instead of leaving the same #KT-4887 Fixed
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
package h
|
||||
|
||||
public class MyClass<S, T>(param: MyClass<S, T>) {
|
||||
fun test() {
|
||||
val result: MyClass<Any, Any>? = null
|
||||
MyClass<S, Any>(result <!CAST_NEVER_SUCCEEDS!>as<!> MyClass<S, Any>)
|
||||
}
|
||||
}
|
||||
@@ -6773,6 +6773,11 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest {
|
||||
doTest("compiler/testData/diagnostics/tests/substitutions/kt1558-short.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt4887.kt")
|
||||
public void testKt4887() throws Exception {
|
||||
doTest("compiler/testData/diagnostics/tests/substitutions/kt4887.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("upperBoundsSubstitutionForOverloadResolutionWithAmbiguity.kt")
|
||||
public void testUpperBoundsSubstitutionForOverloadResolutionWithAmbiguity() throws Exception {
|
||||
doTest("compiler/testData/diagnostics/tests/substitutions/upperBoundsSubstitutionForOverloadResolutionWithAmbiguity.kt");
|
||||
|
||||
+1
-4
@@ -116,10 +116,7 @@ public abstract class AbstractClassDescriptor implements ClassDescriptor {
|
||||
List<TypeParameterDescriptor> typeParameters = getTypeConstructor().getParameters();
|
||||
Map<TypeConstructor, TypeProjection> substitutionContext = TypeSubstitutor.buildSubstitutionContext(typeParameters, typeArguments);
|
||||
|
||||
// Unsafe substitutor is OK, because no recursion can hurt us upon a trivial substitution:
|
||||
// all the types are written explicitly in the code already, they can not get infinite.
|
||||
// One exception is *-projections, but they need to be handled separately anyways.
|
||||
TypeSubstitutor substitutor = TypeSubstitutor.createUnsafe(substitutionContext);
|
||||
TypeSubstitutor substitutor = TypeSubstitutor.create(substitutionContext);
|
||||
return new SubstitutingScope(getScopeForMemberLookup(), substitutor);
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,6 @@ import org.jetbrains.jet.lang.resolve.scopes.SubstitutingScope;
|
||||
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -72,14 +71,8 @@ public class TypeSubstitutor {
|
||||
return create(new CompositeTypeSubstitution(substitutions));
|
||||
}
|
||||
|
||||
/** No assertion for immediate recursion */
|
||||
public static TypeSubstitutor createUnsafe(@NotNull Map<TypeConstructor, TypeProjection> substitutionContext) {
|
||||
Map<TypeConstructor, TypeProjection> cleanContext = removeTrivialSubstitutions(substitutionContext);
|
||||
return create(new MapToTypeSubstitutionAdapter(cleanContext));
|
||||
}
|
||||
|
||||
public static TypeSubstitutor create(@NotNull Map<TypeConstructor, TypeProjection> substitutionContext) {
|
||||
return createUnsafe(removeTrivialSubstitutions(substitutionContext));
|
||||
return create(new MapToTypeSubstitutionAdapter(substitutionContext));
|
||||
}
|
||||
|
||||
public static TypeSubstitutor create(@NotNull JetType context) {
|
||||
@@ -226,22 +219,6 @@ public class TypeSubstitutor {
|
||||
return substitutedArguments;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static Map<TypeConstructor, TypeProjection> removeTrivialSubstitutions(@NotNull Map<TypeConstructor, TypeProjection> context) {
|
||||
Map<TypeConstructor, TypeProjection> clean = new HashMap<TypeConstructor, TypeProjection>(context);
|
||||
boolean changed = false;
|
||||
for (Iterator<Map.Entry<TypeConstructor, TypeProjection>> iterator = clean.entrySet().iterator(); iterator.hasNext(); ) {
|
||||
Map.Entry<TypeConstructor, TypeProjection> entry = iterator.next();
|
||||
TypeConstructor key = entry.getKey();
|
||||
TypeProjection value = entry.getValue();
|
||||
if (key == value.getType().getConstructor() && value.getProjectionKind() == Variance.INVARIANT) {
|
||||
iterator.remove();
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
return changed ? clean : context;
|
||||
}
|
||||
|
||||
private static Variance combine(Variance typeParameterVariance, Variance projectionKind) {
|
||||
if (typeParameterVariance == Variance.INVARIANT) return projectionKind;
|
||||
if (projectionKind == Variance.INVARIANT) return typeParameterVariance;
|
||||
|
||||
Reference in New Issue
Block a user