@@ -1093,6 +1093,24 @@ object desugar {
1093
1093
case IdPattern (named, tpt) =>
1094
1094
derivedValDef(original, named, tpt, rhs, mods)
1095
1095
case _ =>
1096
+ def givenPatternMessage (givenPat : Bind , tpt : Tree )(using Context ): String =
1097
+ val pat =
1098
+ val givenTpt = em " ${hl(" given" )} $tpt"
1099
+ if givenPat.name == nme.WILDCARD then
1100
+ givenTpt
1101
+ else
1102
+ em " ${givenPat.name} @ $givenTpt"
1103
+ em """ pattern ` $pat` is not allowed here,
1104
+ |please bind to a variable and use an alias given. """ .stripMargin
1105
+ end givenPatternMessage
1106
+
1107
+ def filterWildcardGivenBinding (givenPat : Bind , tpt : Tree ): Boolean =
1108
+ givenPat.name != nme.WILDCARD
1109
+
1110
+ def errorOnGivenBinding (bind : Bind , tpt : Tree )(using Context ): Boolean =
1111
+ report.error(givenPatternMessage(bind, tpt), bind)
1112
+ false
1113
+
1096
1114
def isTuplePattern (arity : Int ): Boolean = pat match {
1097
1115
case Tuple (pats) if pats.size == arity =>
1098
1116
pats.forall(isVarPattern)
@@ -1108,13 +1126,23 @@ object desugar {
1108
1126
// - `pat` is a tuple of N variables or wildcard patterns like `(x1, x2, ..., xN)`
1109
1127
val tupleOptimizable = forallResults(rhs, isMatchingTuple)
1110
1128
1129
+ val inAliasGenerator = original match
1130
+ case _ : GenAlias => true
1131
+ case _ => false
1132
+
1111
1133
val vars =
1112
1134
if (tupleOptimizable) // include `_`
1113
- pat match {
1114
- case Tuple (pats) =>
1115
- pats.map { case id : Ident => id -> TypeTree () }
1116
- }
1117
- else getVariables(pat) // no `_`
1135
+ pat match
1136
+ case Tuple (pats) => pats.map { case id : Ident => id -> TypeTree () }
1137
+ else
1138
+ getVariables(
1139
+ tree = pat,
1140
+ shouldAddGiven =
1141
+ if inAliasGenerator then
1142
+ filterWildcardGivenBinding
1143
+ else
1144
+ errorOnGivenBinding
1145
+ ) // no `_`
1118
1146
1119
1147
val ids = for ((named, _) <- vars) yield Ident (named.name)
1120
1148
val caseDef = CaseDef (pat, EmptyTree , makeTuple(ids))
@@ -1800,16 +1828,21 @@ object desugar {
1800
1828
/** Returns list of all pattern variables, possibly with their types,
1801
1829
* without duplicates
1802
1830
*/
1803
- private def getVariables (tree : Tree )(using Context ): List [VarInfo ] = {
1831
+ private def getVariables (tree : Tree , shouldAddGiven : Context ?=> ( Bind , Tree ) => Boolean )(using Context ): List [VarInfo ] = {
1804
1832
val buf = ListBuffer [VarInfo ]()
1805
1833
def seenName (name : Name ) = buf exists (_._1.name == name)
1806
1834
def add (named : NameTree , t : Tree ): Unit =
1807
1835
if (! seenName(named.name) && named.name.isTermName) buf += ((named, t))
1808
1836
def collect (tree : Tree ): Unit = tree match {
1809
- case Bind (nme.WILDCARD , tree1) =>
1837
+ case tree @ Bind (nme.WILDCARD , tree1) =>
1838
+ if tree.mods.is(Given ) then
1839
+ val Typed (_, tpt) = tree1 : @ unchecked
1840
+ if shouldAddGiven(tree, tpt) then
1841
+ add(tree, tpt)
1810
1842
collect(tree1)
1811
1843
case tree @ Bind (_, Typed (tree1, tpt)) =>
1812
- add(tree, tpt)
1844
+ if ! (tree.mods.is(Given ) && ! shouldAddGiven(tree, tpt)) then
1845
+ add(tree, tpt)
1813
1846
collect(tree1)
1814
1847
case tree @ Bind (_, tree1) =>
1815
1848
add(tree, TypeTree ())
@@ -1827,7 +1860,7 @@ object desugar {
1827
1860
case SeqLiteral (elems, _) =>
1828
1861
elems foreach collect
1829
1862
case Alternative (trees) =>
1830
- for (tree <- trees; (vble, _) <- getVariables(tree))
1863
+ for (tree <- trees; (vble, _) <- getVariables(tree, shouldAddGiven ))
1831
1864
report.error(IllegalVariableInPatternAlternative (), vble.srcPos)
1832
1865
case Annotated (arg, _) =>
1833
1866
collect(arg)
0 commit comments