From cfbca8c660c21edeb3a6a83e8fe736ea9f6dd1c1 Mon Sep 17 00:00:00 2001 From: Quentin Bernet Date: Wed, 26 Jan 2022 10:29:06 +0100 Subject: [PATCH] Fix PlainPrinter.scala: incorect type pararameters What it prints might be counter intuitive at first, but is correct The clearest example is in i5345, where otherwise the printed output doesn't correspond to the declaration --- .../src/dotty/tools/dotc/printing/PlainPrinter.scala | 7 ++++--- compiler/test-resources/repl/i5345 | 2 +- .../dotty/tools/languageserver/CompletionTest.scala | 10 +++++----- tests/neg-custom-args/fatal-warnings/i9408a.check | 4 ++-- 4 files changed, 12 insertions(+), 11 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala b/compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala index d3545f09b0e7..64c11d190672 100644 --- a/compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala +++ b/compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala @@ -211,7 +211,8 @@ class PlainPrinter(_ctx: Context) extends Printer { ~ keywordText("erased ").provided(tp.isErasedMethod) ~ keywordText("implicit ").provided(tp.isImplicitMethod && !tp.isContextualMethod) ~ paramsText(tp) - ~ (if tp.resultType.isInstanceOf[MethodType] then ")" else "): ") + ~ ")" + ~ (Str(": ") provided !tp.resultType.isInstanceOf[MethodOrPoly]) ~ toText(tp.resultType) } case tp: ExprType => @@ -223,7 +224,7 @@ class PlainPrinter(_ctx: Context) extends Printer { case tp: PolyType => changePrec(GlobalPrec) { "[" ~ paramsText(tp) ~ "]" ~ lambdaHash(tp) ~ - (Str(" => ") provided !tp.resultType.isInstanceOf[MethodType]) ~ + (Str(": ") provided !tp.resultType.isInstanceOf[MethodOrPoly]) ~ toTextGlobal(tp.resultType) } case AnnotatedType(tpe, annot) => @@ -418,7 +419,7 @@ class PlainPrinter(_ctx: Context) extends Printer { (if (isParameter) ": => " else ": ") ~ toTextGlobal(tp.widenExpr) case tp: PolyType => "[" ~ paramsText(tp) ~ "]" - ~ (Str(": ") provided !tp.resultType.isInstanceOf[MethodType]) + ~ (Str(": ") provided !tp.resultType.isInstanceOf[MethodOrPoly]) ~ toTextGlobal(tp.resultType) case tp => ": " ~ toTextGlobal(tp) diff --git a/compiler/test-resources/repl/i5345 b/compiler/test-resources/repl/i5345 index 458aab906978..4cacdf7ae985 100644 --- a/compiler/test-resources/repl/i5345 +++ b/compiler/test-resources/repl/i5345 @@ -1,2 +1,2 @@ scala> def x[A, B]: Conversion[A, B] = _ => ??? -def x[A, B] => Conversion[A, B] +def x[A, B]: Conversion[A, B] diff --git a/language-server/test/dotty/tools/languageserver/CompletionTest.scala b/language-server/test/dotty/tools/languageserver/CompletionTest.scala index 1657549f9a7a..c155694c494f 100644 --- a/language-server/test/dotty/tools/languageserver/CompletionTest.scala +++ b/language-server/test/dotty/tools/languageserver/CompletionTest.scala @@ -643,7 +643,7 @@ class CompletionTest { code"""object Foo |extension (foo: Foo.type) def xxxx[A]: Int = 1 |object Main { Foo.xx${m1} }""" - .completion(("xxxx", Method, "[A] => Int")) + .completion(("xxxx", Method, "[A]: Int")) } @Test def completeExtensionMethodWithParameterAndTypeParameter: Unit = { @@ -762,7 +762,7 @@ class CompletionTest { |given Baz with {} |extension [A](using bar: Bar)(a: A)(using baz: Baz) def xxxx[B]: Either[A, B] = Left(a) |object Main { 123.xx${m1} }""" - .completion(("xxxx", Method, "(using baz: Baz): [B] => Either[Int, B]")) + .completion(("xxxx", Method, "(using baz: Baz)[B]: Either[Int, B]")) } @Test def completeExtensionMethodWithTypeBounds: Unit = { @@ -772,7 +772,7 @@ class CompletionTest { |extension [A >: Bar](a: A) def xxxx[B <: a.type]: Either[A, B] = Left(a) |val foo = new Foo {} |object Main { foo.xx${m1} }""" - .completion(("xxxx", Method, "[B <: (foo : Foo)] => Either[Foo, B]")) + .completion(("xxxx", Method, "[B <: (foo : Foo)]: Either[Foo, B]")) } @Test def completeInheritedExtensionMethod: Unit = { @@ -1034,7 +1034,7 @@ class CompletionTest { ("→", Method, "[B](y: B): (A, B)"), ("!=", Method, "(x$0: Any): Boolean"), ("fromOrdinal", Method, "(ordinal: Int): Foo.Bar"), - ("asInstanceOf", Method, "[X0] => X0"), + ("asInstanceOf", Method, "[X0]: X0"), ("->", Method, "[B](y: B): (A, B)"), ("wait", Method, "(x$0: Long, x$1: Int): Unit"), ("`back-tick`", Field, "Foo.Bar"), @@ -1042,7 +1042,7 @@ class CompletionTest { ("formatted", Method, "(fmtstr: String): String"), ("ensuring", Method, "(cond: A => Boolean, msg: => Any): A"), ("wait", Method, "(): Unit"), - ("isInstanceOf", Method, "[X0] => Boolean"), + ("isInstanceOf", Method, "[X0]: Boolean"), ("`match`", Field, "Foo.Bar"), ("toString", Method, "(): String"), ("ensuring", Method, "(cond: A => Boolean): A"), diff --git a/tests/neg-custom-args/fatal-warnings/i9408a.check b/tests/neg-custom-args/fatal-warnings/i9408a.check index f3eceb070113..ce2f8c4edd15 100644 --- a/tests/neg-custom-args/fatal-warnings/i9408a.check +++ b/tests/neg-custom-args/fatal-warnings/i9408a.check @@ -9,7 +9,7 @@ -- Error: tests/neg-custom-args/fatal-warnings/i9408a.scala:26:20 ------------------------------------------------------ 26 | val length: Int = "qwerty" // error | ^^^^^^^^ - |The conversion (Test5.implicitLength : [A] => String => Int) will not be applied implicitly here in Scala 3 because only implicit methods and instances of Conversion class will continue to work as implicit views. + |The conversion (Test5.implicitLength : [A]: String => Int) will not be applied implicitly here in Scala 3 because only implicit methods and instances of Conversion class will continue to work as implicit views. -- Error: tests/neg-custom-args/fatal-warnings/i9408a.scala:31:20 ------------------------------------------------------ 31 | val length: Int = "qwerty" // error | ^^^^^^^^ @@ -21,4 +21,4 @@ -- Error: tests/neg-custom-args/fatal-warnings/i9408a.scala:59:2 ------------------------------------------------------- 59 | 123.foo // error | ^^^ - |The conversion (Test11.a2foo : [A] => A => Test11.Foo) will not be applied implicitly here in Scala 3 because only implicit methods and instances of Conversion class will continue to work as implicit views. + |The conversion (Test11.a2foo : [A]: A => Test11.Foo) will not be applied implicitly here in Scala 3 because only implicit methods and instances of Conversion class will continue to work as implicit views.