Skip to content

Commit 5de1da3

Browse files
authored
Merge pull request #15376 from dotty-staging/fix-15372
Handle unconstrained TypeVars when synthesizing ClassTags
2 parents 5015425 + 4548fab commit 5de1da3

File tree

2 files changed

+26
-16
lines changed

2 files changed

+26
-16
lines changed

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

+18-16
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import Types._, Flags._, Symbols._, Names._, StdNames._, Constants._
99
import TypeErasure.{erasure, hasStableErasure}
1010
import Decorators._
1111
import ProtoTypes._
12-
import Inferencing.fullyDefinedType
12+
import Inferencing.{fullyDefinedType, isFullyDefined}
1313
import ast.untpd
1414
import transform.SymUtils._
1515
import transform.TypeUtils._
@@ -30,21 +30,23 @@ class Synthesizer(typer: Typer)(using @constructorOnly c: Context):
3030
val synthesizedClassTag: SpecialHandler = (formal, span) =>
3131
formal.argInfos match
3232
case arg :: Nil =>
33-
fullyDefinedType(arg, "ClassTag argument", span) match
34-
case defn.ArrayOf(elemTp) =>
35-
val etag = typer.inferImplicitArg(defn.ClassTagClass.typeRef.appliedTo(elemTp), span)
36-
if etag.tpe.isError then EmptyTreeNoError else withNoErrors(etag.select(nme.wrap))
37-
case tp if hasStableErasure(tp) && !defn.isBottomClassAfterErasure(tp.typeSymbol) =>
38-
val sym = tp.typeSymbol
39-
val classTag = ref(defn.ClassTagModule)
40-
val tag =
41-
if defn.SpecialClassTagClasses.contains(sym) then
42-
classTag.select(sym.name.toTermName)
43-
else
44-
val clsOfType = escapeJavaArray(erasure(tp))
45-
classTag.select(nme.apply).appliedToType(tp).appliedTo(clsOf(clsOfType))
46-
withNoErrors(tag.withSpan(span))
47-
case tp => EmptyTreeNoError
33+
if isFullyDefined(arg, ForceDegree.all) then
34+
arg match
35+
case defn.ArrayOf(elemTp) =>
36+
val etag = typer.inferImplicitArg(defn.ClassTagClass.typeRef.appliedTo(elemTp), span)
37+
if etag.tpe.isError then EmptyTreeNoError else withNoErrors(etag.select(nme.wrap))
38+
case tp if hasStableErasure(tp) && !defn.isBottomClassAfterErasure(tp.typeSymbol) =>
39+
val sym = tp.typeSymbol
40+
val classTag = ref(defn.ClassTagModule)
41+
val tag =
42+
if defn.SpecialClassTagClasses.contains(sym) then
43+
classTag.select(sym.name.toTermName)
44+
else
45+
val clsOfType = escapeJavaArray(erasure(tp))
46+
classTag.select(nme.apply).appliedToType(tp).appliedTo(clsOf(clsOfType))
47+
withNoErrors(tag.withSpan(span))
48+
case tp => EmptyTreeNoError
49+
else EmptyTreeNoError
4850
case _ => EmptyTreeNoError
4951
end synthesizedClassTag
5052

tests/neg/i15372.scala

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import scala.reflect.ClassTag
2+
3+
class Test {
4+
private def test[A](result: A)(implicit ct: ClassTag[A]): A = result
5+
6+
test(1, 2) -> Array() // error
7+
8+
}

0 commit comments

Comments
 (0)