KT-597 Type inference failed
Resolution rules changed: now autocast and non-autocast candidates are judged together
This commit is contained in:
@@ -64,20 +64,8 @@ import static org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor
|
|||||||
scope = explicitReceiver.getType().getMemberScope();
|
scope = explicitReceiver.getType().getMemberScope();
|
||||||
explicitReceiver = NO_RECEIVER;
|
explicitReceiver = NO_RECEIVER;
|
||||||
}
|
}
|
||||||
doComputeTasks(scope, explicitReceiver, call, name, result, AutoCastService.NO_AUTO_CASTS);
|
doComputeTasks(scope, explicitReceiver, call, name, result, new AutoCastServiceImpl(dataFlowInfo, bindingContext));
|
||||||
|
|
||||||
List<ReceiverDescriptor> receivers;
|
|
||||||
if (explicitReceiver.exists()) {
|
|
||||||
receivers = Collections.singletonList(explicitReceiver);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
receivers = Lists.newArrayList();
|
|
||||||
scope.getImplicitReceiversHierarchy(receivers);
|
|
||||||
}
|
|
||||||
for (ReceiverDescriptor receiverToCast : receivers) {
|
|
||||||
assert receiverToCast.exists();
|
|
||||||
doComputeTasks(scope, receiverToCast, call, name, result, new AutoCastServiceImpl(dataFlowInfo, bindingContext));
|
|
||||||
}
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -87,7 +75,7 @@ import static org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor
|
|||||||
scope.getImplicitReceiversHierarchy(implicitReceivers);
|
scope.getImplicitReceiversHierarchy(implicitReceivers);
|
||||||
if (receiver.exists()) {
|
if (receiver.exists()) {
|
||||||
List<ReceiverDescriptor> variantsForExplicitReceiver = autoCastService.getVariantsForReceiver(receiver);
|
List<ReceiverDescriptor> variantsForExplicitReceiver = autoCastService.getVariantsForReceiver(receiver);
|
||||||
|
|
||||||
Collection<ResolvedCallImpl<D>> extensionFunctions = convertWithImpliedThis(scope, variantsForExplicitReceiver, getExtensionsByName(scope, name));
|
Collection<ResolvedCallImpl<D>> extensionFunctions = convertWithImpliedThis(scope, variantsForExplicitReceiver, getExtensionsByName(scope, name));
|
||||||
List<ResolvedCallImpl<D>> nonlocals = Lists.newArrayList();
|
List<ResolvedCallImpl<D>> nonlocals = Lists.newArrayList();
|
||||||
List<ResolvedCallImpl<D>> locals = Lists.newArrayList();
|
List<ResolvedCallImpl<D>> locals = Lists.newArrayList();
|
||||||
|
|||||||
+4
-1
@@ -1,5 +1,6 @@
|
|||||||
package org.jetbrains.jet.lang.resolve.calls.autocasts;
|
package org.jetbrains.jet.lang.resolve.calls.autocasts;
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||||
@@ -21,7 +22,9 @@ public class AutoCastServiceImpl implements AutoCastService {
|
|||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public List<ReceiverDescriptor> getVariantsForReceiver(@NotNull ReceiverDescriptor receiverDescriptor) {
|
public List<ReceiverDescriptor> getVariantsForReceiver(@NotNull ReceiverDescriptor receiverDescriptor) {
|
||||||
return AutoCastUtils.getAutoCastVariants(bindingContext, dataFlowInfo, receiverDescriptor);
|
List<ReceiverDescriptor> variants = Lists.newArrayList(AutoCastUtils.getAutoCastVariants(bindingContext, dataFlowInfo, receiverDescriptor));
|
||||||
|
variants.add(receiverDescriptor);
|
||||||
|
return variants;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
|
|||||||
+3
@@ -17,6 +17,9 @@ public class AutoCastUtils {
|
|||||||
|
|
||||||
private AutoCastUtils() {}
|
private AutoCastUtils() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return variants @param receiverToCast may be cast to according to @param dataFlowInfo, @param receiverToCast itself is NOT included
|
||||||
|
*/
|
||||||
public static List<ReceiverDescriptor> getAutoCastVariants(@NotNull final BindingContext bindingContext, @NotNull final DataFlowInfo dataFlowInfo, @NotNull ReceiverDescriptor receiverToCast) {
|
public static List<ReceiverDescriptor> getAutoCastVariants(@NotNull final BindingContext bindingContext, @NotNull final DataFlowInfo dataFlowInfo, @NotNull ReceiverDescriptor receiverToCast) {
|
||||||
return receiverToCast.accept(new ReceiverDescriptorVisitor<List<ReceiverDescriptor>, Object>() {
|
return receiverToCast.accept(new ReceiverDescriptorVisitor<List<ReceiverDescriptor>, Object>() {
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
+1
-1
@@ -102,7 +102,7 @@ public class DataFlowInfo {
|
|||||||
|
|
||||||
boolean changed = false;
|
boolean changed = false;
|
||||||
changed |= putNullability(builder, a, nullabilityOfA.refine(nullabilityOfB.invert()));
|
changed |= putNullability(builder, a, nullabilityOfA.refine(nullabilityOfB.invert()));
|
||||||
changed |= putNullability(builder, b, nullabilityOfA.refine(nullabilityOfA.invert()));
|
changed |= putNullability(builder, b, nullabilityOfB.refine(nullabilityOfA.invert()));
|
||||||
return changed ? new DataFlowInfo(ImmutableMap.copyOf(builder), typeInfo) : this;
|
return changed ? new DataFlowInfo(ImmutableMap.copyOf(builder), typeInfo) : this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
//KT-597 Type inference failed
|
||||||
|
// +JDK
|
||||||
|
|
||||||
|
fun <T> Array<T>?.get(i: Int) : T {
|
||||||
|
if (this != null)
|
||||||
|
return this.get(i) // <- inferred type is Any? but &T was excepted
|
||||||
|
else throw NullPointerException()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Int?.inc() : Int {
|
||||||
|
if (this != null)
|
||||||
|
return this.inc()
|
||||||
|
else
|
||||||
|
throw NullPointerException()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
var i : Int? = 10
|
||||||
|
var <!UNUSED_VARIABLE!>i_inc<!> = <!UNUSED_CHANGED_VALUE!>i++<!> // <- expected Int?, but returns Any?
|
||||||
|
}
|
||||||
@@ -216,7 +216,7 @@ fun declarationInsidePattern(x: (Any, Any)): String = when(x) { is (val a is Str
|
|||||||
fun mergeAutocasts(a: Any?) {
|
fun mergeAutocasts(a: Any?) {
|
||||||
if (a is String || a is Int) {
|
if (a is String || a is Int) {
|
||||||
a.<error descr="Unresolved reference: compareTo">compareTo</error>("")
|
a.<error descr="Unresolved reference: compareTo">compareTo</error>("")
|
||||||
a.toString()
|
<info descr="Automatically cast to Any">a</info>.toString()
|
||||||
}
|
}
|
||||||
if (a is Int || a is String) {
|
if (a is Int || a is String) {
|
||||||
a.<error descr="Unresolved reference: compareTo">compareTo</error>("")
|
a.<error descr="Unresolved reference: compareTo">compareTo</error>("")
|
||||||
|
|||||||
Reference in New Issue
Block a user