Skip to content

Commit 59e0717

Browse files
authored
Suppress warnings in comprehensions with 22+ binds (#23590)
Fixes #23164 At that point, we emit a TupleXXL pattern case bundling all the variable bindings so far. The type tests in these patterns cannot be checked at runtime due to erasure. But we know these are safe, so we mark them as `@unchecked`.
2 parents 95b37a7 + abc8192 commit 59e0717

File tree

2 files changed

+85
-1
lines changed

2 files changed

+85
-1
lines changed

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

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2102,7 +2102,19 @@ object desugar {
21022102
val matchCheckMode =
21032103
if (gen.checkMode == GenCheckMode.Check || gen.checkMode == GenCheckMode.CheckAndFilter) MatchCheck.IrrefutableGenFrom
21042104
else MatchCheck.None
2105-
makeCaseLambda(CaseDef(gen.pat, EmptyTree, body) :: Nil, matchCheckMode)
2105+
val pat = gen.pat.match
2106+
case Tuple(pats) if pats.length > Definitions.MaxImplementedFunctionArity =>
2107+
/* The pattern case is a tupleXXL, because we have bound > 21 variables in the comprehension.
2108+
* In this case, we need to mark all the typed patterns as @unchecked, or get loads of warnings.
2109+
* Cf. warn test i23164.scala */
2110+
Tuple:
2111+
pats.map:
2112+
case t @ Bind(name, tp @ Typed(id, tpt)) =>
2113+
val annotated = Annotated(tpt, New(ref(defn.UncheckedAnnot.typeRef)))
2114+
cpy.Bind(t)(name, cpy.Typed(tp)(id, annotated)).withMods(t.mods)
2115+
case t => t
2116+
case _ => gen.pat
2117+
makeCaseLambda(CaseDef(pat, EmptyTree, body) :: Nil, matchCheckMode)
21062118
}
21072119

21082120
def hasGivenBind(pat: Tree): Boolean = pat.existsSubTree {

tests/warn/i23164.scala

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
class T1[F[_]]
2+
class T2[F[_]]
3+
class T3[F[_]]
4+
class T4[F[_]]
5+
class T5[F[_]]
6+
class T6[F[_]]
7+
class T7[F[_]]
8+
class T8[F[_]]
9+
class T9[F[_]]
10+
class T10[F[_]]
11+
class T11[F[_]]
12+
class T12[F[_]]
13+
class T13[F[_]]
14+
class T14[F[_]]
15+
class T15[F[_]]
16+
class T16[F[_]]
17+
class T17[F[_]]
18+
class T18[F[_]]
19+
class T19[F[_]]
20+
class T20[F[_]]
21+
class T21[F[_]]
22+
class T22[F[_]]
23+
24+
class Result[F[_]: {T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19,T20,T21,T22}]
25+
26+
val r = for
27+
t1 <- Option(new T1[Option])
28+
t2 <- Option(new T2[Option])
29+
t3 <- Option(new T3[Option])
30+
t4 <- Option(new T4[Option])
31+
t5 <- Option(new T5[Option])
32+
t6 <- Option(new T6[Option])
33+
t7 <- Option(new T7[Option])
34+
t8 <- Option(new T8[Option])
35+
t9 <- Option(new T9[Option])
36+
t10 <- Option(new T10[Option])
37+
t11 <- Option(new T11[Option])
38+
t12 <- Option(new T12[Option])
39+
t13 <- Option(new T13[Option])
40+
t14 <- Option(new T14[Option])
41+
t15 <- Option(new T15[Option])
42+
t16 <- Option(new T16[Option])
43+
t17 <- Option(new T17[Option])
44+
t18 <- Option(new T18[Option])
45+
t19 <- Option(new T19[Option])
46+
t20 <- Option(new T20[Option])
47+
t21 <- Option(new T21[Option])
48+
t22 <- Option(new T22[Option])
49+
given T1[Option] = t1
50+
given T2[Option] = t2
51+
given T3[Option] = t3
52+
given T4[Option] = t4
53+
given T5[Option] = t5
54+
given T6[Option] = t6
55+
given T7[Option] = t7
56+
given T8[Option] = t8
57+
given T9[Option] = t9
58+
given T10[Option] = t10
59+
given T11[Option] = t11
60+
given T12[Option] = t12
61+
given T13[Option] = t13
62+
given T14[Option] = t14
63+
given T15[Option] = t15
64+
given T16[Option] = t16
65+
given T17[Option] = t17
66+
given T18[Option] = t18
67+
given T19[Option] = t19
68+
given T20[Option] = t20
69+
given T21[Option] = t21
70+
given T22[Option] = t22
71+
result <- Option(new Result[Option])
72+
yield result

0 commit comments

Comments
 (0)