Skip to content

Commit 5c28ca1

Browse files
committed
Consider GADT bounds for findMember and underlying
The `findMember` and `underlying` methods on `TermRef` now take GADT bounds into account. This replaces the previous special case in `secectionType`. The previous case did always pass -Ycheck. Currently, the treatment is restricted to TypeRefs of opaque types. We should extend that to all GADT-bound TypeRefs. The question is how this will affect performance.
1 parent 7fa5107 commit 5c28ca1

File tree

2 files changed

+23
-19
lines changed

2 files changed

+23
-19
lines changed

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

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -508,7 +508,9 @@ object Types {
508508
case tp1 => tp1
509509
})
510510
case tp: TypeRef =>
511-
tp.denot.findMember(name, pre, excluded)
511+
val mbr = tp.denot.findMember(name, pre, excluded)
512+
if (mbr.exists) mbr
513+
else followGADT.findMember(name, pre, excluded)
512514
case tp: AppliedType =>
513515
goApplied(tp)
514516
case tp: ThisType =>
@@ -2132,7 +2134,13 @@ object Types {
21322134
override def designator = myDesignator
21332135
override protected def designator_=(d: Designator) = myDesignator = d
21342136

2135-
override def underlying(implicit ctx: Context): Type = info
2137+
override def underlying(implicit ctx: Context): Type = {
2138+
if (symbol.is(Opaque)) {
2139+
val gadtBounds = ctx.gadt.bounds(symbol)
2140+
if (gadtBounds != null) return gadtBounds
2141+
}
2142+
info
2143+
}
21362144
}
21372145

21382146
final class CachedTermRef(prefix: Type, designator: Designator, hc: Int) extends TermRef(prefix, designator) {

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

Lines changed: 13 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -233,25 +233,21 @@ trait TypeAssigner {
233233
*/
234234
def selectionType(site: Type, name: Name, pos: Position)(implicit ctx: Context): Type = {
235235
val mbr = site.member(name)
236-
if (reallyExists(mbr)) site.select(name, mbr)
237-
else if (site.derivesFrom(defn.DynamicClass) && !Dynamic.isDynamicMethod(name)) {
236+
if (reallyExists(mbr))
237+
site.select(name, mbr)
238+
else if (site.derivesFrom(defn.DynamicClass) && !Dynamic.isDynamicMethod(name))
238239
TryDynamicCallType
239-
}
240+
else if (site.isErroneous || name.toTermName == nme.ERROR)
241+
UnspecifiedErrorType
240242
else {
241-
val site1 = site.followGADT
242-
if (site1.exists) selectionType(site1, name, pos)
243-
else if (site.isErroneous || name.toTermName == nme.ERROR)
244-
UnspecifiedErrorType
245-
else {
246-
def kind = if (name.isTypeName) "type" else "value"
247-
def addendum =
248-
if (site.derivesFrom(defn.DynamicClass)) "\npossible cause: maybe a wrong Dynamic method signature?"
249-
else ""
250-
errorType(
251-
if (name == nme.CONSTRUCTOR) ex"$site does not have a constructor"
252-
else NotAMember(site, name, kind),
253-
pos)
254-
}
243+
def kind = if (name.isTypeName) "type" else "value"
244+
def addendum =
245+
if (site.derivesFrom(defn.DynamicClass)) "\npossible cause: maybe a wrong Dynamic method signature?"
246+
else ""
247+
errorType(
248+
if (name == nme.CONSTRUCTOR) ex"$site does not have a constructor"
249+
else NotAMember(site, name, kind),
250+
pos)
255251
}
256252
}
257253

0 commit comments

Comments
 (0)