Repository: intellij-rust/intellij-rust
Issue: CCE while type inference

Sometimes I get such exception:

<details><summary>stacktrace</summary>
<p>

```
java.lang.ClassCastException: org.rust.lang.core.types.ty.TyInfer$IntVar cannot be cast to org.rust.lang.core.types.infer.VarValue
	at org.rust.lang.core.types.infer.UnificationTable$Root.<init>(Unify.kt:34)
	at org.rust.lang.core.types.infer.UnificationTable.get(Unify.kt:49)
	at org.rust.lang.core.types.infer.UnificationTable.get(Unify.kt:42)
	at org.rust.lang.core.types.infer.UnificationTable.findValue(Unify.kt:83)
	at org.rust.lang.core.types.infer.RsInferenceContext.shallowResolve(TypeInference.kt:351)
	at org.rust.lang.core.types.infer.RsInferenceContext.combineTypes(TypeInference.kt:249)
	at org.rust.lang.core.types.infer.RsInferenceContext.combinePairs(TypeInference.kt:335)
	at org.rust.lang.core.resolve.ImplLookup.confirmCandidate(ImplLookup.kt:468)
	at org.rust.lang.core.resolve.ImplLookup.select(ImplLookup.kt:321)
	at org.rust.lang.core.resolve.ImplLookup.selectProjection(ImplLookup.kt:527)
	at org.rust.lang.core.resolve.ImplLookup.selectProjection$default(ImplLookup.kt:525)
	at org.rust.lang.core.resolve.ImplLookup.selectProjection(ImplLookup.kt:519)
	at org.rust.lang.core.resolve.ImplLookup.findArithmeticBinaryExprOutputType(ImplLookup.kt:510)
	at org.rust.lang.core.types.infer.RsFnInferenceContext.inferBinaryExprType(TypeInference.kt:1251)
	at org.rust.lang.core.types.infer.RsFnInferenceContext.inferType(TypeInference.kt:632)
	at org.rust.lang.core.types.infer.RsFnInferenceContext.inferType$default(TypeInference.kt:612)
	at org.rust.lang.core.types.infer.RsFnInferenceContext.inferBinaryExprType(TypeInference.kt:1249)
	at org.rust.lang.core.types.infer.RsFnInferenceContext.inferType(TypeInference.kt:632)
	at org.rust.lang.core.types.infer.RsFnInferenceContext.inferType$default(TypeInference.kt:612)
	at org.rust.lang.core.types.infer.RsFnInferenceContext.processStatement(TypeInference.kt:603)
	at org.rust.lang.core.types.infer.RsFnInferenceContext.inferType(TypeInference.kt:590)
	at org.rust.lang.core.types.infer.RsFnInferenceContext.inferType$default(TypeInference.kt:587)
	at org.rust.lang.core.types.infer.RsFnInferenceContext.inferForExprType(TypeInference.kt:1167)
	at org.rust.lang.core.types.infer.RsFnInferenceContext.inferType(TypeInference.kt:629)
	at org.rust.lang.core.types.infer.RsFnInferenceContext.inferTypeCoercableTo(TypeInference.kt:650)
	at org.rust.lang.core.types.infer.RsFnInferenceContext.inferType(TypeInference.kt:592)
	at org.rust.lang.core.types.infer.RsFnInferenceContext.inferTypeCoercableTo(TypeInference.kt:585)
	at org.rust.lang.core.types.infer.RsFnInferenceContext.inferFnBody(TypeInference.kt:573)
	at org.rust.lang.core.types.infer.RsInferenceContext.infer(TypeInference.kt:127)
	at org.rust.lang.core.types.infer.TypeInferenceKt$inferTypesIn$1.compute(TypeInference.kt:41)
	at org.rust.lang.core.types.infer.TypeInferenceKt$inferTypesIn$1.compute(TypeInference.kt)
	at com.intellij.openapi.util.RecursionManager$2.doPreventingRecursion(RecursionManager.java:113)
	at com.intellij.openapi.util.RecursionManager.doPreventingRecursion(RecursionManager.java:68)
	at org.rust.openapiext.UtilsKt.recursionGuard(utils.kt:45)
	at org.rust.openapiext.UtilsKt.recursionGuard$default(utils.kt:44)
	at org.rust.lang.core.types.infer.TypeInferenceKt.inferTypesIn(TypeInference.kt:41)
	at org.rust.lang.core.types.ExtensionsKt$inference$1.compute(Extensions.kt:36)
	at com.intellij.psi.util.CachedValuesManager.lambda$getCachedValue$0(CachedValuesManager.java:140)
	at com.intellij.psi.impl.PsiCachedValueImpl.doCompute(PsiCachedValueImpl.java:49)
	at com.intellij.util.CachedValueBase.getValueWithLock(CachedValueBase.java:222)
	at com.intellij.psi.impl.PsiCachedValue.getValueWithLock(PsiCachedValue.java:60)
	at com.intellij.psi.impl.PsiCachedValueImpl.getValue(PsiCachedValueImpl.java:38)
	at com.intellij.psi.util.CachedValuesManager.getCachedValue(CachedValuesManager.java:136)
	at com.intellij.psi.util.CachedValuesManager.getCachedValue(CachedValuesManager.java:126)
	at org.rust.lang.core.types.ExtensionsKt.getInference(Extensions.kt:35)
	at org.rust.lang.core.types.ExtensionsKt.getInference(Extensions.kt:93)
	at org.rust.lang.core.types.ExtensionsKt.getType(Extensions.kt:43)
	at org.rust.ide.annotator.RsHighlightingMutableAnnotatorKt.isMut(RsHighlightingMutableAnnotator.kt:80)
	at org.rust.ide.annotator.RsHighlightingMutableAnnotator.distinctAnnotation(RsHighlightingMutableAnnotator.kt:52)
	at org.rust.ide.annotator.RsHighlightingMutableAnnotator.annotate(RsHighlightingMutableAnnotator.kt:37)
	at com.intellij.codeInsight.daemon.impl.DefaultHighlightVisitor.a(DefaultHighlightVisitor.java:139)
	at com.intellij.codeInsight.daemon.impl.DefaultHighlightVisitor.visit(DefaultHighlightVisitor.java:102)
	at com.intellij.codeInsight.daemon.impl.GeneralHighlightingPass.a(GeneralHighlightingPass.java:366)
	at com.intellij.codeInsight.daemon.impl.GeneralHighlightingPass.a(GeneralHighlightingPass.java:298)
	at com.intellij.codeInsight.daemon.impl.GeneralHighlightingPass.a(GeneralHighlightingPass.java:325)
	at com.intellij.codeInsight.daemon.impl.GeneralHighlightingPass.a(GeneralHighlightingPass.java:328)
	at com.intellij.codeInsight.daemon.impl.DefaultHighlightVisitor.analyze(DefaultHighlightVisitor.java:86)
	at com.intellij.codeInsight.daemon.impl.GeneralHighlightingPass.a(GeneralHighlightingPass.java:328)
	at com.intellij.codeInsight.daemon.impl.GeneralHighlightingPass.a(GeneralHighlightingPass.java:295)
	at com.intellij.codeInsight.daemon.impl.GeneralHighlightingPass.collectInformationWithProgress(GeneralHighlightingPass.java:238)
	at com.intellij.codeInsight.daemon.impl.ProgressableTextEditorHighlightingPass.doCollectInformation(ProgressableTextEditorHighlightingPass.java:83)
	at com.intellij.codeHighlighting.TextEditorHighlightingPass.collectInformation(TextEditorHighlightingPass.java:69)
	at com.intellij.codeInsight.daemon.impl.PassExecutorService$ScheduledPass.c(PassExecutorService.java:423)
	at com.intellij.openapi.application.impl.ApplicationImpl.tryRunReadAction(ApplicationImpl.java:1152)
	at com.intellij.codeInsight.daemon.impl.PassExecutorService$ScheduledPass.d(PassExecutorService.java:416)
	at com.intellij.openapi.progress.impl.CoreProgressManager.a(CoreProgressManager.java:580)
	at com.intellij.openapi.progress.impl.CoreProgressManager.executeProcessUnderProgress(CoreProgressManager.java:525)
	at com.intellij.openapi.progress.impl.ProgressManagerImpl.executeProcessUnderProgress(ProgressManagerImpl.java:85)
	at com.intellij.codeInsight.daemon.impl.PassExecutorService$ScheduledPass.a(PassExecutorService.java:415)
	at com.intellij.codeInsight.daemon.impl.PassExecutorService$ScheduledPass.e(PassExecutorService.java:391)
	at com.intellij.openapi.application.impl.ReadMostlyRWLock.executeByImpatientReader(ReadMostlyRWLock.java:147)
	at com.intellij.openapi.application.impl.ApplicationImpl.executeByImpatientReader(ApplicationImpl.java:218)
	at com.intellij.codeInsight.daemon.impl.PassExecutorService$ScheduledPass.run(PassExecutorService.java:389)
	at com.intellij.concurrency.JobLauncherImpl$VoidForkJoinTask$1.exec(JobLauncherImpl.java:161)
	at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
	at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056)
	at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692)
	at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)
```

