Skip to content

Commit 0a3fb0f

Browse files
Remove NameBasedPattern, use scala.Product instead
1 parent 6c56acd commit 0a3fb0f

File tree

10 files changed

+45
-59
lines changed

10 files changed

+45
-59
lines changed

compiler/foo

Whitespace-only changes.

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -414,10 +414,10 @@ object desugar {
414414
if (arity > Definitions.MaxTupleArity) scalaDot(nme.Product.toTypeName)
415415
else productConstr(arity)
416416

417-
// Case classes and case objects get NameBasedPattern and Product/ProductN parents
417+
// Case classes and case objects get Product/ProductN parents
418418
val parents1: List[Tree] =
419419
if (mods.is(Case))
420-
parents :+ product :+ scalaDot(nme.NameBasedPattern.toTypeName)
420+
parents :+ product
421421
else parents
422422

423423
// The thicket which is the desugared version of the companion object

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

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -508,7 +508,6 @@ class Definitions {
508508
def DynamicClass(implicit ctx: Context) = DynamicType.symbol.asClass
509509
lazy val OptionType: TypeRef = ctx.requiredClassRef("scala.Option")
510510
def OptionClass(implicit ctx: Context) = OptionType.symbol.asClass
511-
lazy val NameBasedPatternType: TypeRef = ctx.requiredClassRef("scala.NameBasedPattern")
512511
lazy val ProductType: TypeRef = ctx.requiredClassRef("scala.Product")
513512
def ProductClass(implicit ctx: Context) = ProductType.symbol.asClass
514513
lazy val Product_canEqualR = ProductClass.requiredMethodRef(nme.canEqual_)
@@ -794,15 +793,8 @@ class Definitions {
794793
TupleType(elems.size).appliedTo(elems)
795794
}
796795

797-
/** Is this type eligible for name based pattern matching?
798-
*
799-
* That means either extending `scala.ProductN` OR `NameBasedPattern`.
800-
* In the long term, we can remove the first condition by having
801-
* `scala.ProductN` inherit `NameBasedPattern`.
802-
*/
803-
def isNameBasedPatternSubType(tp: Type)(implicit ctx: Context) =
804-
(tp.derivesFrom(ProductType.symbol) && tp.baseClasses.exists(isProductClass)) ||
805-
tp.derivesFrom(NameBasedPatternType.symbol)
796+
def isProductSubType(tp: Type)(implicit ctx: Context) =
797+
tp.derivesFrom(ProductType.symbol)
806798

807799
/** Is `tp` (an alias) of either a scala.FunctionN or a scala.ImplicitFunctionN? */
808800
def isFunctionType(tp: Type)(implicit ctx: Context) = {

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,6 @@ object StdNames {
184184
final val Function: N = "Function"
185185
final val ImplicitFunction: N = "ImplicitFunction"
186186
final val Mirror: N = "Mirror"
187-
final val NameBasedPattern: N = "NameBasedPattern"
188187
final val Nothing: N = "Nothing"
189188
final val Null: N = "Null"
190189
final val Object: N = "Object"

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

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,7 @@ class PatternMatcher extends MiniPhaseTransform with DenotTransformer {
236236
// returns MatchMonad[U]
237237
def flatMap(prev: Tree, b: Symbol, next: Tree): Tree = {
238238
val resultArity = productArity(b.info)
239-
if (isNameBasedMatch(prev.tpe, resultArity)) {
239+
if (!isGetMatch(prev.tpe)) {
240240
val nullCheck: Tree = prev.select(defn.Object_ne).appliedTo(Literal(Constant(null)))
241241
ifThenElseZero(
242242
nullCheck,
@@ -1430,8 +1430,8 @@ class PatternMatcher extends MiniPhaseTransform with DenotTransformer {
14301430

14311431
def resultInMonad =
14321432
if (aligner.isBool) defn.UnitType
1433-
else if (isNameBasedMatch(resultType, aligner.prodArity)) resultType
14341433
else if (isGetMatch(resultType)) extractorMemberType(resultType, nme.get)
1434+
else if (isProductMatch(resultType, aligner.prodArity)) resultType
14351435
else resultType
14361436

14371437
def resultType: Type
@@ -1474,7 +1474,7 @@ class PatternMatcher extends MiniPhaseTransform with DenotTransformer {
14741474
protected def seqTree(binder: Symbol) = tupleSel(binder)(firstIndexingBinder + 1)
14751475
protected def tupleSel(binder: Symbol)(i: Int): Tree = {
14761476
val accessors =
1477-
if (defn.isNameBasedPatternSubType(binder.info))
1477+
if (defn.isProductSubType(binder.info))
14781478
productSelectors(binder.info)
14791479
else binder.caseAccessors
14801480
val res =
@@ -1631,7 +1631,7 @@ class PatternMatcher extends MiniPhaseTransform with DenotTransformer {
16311631
ref(binder) :: Nil
16321632
}
16331633
else if ((aligner.isSingle && aligner.extractor.prodArity == 1) &&
1634-
!isNameBasedMatch(binderTypeTested, aligner.prodArity) && isGetMatch(binderTypeTested))
1634+
!isProductMatch(binderTypeTested, aligner.prodArity) && isGetMatch(binderTypeTested))
16351635
List(ref(binder))
16361636
else
16371637
subPatRefs(binder)
@@ -1882,12 +1882,12 @@ class PatternMatcher extends MiniPhaseTransform with DenotTransformer {
18821882

18831883
val expanded: List[Type] = /*(
18841884
if (result =:= defn.BooleanType) Nil
1885-
else if (defn.isNameBasedPatternSubType(result)) productSelectorTypes(result)
1885+
else if (defn.isProductSubType(result)) productSelectorTypes(result)
18861886
else if (result.classSymbol is Flags.CaseClass) result.decls.filter(x => x.is(Flags.CaseAccessor) && x.is(Flags.Method)).map(_.info).toList
18871887
else result.select(nme.get) :: Nil
18881888
)*/
1889-
if (isNameBasedMatch(resultType, args.length)) productSelectorTypes(resultType)
1890-
else if (isGetMatch(resultType)) getUnapplySelectors(resultOfGet, args)
1889+
if (isGetMatch(resultType)) getUnapplySelectors(resultOfGet, args)
1890+
else if (isProductMatch(resultType, args.length)) productSelectorTypes(resultType)
18911891
else if (resultType isRef defn.BooleanClass) Nil
18921892
else {
18931893
ctx.error(i"invalid return type in Unapply node: $resultType")

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

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,11 @@ object Applications {
5151
* type for a pattern with `numArgs` subpatterns.
5252
*
5353
* This is the case if:
54-
* - `tp` is a subtype of the Product<numArgs> class or `NameBasedPattern` trait
54+
* - `tp` is a subtype of the Product trait
5555
* - `tp` has members `_1` to `_N` where `N == numArgs`
5656
*/
57-
def isNameBasedMatch(tp: Type, numArgs: Int)(implicit ctx: Context) =
58-
0 <= numArgs && defn.isNameBasedPatternSubType(tp) &&
57+
def isProductMatch(tp: Type, numArgs: Int)(implicit ctx: Context) =
58+
0 <= numArgs && defn.isProductSubType(tp) &&
5959
productSelectorTypes(tp).size == numArgs
6060

6161
/** Does `tp` fit the "get match" conditions as an unapply result type?
@@ -72,7 +72,7 @@ object Applications {
7272
}
7373

7474
def productArity(tp: Type)(implicit ctx: Context) =
75-
if (defn.isNameBasedPatternSubType(tp)) productSelectorTypes(tp).size else -1
75+
if (defn.isProductSubType(tp)) productSelectorTypes(tp).size else -1
7676

7777
def productSelectors(tp: Type)(implicit ctx: Context): List[Symbol] = {
7878
val sels = for (n <- Iterator.from(0)) yield tp.member(nme.selectorName(n)).symbol
@@ -108,13 +108,13 @@ object Applications {
108108
}
109109
else {
110110
assert(unapplyName == nme.unapply)
111-
if (isNameBasedMatch(unapplyResult, args.length))
111+
if (isProductMatch(unapplyResult, args.length))
112112
productSelectorTypes(unapplyResult)
113113
else if (isGetMatch(unapplyResult, pos))
114114
getUnapplySelectors(getTp, args, pos)
115115
else if (unapplyResult isRef defn.BooleanClass)
116116
Nil
117-
else if (defn.isNameBasedPatternSubType(unapplyResult))
117+
else if (defn.isProductSubType(unapplyResult))
118118
productSelectorTypes(unapplyResult)
119119
// this will cause a "wrong number of arguments in pattern" error later on,
120120
// which is better than the message in `fail`.

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -747,7 +747,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
747747
/** Is `formal` a product type which is elementwise compatible with `params`? */
748748
def ptIsCorrectProduct(formal: Type) = {
749749
isFullyDefined(formal, ForceDegree.noBottom) &&
750-
defn.isNameBasedPatternSubType(formal) &&
750+
defn.isProductSubType(formal) &&
751751
Applications.productSelectorTypes(formal).corresponds(params) {
752752
(argType, param) =>
753753
param.tpt.isEmpty || argType <:< typedAheadType(param.tpt).tpe

library/src/scala/NameBasedPattern.scala

Lines changed: 0 additions & 4 deletions
This file was deleted.

tests/neg/Patterns.scala

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// Tricky case (exercised by Scala parser combinators) where we use
2+
// both get/isEmpty and product-based pattern matching in different
3+
// matches on the same types.
4+
object ProductAndGet {
5+
6+
trait Result[+T]
7+
case class Success[+T](in: String, x: T) extends Result[T] {
8+
def isEmpty = false
9+
def get: T = x
10+
}
11+
case class Failure[+T](in: String, msg: String) extends Result[T] {
12+
def isEmpty = false
13+
def get: String = msg
14+
}
15+
16+
val r: Result[Int] = ???
17+
18+
r match {
19+
case Success(in, x) => x // error
20+
case Failure(in, msg) => -1 // error
21+
}
22+
23+
r match {
24+
case Success(x) => x
25+
case Failure(msg) => -1
26+
}
27+
}

tests/pos/Patterns.scala

Lines changed: 0 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -108,31 +108,3 @@ object NestedPattern {
108108
val xss: List[List[String]] = ???
109109
val List(List(x)) = xss
110110
}
111-
112-
// Tricky case (exercised by Scala parser combinators) where we use
113-
// both get/isEmpty and product-based pattern matching in different
114-
// matches on the same types.
115-
object ProductAndGet {
116-
117-
trait Result[+T]
118-
case class Success[+T](in: String, x: T) extends Result[T] {
119-
def isEmpty = false
120-
def get: T = x
121-
}
122-
case class Failure[+T](in: String, msg: String) extends Result[T] {
123-
def isEmpty = false
124-
def get: String = msg
125-
}
126-
127-
val r: Result[Int] = ???
128-
129-
r match {
130-
case Success(in, x) => x
131-
case Failure(in, msg) => -1
132-
}
133-
134-
r match {
135-
case Success(x) => x
136-
case Failure(msg) => -1
137-
}
138-
}

0 commit comments

Comments
 (0)