Fix race in IDE: inject proper storage manager for type parameters
With NO_LOCKS strategy we can easily end up in a situation when constraint system for a generic call is built incorrectly, producing flaky errors (or don't produce errors at all) Now proper storage manager is injected for all cases except: - IR - Codegen - Serialization plugin - Fake local objects Most likely, NO_LOCKS strategy for these cases is fine as at that point the compiler works in one thread #KT-34786 Fixed
This commit is contained in:
+1
-1
@@ -60,7 +60,7 @@ class FunctionClassDescriptor(
|
||||
|
||||
fun typeParameter(variance: Variance, name: String) {
|
||||
result.add(TypeParameterDescriptorImpl.createWithDefaultBound(
|
||||
this@FunctionClassDescriptor, Annotations.EMPTY, false, variance, Name.identifier(name), result.size
|
||||
this@FunctionClassDescriptor, Annotations.EMPTY, false, variance, Name.identifier(name), result.size, storageManager
|
||||
))
|
||||
}
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ private val FAKE_CONTINUATION_CLASS_DESCRIPTOR_EXPERIMENTAL =
|
||||
visibility = Visibilities.PUBLIC
|
||||
setTypeParameterDescriptors(
|
||||
TypeParameterDescriptorImpl.createWithDefaultBound(
|
||||
this, Annotations.EMPTY, false, Variance.IN_VARIANCE, Name.identifier("T"), 0
|
||||
this, Annotations.EMPTY, false, Variance.IN_VARIANCE, Name.identifier("T"), 0, LockBasedStorageManager.NO_LOCKS
|
||||
).let(::listOf)
|
||||
)
|
||||
createTypeConstructor()
|
||||
@@ -47,7 +47,7 @@ private val FAKE_CONTINUATION_CLASS_DESCRIPTOR_RELEASE =
|
||||
visibility = Visibilities.PUBLIC
|
||||
setTypeParameterDescriptors(
|
||||
TypeParameterDescriptorImpl.createWithDefaultBound(
|
||||
this, Annotations.EMPTY, false, Variance.IN_VARIANCE, Name.identifier("T"), 0
|
||||
this, Annotations.EMPTY, false, Variance.IN_VARIANCE, Name.identifier("T"), 0, LockBasedStorageManager.NO_LOCKS
|
||||
).let(::listOf)
|
||||
)
|
||||
createTypeConstructor()
|
||||
|
||||
@@ -53,7 +53,7 @@ class NotFoundClasses(private val storageManager: StorageManager, private val mo
|
||||
) : ClassDescriptorBase(storageManager, container, name, SourceElement.NO_SOURCE, /* isExternal = */ false) {
|
||||
private val typeParameters = (0 until numberOfDeclaredTypeParameters).map { index ->
|
||||
TypeParameterDescriptorImpl.createWithDefaultBound(
|
||||
this, Annotations.EMPTY, false, Variance.INVARIANT, Name.identifier("T$index"), index
|
||||
this, Annotations.EMPTY, false, Variance.INVARIANT, Name.identifier("T$index"), index, storageManager
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package org.jetbrains.kotlin.descriptors;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.kotlin.storage.StorageManager;
|
||||
import org.jetbrains.kotlin.types.KotlinType;
|
||||
import org.jetbrains.kotlin.types.TypeConstructor;
|
||||
import org.jetbrains.kotlin.types.Variance;
|
||||
@@ -53,4 +54,7 @@ public interface TypeParameterDescriptor extends ClassifierDescriptor, TypeParam
|
||||
* 3. 'getTypeConstructor' is the same as for original declaration (at least in means of 'equals')
|
||||
*/
|
||||
boolean isCapturedFromOuterDeclaration();
|
||||
|
||||
@NotNull
|
||||
StorageManager getStorageManager();
|
||||
}
|
||||
|
||||
+8
@@ -42,6 +42,7 @@ public abstract class AbstractTypeParameterDescriptor extends DeclarationDescrip
|
||||
|
||||
private final NotNullLazyValue<TypeConstructor> typeConstructor;
|
||||
private final NotNullLazyValue<SimpleType> defaultType;
|
||||
private final StorageManager storageManager;
|
||||
|
||||
protected AbstractTypeParameterDescriptor(
|
||||
@NotNull final StorageManager storageManager,
|
||||
@@ -82,6 +83,7 @@ public abstract class AbstractTypeParameterDescriptor extends DeclarationDescrip
|
||||
);
|
||||
}
|
||||
});
|
||||
this.storageManager = storageManager;
|
||||
}
|
||||
|
||||
protected abstract void reportSupertypeLoopError(@NotNull KotlinType type);
|
||||
@@ -139,6 +141,12 @@ public abstract class AbstractTypeParameterDescriptor extends DeclarationDescrip
|
||||
return visitor.visitTypeParameterDescriptor(this, data);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public StorageManager getStorageManager() {
|
||||
return storageManager;
|
||||
}
|
||||
|
||||
private class TypeParameterTypeConstructor extends AbstractTypeConstructor {
|
||||
|
||||
private final SupertypeLoopChecker supertypeLoopChecker;
|
||||
|
||||
+21
-13
@@ -26,7 +26,7 @@ import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations;
|
||||
import org.jetbrains.kotlin.name.Name;
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
||||
import org.jetbrains.kotlin.storage.LockBasedStorageManager;
|
||||
import org.jetbrains.kotlin.storage.StorageManager;
|
||||
import org.jetbrains.kotlin.types.KotlinType;
|
||||
import org.jetbrains.kotlin.types.KotlinTypeKt;
|
||||
import org.jetbrains.kotlin.types.Variance;
|
||||
@@ -47,10 +47,12 @@ public class TypeParameterDescriptorImpl extends AbstractTypeParameterDescriptor
|
||||
boolean reified,
|
||||
@NotNull Variance variance,
|
||||
@NotNull Name name,
|
||||
int index
|
||||
int index,
|
||||
@NotNull StorageManager storageManager
|
||||
) {
|
||||
TypeParameterDescriptorImpl typeParameterDescriptor =
|
||||
createForFurtherModification(containingDeclaration, annotations, reified, variance, name, index, SourceElement.NO_SOURCE);
|
||||
TypeParameterDescriptorImpl typeParameterDescriptor = createForFurtherModification(
|
||||
containingDeclaration, annotations, reified, variance, name, index, SourceElement.NO_SOURCE, storageManager
|
||||
);
|
||||
typeParameterDescriptor.addUpperBound(getBuiltIns(containingDeclaration).getDefaultBound());
|
||||
typeParameterDescriptor.setInitialized();
|
||||
return typeParameterDescriptor;
|
||||
@@ -63,10 +65,13 @@ public class TypeParameterDescriptorImpl extends AbstractTypeParameterDescriptor
|
||||
@NotNull Variance variance,
|
||||
@NotNull Name name,
|
||||
int index,
|
||||
@NotNull SourceElement source
|
||||
@NotNull SourceElement source,
|
||||
@NotNull StorageManager storageManager
|
||||
) {
|
||||
return createForFurtherModification(containingDeclaration, annotations, reified, variance, name, index, source,
|
||||
/* reportSupertypeLoopError = */ null, SupertypeLoopChecker.EMPTY.INSTANCE);
|
||||
return createForFurtherModification(
|
||||
containingDeclaration, annotations, reified, variance, name, index, source,
|
||||
null, SupertypeLoopChecker.EMPTY.INSTANCE, storageManager
|
||||
);
|
||||
}
|
||||
|
||||
public static TypeParameterDescriptorImpl createForFurtherModification(
|
||||
@@ -78,10 +83,13 @@ public class TypeParameterDescriptorImpl extends AbstractTypeParameterDescriptor
|
||||
int index,
|
||||
@NotNull SourceElement source,
|
||||
@Nullable Function1<KotlinType, Void> reportCycleError,
|
||||
@NotNull SupertypeLoopChecker supertypeLoopsResolver
|
||||
@NotNull SupertypeLoopChecker supertypeLoopsResolver,
|
||||
@NotNull StorageManager storageManager
|
||||
) {
|
||||
return new TypeParameterDescriptorImpl(containingDeclaration, annotations, reified, variance, name, index, source, reportCycleError,
|
||||
supertypeLoopsResolver);
|
||||
return new TypeParameterDescriptorImpl(
|
||||
containingDeclaration, annotations, reified, variance, name,
|
||||
index, source, reportCycleError, supertypeLoopsResolver, storageManager
|
||||
);
|
||||
}
|
||||
|
||||
private final List<KotlinType> upperBounds = new ArrayList<KotlinType>(1);
|
||||
@@ -96,10 +104,10 @@ public class TypeParameterDescriptorImpl extends AbstractTypeParameterDescriptor
|
||||
int index,
|
||||
@NotNull SourceElement source,
|
||||
@Nullable Function1<KotlinType, Void> reportCycleError,
|
||||
@NotNull SupertypeLoopChecker supertypeLoopsChecker
|
||||
@NotNull SupertypeLoopChecker supertypeLoopsChecker,
|
||||
@NotNull StorageManager storageManager
|
||||
) {
|
||||
super(LockBasedStorageManager.NO_LOCKS, containingDeclaration, annotations, name, variance, reified, index, source,
|
||||
supertypeLoopsChecker);
|
||||
super(storageManager, containingDeclaration, annotations, name, variance, reified, index, source, supertypeLoopsChecker);
|
||||
this.reportCycleError = reportCycleError;
|
||||
}
|
||||
|
||||
|
||||
@@ -40,7 +40,9 @@ public class DescriptorSubstitutor {
|
||||
@NotNull DeclarationDescriptor newContainingDeclaration,
|
||||
@NotNull @Mutable List<TypeParameterDescriptor> result
|
||||
) {
|
||||
TypeSubstitutor substitutor = substituteTypeParameters(typeParameters, originalSubstitution, newContainingDeclaration, result, null);
|
||||
TypeSubstitutor substitutor = substituteTypeParameters(
|
||||
typeParameters, originalSubstitution, newContainingDeclaration, result, null
|
||||
);
|
||||
if (substitutor == null) throw new AssertionError("Substitution failed");
|
||||
return substitutor;
|
||||
}
|
||||
@@ -65,7 +67,8 @@ public class DescriptorSubstitutor {
|
||||
descriptor.getVariance(),
|
||||
descriptor.getName(),
|
||||
index++,
|
||||
SourceElement.NO_SOURCE
|
||||
SourceElement.NO_SOURCE,
|
||||
descriptor.getStorageManager()
|
||||
);
|
||||
|
||||
mutableSubstitution.put(descriptor.getTypeConstructor(), new TypeProjectionImpl(substituted.getDefaultType()));
|
||||
|
||||
Reference in New Issue
Block a user