Skip to content

Commit f657399

Browse files
committed
Avoid premature widening of type in recheckSelection
1 parent 1d0cdf9 commit f657399

File tree

3 files changed

+17
-8
lines changed

3 files changed

+17
-8
lines changed

compiler/src/dotty/tools/dotc/cc/CheckCaptures.scala

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,7 @@ class CheckCaptures extends Recheck, SymTransformer:
288288
* outcome of a `mightSubcapture` test. It picks `{f}` if this might subcapture Cr
289289
* and Cr otherwise.
290290
*/
291-
override def recheckSelection(tree: Select, qualType: Type, name: Name)(using Context) = {
291+
override def recheckSelection(tree: Select, qualType: Type, name: Name, pt: Type)(using Context) = {
292292
def disambiguate(denot: Denotation): Denotation = denot match
293293
case MultiDenotation(denot1, denot2) =>
294294
// This case can arise when we try to merge multiple types that have different
@@ -310,8 +310,12 @@ class CheckCaptures extends Recheck, SymTransformer:
310310
else
311311
val qualCs = qualType.captureSet
312312
capt.println(i"intersect $qualType, ${selType.widen}, $qualCs, $selCs in $tree")
313-
if qualCs.mightSubcapture(selCs) then
313+
if qualCs.mightSubcapture(selCs)
314+
&& !selCs.mightSubcapture(qualCs)
315+
&& !pt.stripCapturing.isInstanceOf[SingletonType]
316+
then
314317
selType.widen.stripCapturing.capturing(qualCs)
318+
.showing(i"alternate type for select $tree: $selType --> $result, $qualCs / $selCs", capt)
315319
else
316320
selType
317321
}//.showing(i"recheck sel $tree, $qualType = $result")

compiler/src/dotty/tools/dotc/transform/Recheck.scala

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import util.Property
2121
import StdNames.nme
2222
import reporting.trace
2323
import annotation.constructorOnly
24+
import cc.CaptureSet.IdempotentCaptRefMap
2425

2526
object Recheck:
2627
import tpd.*
@@ -144,9 +145,9 @@ abstract class Recheck extends Phase, SymTransformer:
144145
def recheckIdent(tree: Ident)(using Context): Type =
145146
tree.tpe
146147

147-
def recheckSelect(tree: Select)(using Context): Type =
148+
def recheckSelect(tree: Select, pt: Type)(using Context): Type =
148149
val Select(qual, name) = tree
149-
recheckSelection(tree, recheck(qual).widenIfUnstable, name)
150+
recheckSelection(tree, recheck(qual).widenIfUnstable, name, pt)
150151

151152
def recheckSelection(tree: Select, qualType: Type, name: Name,
152153
sharpen: Denotation => Denotation)(using Context): Type =
@@ -162,8 +163,8 @@ abstract class Recheck extends Phase, SymTransformer:
162163

163164

164165
/** Keep the symbol of the `select` but re-infer its type */
165-
def recheckSelection(tree: Select, qualType: Type, name: Name)(using Context): Type =
166-
recheckSelection(tree, qualType, name, sharpen = identity)
166+
def recheckSelection(tree: Select, qualType: Type, name: Name, pt: Type)(using Context): Type =
167+
recheckSelection(tree, qualType, name, sharpen = identity[Denotation])
167168

168169
def recheckBind(tree: Bind, pt: Type)(using Context): Type = tree match
169170
case Bind(name, body) =>
@@ -200,7 +201,7 @@ abstract class Recheck extends Phase, SymTransformer:
200201
* to FromJavaObject since it got lost in ElimRepeated
201202
*/
202203
private def mapJavaArgs(formals: List[Type])(using Context): List[Type] =
203-
val tm = new TypeMap:
204+
val tm = new TypeMap with IdempotentCaptRefMap:
204205
def apply(t: Type) = t match
205206
case t: TypeRef if t.symbol == defn.ObjectClass => defn.FromJavaObjectType
206207
case _ => mapOver(t)
@@ -357,7 +358,7 @@ abstract class Recheck extends Phase, SymTransformer:
357358
val sym = tree.symbol
358359
tree match
359360
case tree: Ident => recheckIdent(tree)
360-
case tree: Select => recheckSelect(tree)
361+
case tree: Select => recheckSelect(tree, pt)
361362
case tree: Bind => recheckBind(tree, pt)
362363
case tree: ValOrDefDef =>
363364
if tree.isEmpty then NoType
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
enum E:
2+
3+
case A extends E
4+

0 commit comments

Comments
 (0)