Skip to content

Commit 38350ec

Browse files
Keep tree of type ascriptions of quote pattern splices (#18412)
These trees where removed as part of an optimization. However, they should be kept around to allow for better error messages and IDE navigation. The type of the ascription in pickled in the TASTy file but is elided in the pickled quote pattern (same optimization already done later). Fixes #18409
2 parents 5690bbf + f02befc commit 38350ec

8 files changed

+37
-32
lines changed

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

+1-10
Original file line numberDiff line numberDiff line change
@@ -492,18 +492,9 @@ class PostTyper extends MacroTransform with InfoTransformer { thisPhase =>
492492
)
493493
case Block(_, Closure(_, _, tpt)) if ExpandSAMs.needsWrapperClass(tpt.tpe) =>
494494
superAcc.withInvalidCurrentClass(super.transform(tree))
495-
case _: Quote =>
495+
case _: Quote | _: QuotePattern =>
496496
ctx.compilationUnit.needsStaging = true
497497
super.transform(tree)
498-
case _: QuotePattern =>
499-
if !ctx.reporter.errorsReported then
500-
Checking.checkAppliedTypesIn(TypeTree(tree.tpe).withSpan(tree.span))
501-
ctx.compilationUnit.needsStaging = true
502-
super.transform(tree)
503-
case tree: SplicePattern =>
504-
if !ctx.reporter.errorsReported then
505-
Checking.checkAppliedTypesIn(TypeTree(tree.tpe).withSpan(tree.span))
506-
super.transform(tree)
507498
case tree =>
508499
super.transform(tree)
509500
}

compiler/src/dotty/tools/dotc/transform/patmat/Space.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,7 @@ object SpaceEngine {
312312
def isIrrefutableQuotePattern(pat: tpd.QuotePattern, pt: Type)(using Context): Boolean = {
313313
if pat.body.isType then pat.bindings.isEmpty && pt =:= pat.tpe
314314
else pat.body match
315-
case _: SplicePattern => pat.bindings.isEmpty && pt <:< pat.tpe
315+
case _: SplicePattern | Typed(_: SplicePattern, _) => pat.bindings.isEmpty && pt <:< pat.tpe
316316
case _ => false
317317
}
318318

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

-6
Original file line numberDiff line numberDiff line change
@@ -259,14 +259,8 @@ trait QuotesAndSplices {
259259
pat.symbol.addAnnotation(Annotation(New(ref(defn.QuotedRuntimePatterns_fromAboveAnnot.typeRef)).withSpan(pat.span)))
260260
allTypeBindings += pat
261261
TypeTree(pat.symbol.typeRef).withSpan(pat.span)
262-
263-
case Typed(splice: SplicePattern, tpt) if !tpt.tpe.derivesFrom(defn.RepeatedParamClass) =>
264-
// We drop the type ascription because it is redundant, the SplicePattern contains the same type
265-
transform(tpt) // Collect type bindings
266-
splice
267262
case _: SplicePattern =>
268263
tree
269-
270264
case _ =>
271265
super.transform(tree)
272266
}

tests/neg-macros/quote-type-variable-no-inference-2.check

+3-3
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@
55
|
66
| Consider defining bounds explicitly:
77
| '{ type t <: Int & Double; ... }
8-
-- [E057] Type Mismatch Error: tests/neg-macros/quote-type-variable-no-inference-2.scala:5:12 --------------------------
8+
-- [E057] Type Mismatch Error: tests/neg-macros/quote-type-variable-no-inference-2.scala:5:20 --------------------------
99
5 | case '{ $_ : F[t, t]; () } => // warn // error
10-
| ^
11-
| Type argument t does not conform to upper bound Double in inferred type F[t, t]
10+
| ^
11+
| Type argument t does not conform to upper bound Double
1212
|
1313
| longer explanation available when compiling with `-explain`

tests/neg-macros/quote-type-variable-no-inference-3.check

+3-3
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@
1212
|
1313
| Consider defining bounds explicitly:
1414
| '{ type u <: Comparable[u] & Comparable[Any]; ... }
15-
-- [E057] Type Mismatch Error: tests/neg-macros/quote-type-variable-no-inference-3.scala:5:12 --------------------------
15+
-- [E057] Type Mismatch Error: tests/neg-macros/quote-type-variable-no-inference-3.scala:5:20 --------------------------
1616
5 | case '{ $_ : F[t, t]; () } => // warn // error
17-
| ^
18-
| Type argument t does not conform to upper bound Comparable[t] in inferred type F[t, t]
17+
| ^
18+
| Type argument t does not conform to upper bound Comparable[t]
1919
|
2020
| longer explanation available when compiling with `-explain`

tests/neg-macros/quote-type-variable-no-inference.check

+2-8
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,12 @@
11
-- Warning: tests/neg-macros/quote-type-variable-no-inference.scala:5:17 -----------------------------------------------
2-
5 | case '[ F[t, t] ] => // warn // error // error
2+
5 | case '[ F[t, t] ] => // warn // error
33
| ^
44
| Ignored bound <: Double
55
|
66
| Consider defining bounds explicitly:
77
| '[ type t <: Int & Double; ... ]
8-
-- [E057] Type Mismatch Error: tests/neg-macros/quote-type-variable-no-inference.scala:5:9 -----------------------------
9-
5 | case '[ F[t, t] ] => // warn // error // error
10-
| ^
11-
|Type argument t does not conform to upper bound Double in subpart F[t, t] of inferred type scala.quoted.Type[F[t, t]]
12-
|
13-
| longer explanation available when compiling with `-explain`
148
-- [E057] Type Mismatch Error: tests/neg-macros/quote-type-variable-no-inference.scala:5:15 ----------------------------
15-
5 | case '[ F[t, t] ] => // warn // error // error
9+
5 | case '[ F[t, t] ] => // warn // error
1610
| ^
1711
| Type argument t does not conform to upper bound Double
1812
|

tests/neg-macros/quote-type-variable-no-inference.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import scala.quoted.*
22

33
def test(x: Type[?])(using Quotes) =
44
x match
5-
case '[ F[t, t] ] => // warn // error // error
5+
case '[ F[t, t] ] => // warn // error
66
case '[ type u <: Int & Double; F[u, u] ] =>
77

88
type F[x <: Int, y <: Double]

tests/pos-macros/i18409.scala

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// scalac: -Werror -Wunused:all
2+
3+
import scala.quoted.*
4+
5+
object model {
6+
trait Transformer[Source, Dest] {
7+
def transform(from: Source): Dest
8+
}
9+
object Transformer {
10+
trait ForProduct[A, B] extends Transformer[A, B]
11+
}
12+
}
13+
14+
object Ops {
15+
import model.Transformer // unused import false-positive
16+
17+
def unapply(using Quotes)(term: quotes.reflect.Term): Option[String] = {
18+
term.asExpr match {
19+
case '{
20+
($transformer: Transformer.ForProduct[a, b]).transform($appliedTo)
21+
} =>
22+
Some("")
23+
case other => None
24+
}
25+
}
26+
}

0 commit comments

Comments
 (0)