From bc20aa6b568874f787b1b2cd7e54c3b6b1791cc4 Mon Sep 17 00:00:00 2001 From: odersky Date: Mon, 22 Jan 2024 19:14:57 +0100 Subject: [PATCH] Handle default implicits to context parameters under -3.4-migration Synthesized calls for default implicits needed a using clause when the method was an implicit method, but had a context bound parameter in 3.4-migration. Also, we can't rewrite adding a `using` clause if the argument list is empty, since we are lacking precise position info. Fixes #19506 --- .../src/dotty/tools/dotc/printing/RefinedPrinter.scala | 2 +- compiler/src/dotty/tools/dotc/typer/Migrations.scala | 6 ++++-- compiler/src/dotty/tools/dotc/typer/Typer.scala | 5 ++++- tests/neg/i19506.scala | 8 ++++++++ 4 files changed, 17 insertions(+), 4 deletions(-) create mode 100644 tests/neg/i19506.scala diff --git a/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala b/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala index a556a87173f5..de9e21aa4146 100644 --- a/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala +++ b/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala @@ -309,7 +309,7 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) { toText(tp.argType) ~ " ?=>? " ~ toText(tp.resultType) case tp @ FunProto(args, resultType) => "[applied to (" - ~ keywordText("using ").provided(tp.isContextualMethod) + ~ keywordText("using ").provided(tp.applyKind == ApplyKind.Using) ~ argsTreeText(args) ~ ") returning " ~ toText(resultType) diff --git a/compiler/src/dotty/tools/dotc/typer/Migrations.scala b/compiler/src/dotty/tools/dotc/typer/Migrations.scala index 84db91f9dee9..8d468fd68bba 100644 --- a/compiler/src/dotty/tools/dotc/typer/Migrations.scala +++ b/compiler/src/dotty/tools/dotc/typer/Migrations.scala @@ -106,12 +106,14 @@ trait Migrations: && isContextBoundParams && pt.applyKind != ApplyKind.Using then - def rewriteMsg = Message.rewriteNotice("This code", mversion.patchFrom) + def rewriteMsg = + if pt.args.isEmpty then "" + else Message.rewriteNotice("This code", mversion.patchFrom) report.errorOrMigrationWarning( em"""Context bounds will map to context parameters. |A `using` clause is needed to pass explicit arguments to them.$rewriteMsg""", tree.srcPos, mversion) - if mversion.needsPatch then + if mversion.needsPatch && pt.args.nonEmpty then patch(Span(pt.args.head.span.start), "using ") end contextBoundParams diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala index 1303b64cbd12..fe2a6f92eb97 100644 --- a/compiler/src/dotty/tools/dotc/typer/Typer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala @@ -3906,7 +3906,10 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer if (arg.tpe.isError) Nil else untpd.NamedArg(pname, untpd.TypedSplice(arg)) :: Nil } val app = cpy.Apply(tree)(untpd.TypedSplice(tree), namedArgs) - if (wtp.isContextualMethod) app.setApplyKind(ApplyKind.Using) + val needsUsing = wtp.isContextualMethod || wtp.match + case MethodType(ContextBoundParamName(_) :: _) => sourceVersion.isAtLeast(`3.4`) + case _ => false + if needsUsing then app.setApplyKind(ApplyKind.Using) typr.println(i"try with default implicit args $app") typed(app, pt, locked) else issueErrors() diff --git a/tests/neg/i19506.scala b/tests/neg/i19506.scala new file mode 100644 index 000000000000..4e139fed07d0 --- /dev/null +++ b/tests/neg/i19506.scala @@ -0,0 +1,8 @@ +//> using options "-source 3.4-migration", + +trait Reader[T] +def read[T: Reader](s: String, trace: Boolean = false): T = ??? + +def Test = + read[Object]("") // error + read[Object]("")() // error