Skip to content

Commit cc452af

Browse files
committed
Raise a warning instead of an error for type a type ascription on a pattern other than a variable or a number literal.
This partially reverts the changes from #16150. This change is motivated by not breaking source compatibility for a number of projects in the Open Community Build.
1 parent 982ce3f commit cc452af

File tree

8 files changed

+76
-19
lines changed

8 files changed

+76
-19
lines changed

compiler/src/dotty/tools/dotc/parsing/Parsers.scala

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2871,14 +2871,14 @@ object Parsers {
28712871
if (isIdent(nme.raw.BAR)) { in.nextToken(); pattern1(location) :: patternAlts(location) }
28722872
else Nil
28732873

2874-
/** Pattern1 ::= PatVar Ascription
2875-
* | [‘-’] integerLiteral Ascription
2876-
* | [‘-’] floatingPointLiteral Ascription
2877-
* | Pattern2
2874+
/** Pattern1 ::= Pattern2 [Ascription]
28782875
*/
28792876
def pattern1(location: Location = Location.InPattern): Tree =
28802877
val p = pattern2()
2881-
if (isVarPattern(p) || p.isInstanceOf[Number]) && in.isColon then
2878+
if in.isColon then
2879+
val isVariableOrNumber = isVarPattern(p) || p.isInstanceOf[Number]
2880+
if !isVariableOrNumber then
2881+
warning(em"Only variable and number literal patterns can have type ascriptions")
28822882
in.nextToken()
28832883
ascription(p, location)
28842884
else p

docs/_docs/internals/syntax.md

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -314,10 +314,7 @@ TypeCaseClauses ::= TypeCaseClause { TypeCaseClause }
314314
TypeCaseClause ::= ‘case’ (InfixType | ‘_’) ‘=>’ Type [semi]
315315
316316
Pattern ::= Pattern1 { ‘|’ Pattern1 } Alternative(pats)
317-
Pattern1 ::= PatVar ‘:’ RefinedType Bind(name, Typed(Ident(wildcard), tpe))
318-
| [‘-’] integerLiteral ‘:’ RefinedType Typed(pat, tpe)
319-
| [‘-’] floatingPointLiteral ‘:’ RefinedType Typed(pat, tpe)
320-
| Pattern2
317+
Pattern1 ::= Pattern2 [‘:’ RefinedType] Bind(name, Typed(Ident(wildcard), tpe))
321318
Pattern2 ::= [id ‘@’] InfixPattern [‘*’] Bind(name, pat)
322319
InfixPattern ::= SimplePattern { id [nl] SimplePattern } InfixOp(pat, op, pat)
323320
SimplePattern ::= PatVar Ident(wildcard)

docs/_docs/reference/syntax.md

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -312,10 +312,7 @@ TypeCaseClauses ::= TypeCaseClause { TypeCaseClause }
312312
TypeCaseClause ::= ‘case’ (InfixType | ‘_’) ‘=>’ Type [semi]
313313
314314
Pattern ::= Pattern1 { ‘|’ Pattern1 }
315-
Pattern1 ::= PatVar ‘:’ RefinedType
316-
| [‘-’] integerLiteral ‘:’ RefinedType
317-
| [‘-’] floatingPointLiteral ‘:’ RefinedType
318-
| Pattern2
315+
Pattern1 ::= Pattern2 [‘:’ RefinedType]
319316
Pattern2 ::= [id ‘@’] InfixPattern [‘*’]
320317
InfixPattern ::= SimplePattern { id [nl] SimplePattern }
321318
SimplePattern ::= PatVar

tests/neg/i15893.scala renamed to tests/neg-custom-args/fatal-warnings/i15893.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ transparent inline def transparentInlineMod2(inline n: NatT): NatT = inline n m
2222
case Succ(Zero()) => Succ(Zero())
2323
case Succ(Succ(predPredN)) => transparentInlineMod2(predPredN)
2424

25-
def dependentlyTypedMod2[N <: NatT](n: N): Mod2[N] = n match // exhaustivity warning; unexpected
25+
def dependentlyTypedMod2[N <: NatT](n: N): Mod2[N] = n match
2626
case Zero(): Zero => Zero() // error
2727
case Succ(Zero()): Succ[Zero] => Succ(Zero()) // error
2828
case Succ(Succ(predPredN)): Succ[Succ[_]] => dependentlyTypedMod2(predPredN) // error
@@ -57,5 +57,5 @@ inline def transparentInlineFoo(inline n: NatT): NatT = inline transparentInline
5757
println(transparentInlineMod2(Succ(Succ(Succ(Zero()))))) // prints Succ(Zero()), as expected
5858
println(transparentInlineFoo(Succ(Succ(Succ(Zero()))))) // prints Zero(), as expected
5959
println(dependentlyTypedMod2(Succ(Succ(Succ(Zero()))))) // runtime error; unexpected
60-
// println(inlineDependentlyTypedMod2(Succ(Succ(Succ(Zero()))))) // doesn't compile; unexpected
61-
// println(transparentInlineDependentlyTypedMod2(Succ(Succ(Succ(Zero()))))) // doesn't compile; unexpected
60+
println(inlineDependentlyTypedMod2(Succ(Succ(Succ(Zero()))))) // prints Succ(Zero()), as expected
61+
println(transparentInlineDependentlyTypedMod2(Succ(Succ(Succ(Zero()))))) // prints Succ(Zero()), as expected

tests/pending/run/i15893.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ transparent inline def transparentInlineMod2(inline n: NatT): NatT = inline n m
2424
case Succ(Zero()) => Succ(Zero())
2525
case Succ(Succ(predPredN)) => transparentInlineMod2(predPredN)
2626
*/
27-
def dependentlyTypedMod2[N <: NatT](n: N): Mod2[N] = n match // exhaustivity warning; unexpected
27+
def dependentlyTypedMod2[N <: NatT](n: N): Mod2[N] = n match
2828
case Zero(): Zero => Zero()
2929
case Succ(Zero()): Succ[Zero] => Succ(Zero())
3030
case Succ(Succ(predPredN)): Succ[Succ[_]] => dependentlyTypedMod2(predPredN)
@@ -61,5 +61,5 @@ inline def transparentInlineFoo(inline n: NatT): NatT = inline transparentInline
6161
println(transparentInlineFoo(Succ(Succ(Succ(Zero()))))) // prints Zero(), as expected
6262
*/
6363
println(dependentlyTypedMod2(Succ(Succ(Succ(Zero()))))) // runtime error; unexpected
64-
// println(inlineDependentlyTypedMod2(Succ(Succ(Succ(Zero()))))) // doesn't compile; unexpected
65-
// println(transparentInlineDependentlyTypedMod2(Succ(Succ(Succ(Zero()))))) // doesn't compile; unexpected
64+
// println(inlineDependentlyTypedMod2(Succ(Succ(Succ(Zero()))))) // prints Succ(Zero()), as expected
65+
// println(transparentInlineDependentlyTypedMod2(Succ(Succ(Succ(Zero()))))) // prints Succ(Zero()), as expected

tests/pos/i10994.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
def foo = true match
2+
case (b: Boolean): Boolean => ()

tests/pos/i15893.scala

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
sealed trait NatT
2+
case class Zero() extends NatT
3+
case class Succ[+N <: NatT](n: N) extends NatT
4+
5+
type Mod2[N <: NatT] <: NatT = N match
6+
case Zero => Zero
7+
case Succ[Zero] => Succ[Zero]
8+
case Succ[Succ[predPredN]] => Mod2[predPredN]
9+
10+
def mod2(n: NatT): NatT = n match
11+
case Zero() => Zero()
12+
case Succ(Zero()) => Succ(Zero())
13+
case Succ(Succ(predPredN)) => mod2(predPredN)
14+
15+
inline def inlineMod2(inline n: NatT): NatT = inline n match
16+
case Zero() => Zero()
17+
case Succ(Zero()) => Succ(Zero())
18+
case Succ(Succ(predPredN)) => inlineMod2(predPredN)
19+
20+
transparent inline def transparentInlineMod2(inline n: NatT): NatT = inline n match
21+
case Zero() => Zero()
22+
case Succ(Zero()) => Succ(Zero())
23+
case Succ(Succ(predPredN)) => transparentInlineMod2(predPredN)
24+
25+
def dependentlyTypedMod2[N <: NatT](n: N): Mod2[N] = n match
26+
case Zero(): Zero => Zero() // warning
27+
case Succ(Zero()): Succ[Zero] => Succ(Zero()) // warning
28+
case Succ(Succ(predPredN)): Succ[Succ[_]] => dependentlyTypedMod2(predPredN) // warning
29+
30+
inline def inlineDependentlyTypedMod2[N <: NatT](inline n: N): Mod2[N] = inline n match
31+
case Zero(): Zero => Zero() // warning
32+
case Succ(Zero()): Succ[Zero] => Succ(Zero()) // warning
33+
case Succ(Succ(predPredN)): Succ[Succ[_]] => inlineDependentlyTypedMod2(predPredN) // warning
34+
35+
transparent inline def transparentInlineDependentlyTypedMod2[N <: NatT](inline n: N): Mod2[N] = inline n match
36+
case Zero(): Zero => Zero() // warning
37+
case Succ(Zero()): Succ[Zero] => Succ(Zero()) // warning
38+
case Succ(Succ(predPredN)): Succ[Succ[_]] => transparentInlineDependentlyTypedMod2(predPredN) // warning
39+
40+
def foo(n: NatT): NatT = mod2(n) match
41+
case Succ(Zero()) => Zero()
42+
case _ => n
43+
44+
inline def inlineFoo(inline n: NatT): NatT = inline inlineMod2(n) match
45+
case Succ(Zero()) => Zero()
46+
case _ => n
47+
48+
inline def transparentInlineFoo(inline n: NatT): NatT = inline transparentInlineMod2(n) match
49+
case Succ(Zero()) => Zero()
50+
case _ => n
51+
52+
@main def main(): Unit =
53+
println(mod2(Succ(Succ(Succ(Zero()))))) // prints Succ(Zero()), as expected
54+
println(foo(Succ(Succ(Succ(Zero()))))) // prints Zero(), as expected
55+
println(inlineMod2(Succ(Succ(Succ(Zero()))))) // prints Succ(Zero()), as expected
56+
println(inlineFoo(Succ(Succ(Succ(Zero()))))) // prints Succ(Succ(Succ(Zero()))); unexpected
57+
println(transparentInlineMod2(Succ(Succ(Succ(Zero()))))) // prints Succ(Zero()), as expected
58+
println(transparentInlineFoo(Succ(Succ(Succ(Zero()))))) // prints Zero(), as expected
59+
println(dependentlyTypedMod2(Succ(Succ(Succ(Zero()))))) // runtime error; unexpected
60+
println(inlineDependentlyTypedMod2(Succ(Succ(Succ(Zero()))))) // prints Succ(Zero()), as expected
61+
println(transparentInlineDependentlyTypedMod2(Succ(Succ(Succ(Zero()))))) // prints Succ(Zero()), as expected

0 commit comments

Comments
 (0)