Skip to content

Commit 5b96cba

Browse files
committed
add test for subtyping
1 parent 9dfdf36 commit 5b96cba

File tree

4 files changed

+53
-3
lines changed

4 files changed

+53
-3
lines changed

compiler/src/dotty/tools/dotc/ast/TreeInfo.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -672,7 +672,7 @@ trait TypedTreeInfo extends TreeInfo[Type] { self: Trees.Instance[Type] =>
672672
def isStructuralTermSelect(tree: Tree)(implicit ctx: Context) = tree match {
673673
case tree: Select =>
674674
def hasRefinement(qualtpe: Type): Boolean = qualtpe.dealias match {
675-
case RefinedType(parent, rname, rinfo) =>
675+
case tp @ RefinedType(parent, rname, rinfo) if !tp.isDependent =>
676676
rname == tree.name || hasRefinement(parent)
677677
case tp: TypeProxy =>
678678
hasRefinement(tp.underlying)

compiler/src/dotty/tools/dotc/core/SymDenotations.scala

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1665,8 +1665,7 @@ object SymDenotations {
16651665
case tparams: List[Symbol @unchecked] =>
16661666
baseTypeOf(tycon).subst(tparams, args)
16671667
}
1668-
case tp @ RefinedType(parent, name, AnnotatedType(refine, annot))
1669-
if annot.symbol eq defn.DependentAnnot =>
1668+
case tp @ RefinedType(parent, name, refine) if tp.isDependent =>
16701669
val res = baseTypeOf(tp.superType)
16711670
res.subst(tp.nonPrivateMember(name).symbol :: Nil, refine :: Nil)
16721671
case tp: TypeProxy =>

compiler/src/dotty/tools/dotc/core/Types.scala

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2255,6 +2255,12 @@ object Types {
22552255
if (parent.member(refinedName).exists) derivedRefinedType(parent, refinedName, refinedInfo)
22562256
else parent
22572257

2258+
/** Is current type a dependent class refinement, i.e. { val x: T @dependent } ? */
2259+
def isDependent(implicit ctx: Context): Boolean = refinedInfo match {
2260+
case AnnotatedType(_, annot) => annot.symbol eq defn.DependentAnnot
2261+
case _ => false
2262+
}
2263+
22582264
override def computeHash = doHash(refinedName, refinedInfo, parent)
22592265

22602266
override def eql(that: Type) = that match {

tests/neg/dependent-subtype.scala

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import scala.annotation.dependent
2+
3+
trait Foo {
4+
type Bar
5+
}
6+
7+
class Quux(@dependent val foo: Foo)
8+
class Child1(@dependent override val foo: Foo) extends Quux(foo)
9+
class Child2(override val foo: Foo) extends Quux(foo)
10+
class Child3(foo: Foo) extends Quux(foo)
11+
12+
object FooInt extends Foo {
13+
type Bar = Int
14+
}
15+
16+
object Test {
17+
val quux1 = new Child1(FooInt)
18+
val x1: quux1.foo.Bar = 3 // ok
19+
20+
val quux2 = new Child2(FooInt)
21+
val x2: quux2.foo.Bar = 3 // error
22+
23+
val quux3 = new Child3(FooInt)
24+
val x3: quux3.foo.Bar = 3 // error
25+
}
26+
27+
28+
object Test2 {
29+
trait C
30+
class D extends C
31+
class E extends D
32+
33+
class Bar(@dependent o: C)
34+
35+
val x1 = new Bar(new D)
36+
val d: D = x1.o // ok
37+
38+
val x2 = new Bar(new E)
39+
val e: E = x2.o // ok
40+
41+
def f(x: Int): E = ???
42+
43+
val x3 = new Bar(f(5))
44+
val e2: E = x3.o // ok
45+
}

0 commit comments

Comments
 (0)