Skip to content

Commit c3be793

Browse files
committed
Fix scala#10123: Try to fully define qualifier type
Try to fully define qualifier type before emitting an error for a typed Select. The one possible objection to doing this is that it might hide other errors where a type was not sufficiently well defined before we select on it. On the other hand: - My comment in issue scala#10123 shows that the problem is more widespread than just a single case. - We otherwise rely on interpolation to instantiate type variables in many cases. But interpolation is meant as an optimization only, to keep constraint sets smaller. So, we should be prepared that interpolation will not do its job. The fix in this commit is a way to do so.
1 parent eddd4da commit c3be793

File tree

2 files changed

+23
-0
lines changed

2 files changed

+23
-0
lines changed

compiler/src/dotty/tools/dotc/typer/TypeAssigner.scala

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import config.Printers.typr
1212
import ast.Trees._
1313
import NameOps._
1414
import ProtoTypes._
15+
import Inferencing.isFullyDefined
1516
import collection.mutable
1617
import reporting._
1718
import Checking.{checkNoPrivateLeaks, checkNoWildcard}
@@ -159,6 +160,9 @@ trait TypeAssigner {
159160
TryDynamicCallType
160161
else if (qualType.isErroneous || name.toTermName == nme.ERROR)
161162
UnspecifiedErrorType
163+
else if !isFullyDefined(qualType, ForceDegree.none) && isFullyDefined(qualType, ForceDegree.failBottom) then
164+
// try again with more defined qualifier type
165+
selectionType(tree, qual1)
162166
else if (name == nme.CONSTRUCTOR)
163167
errorType(ex"$qualType does not have a constructor", tree.srcPos)
164168
else {

tests/pos/i10123.scala

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
class D
2+
class C[+T](x: T)
3+
4+
class Foo() {
5+
val status: Int = 0
6+
}
7+
8+
object Main {
9+
implicit class RichC[T](c: C[T]) {
10+
def await(implicit d: D = ???): T = ???
11+
}
12+
13+
def test1: Int = {
14+
val foo = new C(new Foo()).await
15+
foo.status
16+
}
17+
18+
val test2 = new C(new Foo()).await.status
19+
}

0 commit comments

Comments
 (0)