Skip to content

Commit 00a4ee0

Browse files
authored
Merge pull request #12201 from dotty-staging/fix-12169
Don't use `_` as a binder for abstract type arguments in patterns
2 parents a9c2e46 + 32e287f commit 00a4ee0

File tree

8 files changed

+63
-14
lines changed

8 files changed

+63
-14
lines changed

compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,7 @@ class PlainPrinter(_ctx: Context) extends Printer {
257257
Text(lam.paramNames.lazyZip(lam.paramInfos).map(paramText), ", ")
258258
}
259259

260-
protected def ParamRefNameString(name: Name): String = name.toString
260+
protected def ParamRefNameString(name: Name): String = nameString(name)
261261

262262
protected def ParamRefNameString(param: ParamRef): String =
263263
ParamRefNameString(param.binder.paramNames(param.paramNum))

compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import typer.ProtoTypes._
2020
import Trees._
2121
import TypeApplications._
2222
import Decorators._
23+
import NameKinds.WildcardParamName
2324
import util.Chars.isOperatorPart
2425
import transform.TypeUtils._
2526
import transform.SymUtils._
@@ -76,8 +77,8 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
7677
}
7778

7879
override def nameString(name: Name): String =
79-
if ctx.settings.YdebugNames.value
80-
then name.debugString
80+
if ctx.settings.YdebugNames.value then name.debugString
81+
else if name.isTypeName && name.is(WildcardParamName) && !printDebug then "_"
8182
else super.nameString(name)
8283

8384
override protected def simpleNameString(sym: Symbol): String =
@@ -963,9 +964,6 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
963964
def optText[T >: Untyped](tree: List[Tree[T]])(encl: Text => Text): Text =
964965
if (tree.exists(!_.isEmpty)) encl(blockText(tree)) else ""
965966

966-
override protected def ParamRefNameString(name: Name): String =
967-
name.toString
968-
969967
override protected def treatAsTypeParam(sym: Symbol): Boolean = sym.is(TypeParam)
970968

971969
override protected def treatAsTypeArg(sym: Symbol): Boolean =

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

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1560,9 +1560,9 @@ class Typer extends Namer
15601560
super.transform(trt.withType(stripTypeVars(trt.tpe))) match {
15611561
case b: Bind =>
15621562
val sym = b.symbol
1563-
if (sym.name != tpnme.WILDCARD)
1564-
if (ctx.scope.lookup(b.name) == NoSymbol) ctx.enter(sym)
1565-
else report.error(new DuplicateBind(b, cdef), b.srcPos)
1563+
assert(sym.name != tpnme.WILDCARD)
1564+
if ctx.scope.lookup(b.name) == NoSymbol then ctx.enter(sym)
1565+
else report.error(new DuplicateBind(b, cdef), b.srcPos)
15661566
if (!ctx.isAfterTyper) {
15671567
val bounds = ctx.gadt.fullBounds(sym)
15681568
if (bounds != null) sym.info = bounds
@@ -1969,8 +1969,9 @@ class Typer extends Namer
19691969
//val ptt = if (lo.isEmpty && hi.isEmpty) pt else
19701970
if (ctx.isAfterTyper) tree1
19711971
else {
1972-
val wildcardSym = newPatternBoundSymbol(tpnme.WILDCARD, tree1.tpe & pt, tree.span)
1973-
untpd.Bind(tpnme.WILDCARD, tree1).withType(wildcardSym.typeRef)
1972+
val boundName = WildcardParamName.fresh().toTypeName
1973+
val wildcardSym = newPatternBoundSymbol(boundName, tree1.tpe & pt, tree.span)
1974+
untpd.Bind(boundName, tree1).withType(wildcardSym.typeRef)
19741975
}
19751976
else tree1
19761977
}

tests/neg-custom-args/kind-projector.check

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,4 @@
99
-- Error: tests/neg-custom-args/kind-projector.scala:6:22 --------------------------------------------------------------
1010
6 |class Bar2 extends Foo[*] // error
1111
| ^
12-
| Type argument _$4 does not have the same kind as its bound [_$1]
12+
| Type argument _ does not have the same kind as its bound [_$1]

tests/neg/i12169.scala

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
object Var:
2+
class Expanded[T <: Txn[T], B] extends Form[T]
3+
4+
trait Txn[T <: Txn[T]]
5+
6+
trait Form[T]
7+
8+
class TT extends Txn[TT]
9+
10+
private final class FlatVarCellView[T <: Txn[T], B](
11+
firstVr : Option[Var.Expanded[TT, B]]
12+
)
13+
14+
def Test =
15+
val opt: Option[Form[TT]] = ???
16+
val firstVr = opt match
17+
case Some(ex: Var.Expanded[TT, _]) => Some(ex)
18+
case _ => None
19+
new FlatVarCellView(firstVr) // error
20+
// Found: (firstVr : Option[Var.Expanded[TT, ?]])
21+
// Required: Option[Var.Expanded[TT, B]]
22+
//
23+
// where: B is a type variable
24+
//
25+
// Note that we cannot do capture conversion since the `?` does not appear as an argument
26+
// of the a type. It's dubious whether capture conversion for more deeply nested types
27+
// would be sound.
28+
29+
// Remedy:
30+
opt match
31+
case Some(ex: Var.Expanded[TT, _]) => new FlatVarCellView(Some(ex))
32+
// here, we instantiate `B` with the unnamed second parameter of `Var.Expanded`
33+
case _ => new FlatVarCellView(None)
34+
opt match
35+
case Some(ex: Var.Expanded[TT, t]) => new FlatVarCellView[TT, t](Some(ex))
36+
// the same as above, spelt out
37+
case _ => new FlatVarCellView(None)

tests/neg/i4986c.check

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,4 +61,4 @@
6161
-- Error: tests/neg/i4986c.scala:62:19 ---------------------------------------------------------------------------------
6262
62 | i.m[Option[Long]] // error
6363
| ^
64-
| String; List; [A, _$6] =>> List[Option[?]]; Int; Option[Long];
64+
| String; List; [A, _] =>> List[Option[?]]; Int; Option[Long];

tests/pos/i12169.scala

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
class Property[T]
2+
3+
class VObject {
4+
def properties() = {
5+
List.empty[Property[?]].collect {
6+
case p: Property[?] => List(p)
7+
}
8+
}
9+
}
10+
11+
class Event extends VObject {
12+
override def properties() = ???
13+
}

0 commit comments

Comments
 (0)