diff --git a/compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala b/compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala
index 89a2cbbfbc21..db2faa2b28fd 100644
--- a/compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala
+++ b/compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala
@@ -950,6 +950,15 @@ object ProtoTypes {
paramInfos = tl.paramInfos.mapConserve(wildApprox(_, theMap, seen, internal1).bounds),
resType = wildApprox(tl.resType, theMap, seen, internal1)
)
+ case tp @ AnnotatedType(parent, _) =>
+ // This case avoids approximating types in the annotation tree, which can
+ // cause the type assigner to fail.
+ // See #22893 and tests/pos/annot-default-arg-22874.scala.
+ val parentApprox = wildApprox(parent, theMap, seen, internal)
+ if tp.isRefining then
+ WildcardType(TypeBounds.upper(parentApprox))
+ else
+ parentApprox
case _ =>
(if (theMap != null && seen.eq(theMap.seen)) theMap else new WildApproxMap(seen, internal))
.mapOver(tp)
diff --git a/tests/pos/annot-default-arg-22874.scala b/tests/pos/annot-default-arg-22874.scala
new file mode 100644
index 000000000000..7a983f4d3351
--- /dev/null
+++ b/tests/pos/annot-default-arg-22874.scala
@@ -0,0 +1,7 @@
+package defaultArgBug
+
+class staticAnnot(arg: Int) extends scala.annotation.StaticAnnotation
+class refiningAnnot(arg: Int) extends scala.annotation.RefiningAnnotation
+
+def f1(a: Int, b: Int @staticAnnot(a + a) = 42): Int = b
+def f2(a: Int, b: Int @refiningAnnot(a + a) = 42): Int = b