diff --git a/presentation-compiler/src/main/dotty/tools/pc/PcInlayHintsProvider.scala b/presentation-compiler/src/main/dotty/tools/pc/PcInlayHintsProvider.scala index 3be5927a7aa0..f4e3bc8c9c10 100644 --- a/presentation-compiler/src/main/dotty/tools/pc/PcInlayHintsProvider.scala +++ b/presentation-compiler/src/main/dotty/tools/pc/PcInlayHintsProvider.scala @@ -19,6 +19,7 @@ import dotty.tools.dotc.core.Contexts.Context import dotty.tools.dotc.core.Flags import dotty.tools.dotc.core.NameOps.fieldName import dotty.tools.dotc.core.Names.Name +import dotty.tools.dotc.core.NameKinds.DefaultGetterName import dotty.tools.dotc.core.StdNames.* import dotty.tools.dotc.core.Symbols.* import dotty.tools.dotc.core.Types.* @@ -457,6 +458,13 @@ object Parameters: case TypeApply(fun, _) => getUnderlyingFun(fun) case t => t + @tailrec + def isDefaultArg(arg: Tree): Boolean = arg match + case Ident(name) => name.is(DefaultGetterName) + case Select(_, name) => name.is(DefaultGetterName) + case Apply(fun, _) => isDefaultArg(fun) + case _ => false + if (params.namedParameters() || params.byNameParameters()) then tree match case Apply(fun, args) if isRealApply(fun) => @@ -467,15 +475,16 @@ object Parameters: val funTp = fun.typeOpt.widenTermRefExpr val paramNames = funTp.paramNamess.flatten val paramInfos = funTp.paramInfoss.flatten + Some( - // Check if the function is an infix function or the underlying function is an infix function isInfixFun(fun, args) || underlyingFun.isInfix, ( args .zip(paramNames) .zip(paramInfos) .collect { - case ((arg, paramName), paramInfo) if !arg.span.isZeroExtent => (paramName.fieldName, arg.sourcePos, paramInfo.isByName) + case ((arg, paramName), paramInfo) if !arg.span.isZeroExtent && !isDefaultArg(arg) => + (paramName.fieldName, arg.sourcePos, paramInfo.isByName) } ) ) diff --git a/presentation-compiler/test/dotty/tools/pc/tests/inlayHints/InlayHintsSuite.scala b/presentation-compiler/test/dotty/tools/pc/tests/inlayHints/InlayHintsSuite.scala index bc4443ee5d28..1152e2928ad6 100644 --- a/presentation-compiler/test/dotty/tools/pc/tests/inlayHints/InlayHintsSuite.scala +++ b/presentation-compiler/test/dotty/tools/pc/tests/inlayHints/InlayHintsSuite.scala @@ -1243,4 +1243,61 @@ class InlayHintsSuite extends BaseInlayHintsSuite { |} |""".stripMargin ) + + @Test def `default-parameter` = + check( + """|object Main { + | def foo(a: Int, b: Int = 2) = a + b + | val x = foo(1) + |} + |""".stripMargin, + """|object Main { + | def foo(a: Int, b: Int = 2)/*: Int<>*/ = a + b + | val x/*: Int<>*/ = foo(/*a = */1) + |} + |""".stripMargin + ) + + @Test def `default-parameter-2` = + check( + """|object Main { + | def foo(a: Int = 10, b: Int = 2) = a + b + | val x = foo(b = 1) + |} + |""".stripMargin, + """|object Main { + | def foo(a: Int = 10, b: Int = 2)/*: Int<>*/ = a + b + | val x/*: Int<>*/ = foo(b = 1) + |} + |""".stripMargin + ) + + @Test def `default-parameter-3` = + check( + """|object Main { + | def foo(a: Int, b: Int = 2, c: Int) = a + b + c + | val x = foo(a = 1, c = 2) + |} + |""".stripMargin, + """|object Main { + | def foo(a: Int, b: Int = 2, c: Int)/*: Int<>*/ = a + b + c + | val x/*: Int<>*/ = foo(a = 1, c = 2) + |} + |""".stripMargin + ) + + @Test def `default-parameter-4` = + check( + """|object Main { + | def foo(a: Int, b: Int = 2, c: Int) = a + b + c + | val x = foo(1, 2, 3) + |} + |""".stripMargin, + """|object Main { + | def foo(a: Int, b: Int = 2, c: Int)/*: Int<>*/ = a + b + c + | val x/*: Int<>*/ = foo(/*a = */1, /*b = */2, /*c = */3) + |} + |""".stripMargin + ) + } diff --git a/tests/neg-macros/i22616b.check b/tests/neg-macros/i22616b.check deleted file mode 100644 index 3c6007276cef..000000000000 --- a/tests/neg-macros/i22616b.check +++ /dev/null @@ -1,13 +0,0 @@ --- [E007] Type Mismatch Error: tests/neg-macros/i22616b.scala:17:18 ---------------------------------------------------- -17 | case '{ Foo($y: t) } => // error - | ^^^^^ - | Found: t - | Required: String - | - | longer explanation available when compiling with `-explain` --- [E006] Not Found Error: tests/neg-macros/i22616b.scala:18:19 -------------------------------------------------------- -18 | '{type S = t; ()} // error - | ^ - | Not found: type t - | - | longer explanation available when compiling with `-explain` diff --git a/tests/neg-macros/i22616b.scala b/tests/neg-macros/i22616b.scala deleted file mode 100644 index 45926f4e0d37..000000000000 --- a/tests/neg-macros/i22616b.scala +++ /dev/null @@ -1,22 +0,0 @@ -// This test illustrates a current limitation of quoted pattern type variables, -// which has been discussed in https://github.com/scala/scala3/issues/22616#issuecomment-3012534064: -// These type variables do not have bound in general (see `typedQuotedTypeVar`), -// so they might not conform to the expected type. Here, `t` does not conform -// to `String`. - -import scala.quoted.{FromExpr, Expr, Quotes} - -case class Foo(x: String) - -object Macro: - inline def myMacro(): Unit = - ${ myMacroImpl('{Foo("hello")}) } - - def myMacroImpl(x: Expr[Foo])(using Quotes): Expr[Unit] = - x match - case '{ Foo($y: t) } => // error - '{type S = t; ()} // error - case _ => - println("not a foo") - - '{()} diff --git a/tests/run-macros/i22616c.check b/tests/run-macros/i22616c.check deleted file mode 100644 index d1918272a8f7..000000000000 --- a/tests/run-macros/i22616c.check +++ /dev/null @@ -1 +0,0 @@ -_B_ diff --git a/tests/run-macros/i22616c/Macro_4.scala b/tests/run-macros/i22616c/Macro_4.scala deleted file mode 100644 index 02e677db3428..000000000000 --- a/tests/run-macros/i22616c/Macro_4.scala +++ /dev/null @@ -1,11 +0,0 @@ -import scala.quoted.* - -object Macro: - inline def myMacro[T](): String = - ${ myMacroImpl[T]() } - - def myMacroImpl[T: Type]()(using Quotes): Expr[String] = - import quotes.reflect.* - val myTypeRepr = MyTypeRepr(TypeRepr.of[T]) - val `caseName`(name) = myTypeRepr.requiredAnnotationValue[caseName] - Expr(name) diff --git a/tests/run-macros/i22616c/MyTypeRepr_3.scala b/tests/run-macros/i22616c/MyTypeRepr_3.scala deleted file mode 100644 index 1a35889d403d..000000000000 --- a/tests/run-macros/i22616c/MyTypeRepr_3.scala +++ /dev/null @@ -1,33 +0,0 @@ -import scala.quoted.* - -final class MyTypeRepr(using val quotes: Quotes)(val unwrap: quotes.reflect.TypeRepr) { - import quotes.reflect.* - - def getAnnotation(annotTpe: quotes.reflect.Symbol): Option[quotes.reflect.Term] = - unwrap.typeSymbol.getAnnotation(annotTpe) - - def optionalAnnotation[Annot: Type]: Option[Expr[Annot]] = { - val annotTpe = TypeRepr.of[Annot] - val annotFlags = annotTpe.typeSymbol.flags - - if (annotFlags.is(Flags.Abstract) || annotFlags.is(Flags.Trait)) - report.errorAndAbort(s"Bad annotation type ${annotTpe.show} is abstract") - - this.getAnnotation(annotTpe.typeSymbol) match - case Some(tree) if tree.tpe <:< annotTpe => Some(tree.asExprOf[Annot]) - case _ => None - } - - def requiredAnnotation[Annot: Type]: Expr[Annot] = - optionalAnnotation[Annot].getOrElse(report.errorAndAbort(s"Missing required annotation `${TypeRepr.of[Annot].show}` for `$this`")) - - def optionalAnnotationValue[Annot: {Type, FromExpr}]: Option[Annot] = - optionalAnnotation[Annot].map { expr => - expr.value.getOrElse(report.errorAndAbort(s"Found annotation `${TypeRepr.of[Annot].show}` for `$this`, but are unable to extract Expr.value\n${expr.show}")) - } - - def requiredAnnotationValue[Annot: {Type, FromExpr}]: Annot = { - val expr = requiredAnnotation[Annot] - expr.value.getOrElse(report.errorAndAbort(s"Found annotation `${TypeRepr.of[Annot].show}` for `$this`, but are unable to extract Expr.value\n${expr.show}")) - } -} diff --git a/tests/run-macros/i22616c/SealedTrait3_2.scala b/tests/run-macros/i22616c/SealedTrait3_2.scala deleted file mode 100644 index 9141a9ebd08b..000000000000 --- a/tests/run-macros/i22616c/SealedTrait3_2.scala +++ /dev/null @@ -1,8 +0,0 @@ -sealed trait SealedTrait3[+A, +B] -object SealedTrait3 { - final case class AB1[+B, +A](a: B, b: A) extends SealedTrait3[B, A] - final case class AB2[+C, +D](a: C, b: D) extends SealedTrait3[D, C] - final case class A[+T](a: T) extends SealedTrait3[T, Nothing] - @caseName("_B_") final case class B[+T](b: T) extends SealedTrait3[Nothing, T] - case object Neither extends SealedTrait3[Nothing, Nothing] -} diff --git a/tests/run-macros/i22616c/Test_5.scala b/tests/run-macros/i22616c/Test_5.scala deleted file mode 100644 index c8d177a5ae1b..000000000000 --- a/tests/run-macros/i22616c/Test_5.scala +++ /dev/null @@ -1,2 +0,0 @@ -@main def Test = - println(Macro.myMacro[SealedTrait3.B[Any]]()) diff --git a/tests/run-macros/i22616c/caseName_1.scala b/tests/run-macros/i22616c/caseName_1.scala deleted file mode 100644 index c8fee116e2e9..000000000000 --- a/tests/run-macros/i22616c/caseName_1.scala +++ /dev/null @@ -1,14 +0,0 @@ -import scala.quoted.* - -final case class caseName(name: String) extends scala.annotation.Annotation -object caseName { - // This demonstrates a workaround for issue #22616. - given FromExpr[caseName] = - new FromExpr[caseName] { - override def unapply(x: Expr[caseName])(using Quotes): Option[caseName] = - x match { - case '{ new `caseName`(${ Expr(name) }) } => Some(caseName(name)) - case _ => println(x.show); None - } - } -} diff --git a/tests/warn/i23164.scala b/tests/warn/i23164.scala index ac068555a5b3..b82e21d8d7bb 100644 --- a/tests/warn/i23164.scala +++ b/tests/warn/i23164.scala @@ -21,7 +21,7 @@ class T20[F[_]] class T21[F[_]] class T22[F[_]] -class Result[F[_]: {T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19,T20,T21,T22}] +class Result[F[_]: T1 :T2 :T3 :T4 :T5 :T6 :T7 :T8 :T9 :T10 :T11 :T12 :T13 :T14 :T15 :T16 :T17 :T18 :T19 :T20 :T21 :T22] val r = for t1 <- Option(new T1[Option])