diff --git a/compiler/src/dotty/tools/dotc/core/Definitions.scala b/compiler/src/dotty/tools/dotc/core/Definitions.scala index f95bb3cea351..fd6fbb159f3f 100644 --- a/compiler/src/dotty/tools/dotc/core/Definitions.scala +++ b/compiler/src/dotty/tools/dotc/core/Definitions.scala @@ -1781,18 +1781,24 @@ class Definitions { || (sym eq Any_typeTest) || (sym eq Any_typeCast) - /** Is this type a `TupleN` type? + /** Is `tp` a `TupleN` type? + * + * @return true if the type of `tp` is `TupleN[T1, T2, ..., Tn]` + */ + def isDirectTupleNType(tp: Type)(using Context): Boolean = + val arity = tp.argInfos.length + arity <= MaxTupleArity && { + val tupletp = TupleType(arity) + tupletp != null && tp.isRef(tupletp.symbol) + } + + /** Is `tp` (an alias of) a `TupleN` type? * * @return true if the dealiased type of `tp` is `TupleN[T1, T2, ..., Tn]` */ - def isTupleNType(tp: Type)(using Context): Boolean = { + def isTupleNType(tp: Type)(using Context): Boolean = val tp1 = tp.dealias - val arity = tp1.argInfos.length - arity <= MaxTupleArity && { - val tupletp = TupleType(arity) - tupletp != null && tp1.isRef(tupletp.symbol) - } - } + isDirectTupleNType(tp1) def tupleType(elems: List[Type]): Type = { val arity = elems.length diff --git a/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala b/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala index ea729e9549d5..d8446a575ce8 100644 --- a/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala +++ b/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala @@ -165,7 +165,7 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) { changePrec(GlobalPrec) { val argStr: Text = if args.length == 2 - && !defn.isTupleNType(args.head) + && !defn.isDirectTupleNType(args.head) && !isGiven then atPrec(InfixPrec) { argText(args.head) } diff --git a/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionSuite.scala b/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionSuite.scala index 47e4cabb76f4..f64387ed00d4 100644 --- a/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionSuite.scala +++ b/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionSuite.scala @@ -147,6 +147,50 @@ class CompletionSuite extends BaseCompletionSuite: "XtensionMethod(a: Int): XtensionMethod" ) + @Test def tupleDirect = + check( + """ + |trait Foo { + | def setup: List[(String, String)] + |} + |object Foo { + | val foo: Foo = ??? + | foo.setup.exist@@ + |}""".stripMargin, + """|exists(p: ((String, String)) => Boolean): Boolean + |""".stripMargin + ) + + @Test def tupleAlias = + check( + """ + |trait Foo { + | def setup: List[Foo.TupleAliasResult] + |} + |object Foo { + | type TupleAliasResult = (String, String) + | val foo: Foo = ??? + | foo.setup.exist@@ + |}""".stripMargin, + """|exists(p: TupleAliasResult => Boolean): Boolean + |""".stripMargin + ) + + @Test def listAlias = + check( + """ + |trait Foo { + | def setup: List[Foo.ListAliasResult] + |} + |object Foo { + | type ListAliasResult = List[String] + | val foo: Foo = ??? + | foo.setup.exist@@ + |}""".stripMargin, + """|exists(p: ListAliasResult => Boolean): Boolean + |""".stripMargin + ) + @Ignore("This test should be handled by compiler fuzzy search") @Test def fuzzy = check(