Skip to content

Commit 45536fa

Browse files
committed
Warn on use of inferred quote type variable bounds
This kind of inference is not reliable in general. We can only consider the bounds from type constructor where the type variable is defined but any other constraints are ignored. Therefore it is not possible to properly infer the type bounds of the type variable. The solution is simple, write the bounds explicitly and just check that those bounds conform to the use site of the type variable.
1 parent 221bae8 commit 45536fa

File tree

3 files changed

+25
-0
lines changed

3 files changed

+25
-0
lines changed

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,8 @@ trait QuotesAndSplices {
159159
case _ => TypeBounds.empty
160160
val typeSym = newSymbol(spliceOwner(ctx), name, EmptyFlags, typeSymInfo, NoSymbol, tree.span)
161161
typeSym.addAnnotation(Annotation(New(ref(defn.QuotedRuntimePatterns_patternTypeAnnot.typeRef)).withSpan(tree.span)))
162+
if !(typeSymInfo =:= TypeBounds.empty) then
163+
report.warning(em"Type variable `$tree` has partially inferred bounds$pt.\n\nConsider defining bounds explicitly `'{ $typeSym$pt; ... }`", tree.srcPos)
162164
val pat = typedPattern(expr, defn.QuotedTypeClass.typeRef.appliedTo(typeSym.typeRef))(
163165
using spliceContext.retractMode(Mode.QuotedPattern).withOwner(spliceOwner(ctx)))
164166
pat.select(tpnme.Underlying)
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
-- Error: tests/neg-custom-args/fatal-warnings/quote-type-var-with-bounds.scala:9:18 -----------------------------------
2+
9 | case '{ $x: C[t] } => // error
3+
| ^
4+
| Type variable `t` has partially inferred bounds <: Int.
5+
|
6+
| Consider defining bounds explicitly `'{ type t <: Int; ... }`
7+
-- Error: tests/neg-custom-args/fatal-warnings/quote-type-var-with-bounds.scala:10:18 ----------------------------------
8+
10 | case '{ $x: D[t] } => // error
9+
| ^
10+
| Type variable `t` has partially inferred bounds >: Null <: String.
11+
|
12+
| Consider defining bounds explicitly `'{ type t >: Null <: String; ... }`
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import scala.quoted.*
2+
3+
class C[T <: Int]
4+
class D[T >: Null <: String]
5+
6+
def test(e: Expr[Any])(using Quotes) =
7+
e match
8+
case '{ $x: t } =>
9+
case '{ $x: C[t] } => // error
10+
case '{ $x: D[t] } => // error
11+
case '{ type t <: Int; $x: C[`t`] } =>

0 commit comments

Comments
 (0)