</p>
</details>

**Environment**:
CLion 2018.2 EAP
Build #CL-182.2574.4, built on May 22, 2018
JRE: 1.8.0_152-release-1226-b7 x86_64
JVM: OpenJDK 64-Bit Server VM by JetBrains s.r.o
macOS 10.13.4

I don't have steps to reproduce it, but I was typing the following code
```rust
fn main() {
    for i in 0..16 {
        let x = i * 2 + 1;
        println!("{}", x);
    }
}
```
when I got such exception last time

Changed files:
src/main/kotlin/org/rust/lang/core/types/infer/Fold.kt, src/main/kotlin/org/rust/lang/core/resolve/ImplLookup.kt

diff --git a/src/main/kotlin/org/rust/lang/core/resolve/ImplLookup.kt b/src/main/kotlin/org/rust/lang/core/resolve/ImplLookup.kt
index f494921f6..23c92d5c2 100644
--- a/src/main/kotlin/org/rust/lang/core/resolve/ImplLookup.kt
+++ b/src/main/kotlin/org/rust/lang/core/resolve/ImplLookup.kt
@@ -413,7 +413,7 @@ class ImplLookup(
                 }
                 getHardcodedImpls(ref.selfTy).filter { be ->
                     be.element == element && ctx.probe { ctx.combinePairs(zipValues(be.subst, ref.trait.subst)) }
-                }.forEach { add(SelectionCandidate.TypeParameter(it)) }
+                }.forEach { add(SelectionCandidate.HardcodedImpl) }
             }
         }
     }
