Skip to content

Commit 72d0026

Browse files
authored
Approximate annotated types in wildApprox (#22893)
Fixes #22874. `wildApprox` approximates parameter references and type variables by wildcards. When doing so for an `AnnotatedType`, this can produce trees with wildcards types, causing the type assigner to fail. For example, consider `Apply(fn, args)` where `fn` has type `TermParamRef`. Applying `wildApprox` will approximate the type of `fn` to a wildcard, leading [the type assigner for `Apply`](https://github.com/scala/scala3/blob/cb97c40930d335e0fca38238682d218c3e718bd8/compiler/src/dotty/tools/dotc/typer/TypeAssigner.scala#L298) to emit an error stating that `<?>` does not take parameters. This issue is somehow similar to the one described in #19957 (comment), which was fixed by #21941 (and re-worked in #22839). This PR fixes the issue by approximating annotated types in `wildApprox`: annotated types are approximated by their parent types if they are not refining, or by wildcards upper-bounded by their parent types if they are.
2 parents fa34018 + 4cdeb81 commit 72d0026

File tree

2 files changed

+16
-0
lines changed

2 files changed

+16
-0
lines changed

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

+9
Original file line numberDiff line numberDiff line change
@@ -1017,6 +1017,15 @@ object ProtoTypes {
10171017
paramInfos = tl.paramInfos.mapConserve(wildApprox(_, theMap, seen, internal1).bounds),
10181018
resType = wildApprox(tl.resType, theMap, seen, internal1)
10191019
)
1020+
case tp @ AnnotatedType(parent, _) =>
1021+
// This case avoids approximating types in the annotation tree, which can
1022+
// cause the type assigner to fail.
1023+
// See #22893 and tests/pos/annot-default-arg-22874.scala.
1024+
val parentApprox = wildApprox(parent, theMap, seen, internal)
1025+
if tp.isRefining then
1026+
WildcardType(TypeBounds.upper(parentApprox))
1027+
else
1028+
parentApprox
10201029
case _ =>
10211030
(if (theMap != null && seen.eq(theMap.seen)) theMap else new WildApproxMap(seen, internal))
10221031
.mapOver(tp)
+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package defaultArgBug
2+
3+
class staticAnnot(arg: Int) extends scala.annotation.StaticAnnotation
4+
class refiningAnnot(arg: Int) extends scala.annotation.RefiningAnnotation
5+
6+
def f1(a: Int, b: Int @staticAnnot(a + a) = 42): Int = b
7+
def f2(a: Int, b: Int @refiningAnnot(a + a) = 42): Int = b

0 commit comments

Comments
 (0)