@@ -458,6 +458,8 @@ class ImplLookup(
         val newRecDepth = recursionDepth + 1
         return when (candidate) {
             is SelectionCandidate.Impl -> {
+                assert(!candidate.formalSelfTy.containsTyOfClass(TyInfer::class.java))
+                assert(!candidate.formalTrait.containsTyOfClass(TyInfer::class.java))
                 val (subst, preparedRef) = candidate.prepareSubstAndTraitRef(ctx, ref.selfTy)
                 ctx.combineTraitRefs(ref, preparedRef)
                 // pre-resolve type vars to simplify caching of already inferred obligation on fulfillment
@@ -474,10 +476,19 @@ class ImplLookup(
                 Selection(trait, emptyList())
             }
             is SelectionCandidate.TypeParameter -> {
+                assert(!candidate.bound.containsTyOfClass(TyInfer::class.java))
                 ctx.combinePairs(zipValues(candidate.bound.subst, ref.trait.subst))
                 ctx.combinePairs(zipValues(candidate.bound.assoc, ref.trait.assoc))
                 Selection(candidate.bound.element, emptyList())
             }
+            is SelectionCandidate.HardcodedImpl -> {
+                val impl = getHardcodedImpls(ref.selfTy).first { be ->
+                    be.element == ref.trait.element && ctx.probe { ctx.combinePairs(zipValues(be.subst, ref.trait.subst)) }
+                }
+                ctx.combinePairs(zipValues(impl.subst, ref.trait.subst))
+                ctx.combinePairs(zipValues(impl.assoc, ref.trait.assoc))
+                Selection(impl.element, emptyList())
+            }
         }
     }
 
@@ -709,6 +720,8 @@ private sealed class SelectionCandidate {
 
     data class DerivedTrait(val item: RsTraitItem) : SelectionCandidate()
     data class TypeParameter(val bound: BoundElement<RsTraitItem>) : SelectionCandidate()
+    /** @see ImplLookup.getHardcodedImpls */
+    object HardcodedImpl : SelectionCandidate()
     object Closure : SelectionCandidate()
 }
 
diff --git a/src/main/kotlin/org/rust/lang/core/types/infer/Fold.kt b/src/main/kotlin/org/rust/lang/core/types/infer/Fold.kt
index a7a6dd397..03033f8e3 100644
--- a/src/main/kotlin/org/rust/lang/core/types/infer/Fold.kt
+++ b/src/main/kotlin/org/rust/lang/core/types/infer/Fold.kt
@@ -99,6 +99,9 @@ fun <T> TypeFoldable<T>.containsTyOfClass(classes: List<Class<*>>): Boolean =
             if (classes.any { it.isInstance(ty) }) true else ty.superVisitWith(this)
     })
 
+fun <T> TypeFoldable<T>.containsTyOfClass(vararg classes: Class<*>): Boolean =
+    containsTyOfClass(classes.toList())
+
 fun <T> TypeFoldable<T>.collectInferTys(): List<TyInfer> {
     val list = mutableListOf<TyInfer>()
     visitWith(object : TypeVisitor {