From 21deedf58ae787717baecb8ab186cd1c5d11e258 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Sat, 26 Oct 2019 15:04:49 +0200 Subject: [PATCH] Fix #6938: Expand tuples when synthesizing given names Also: Add more explanations on how names are synthesized. --- compiler/src/dotty/tools/dotc/ast/Desugar.scala | 4 ++-- docs/docs/reference/contextual/delegates.md | 2 +- docs/docs/reference/contextual/relationship-implicits.md | 3 +++ tests/pos/i6938.scala | 5 +++++ 4 files changed, 11 insertions(+), 3 deletions(-) create mode 100644 tests/pos/i6938.scala diff --git a/compiler/src/dotty/tools/dotc/ast/Desugar.scala b/compiler/src/dotty/tools/dotc/ast/Desugar.scala index de2ff5c8f1ca..eba58edbcd39 100644 --- a/compiler/src/dotty/tools/dotc/ast/Desugar.scala +++ b/compiler/src/dotty/tools/dotc/ast/Desugar.scala @@ -963,7 +963,7 @@ object desugar { case Some(DefDef(name, _, (vparam :: _) :: _, _, _)) => s"${name}_of_${inventTypeName(vparam.tpt)}" case _ => - ctx.error(i"anonymous instance must have `as` part or must define at least one extension method", impl.sourcePos) + ctx.error(i"anonymous instance must implement a type or have at least one extension method", impl.sourcePos) nme.ERROR.toString } else @@ -986,7 +986,7 @@ object desugar { case tree: LambdaTypeTree => apply(x, tree.body) case tree: Tuple => - if (followArgs) extractArgs(tree.trees) else "Tuple" + extractArgs(tree.trees) case tree: Function if tree.args.nonEmpty => if (followArgs) s"${extractArgs(tree.args)}_to_${apply("", tree.body)}" else "Function" case _ => foldOver(x, tree) diff --git a/docs/docs/reference/contextual/delegates.md b/docs/docs/reference/contextual/delegates.md index fdf9744340e0..97270aa66832 100644 --- a/docs/docs/reference/contextual/delegates.md +++ b/docs/docs/reference/contextual/delegates.md @@ -45,7 +45,7 @@ given Ord[Int] { ... } given [T](given Ord[T]): Ord[List[T]] { ... } ``` If the name of a given is missing, the compiler will synthesize a name from -the type(s) in the `as` clause. +the implemented type(s). ## Alias Givens diff --git a/docs/docs/reference/contextual/relationship-implicits.md b/docs/docs/reference/contextual/relationship-implicits.md index c6d18751524d..eaa54fbd75a2 100644 --- a/docs/docs/reference/contextual/relationship-implicits.md +++ b/docs/docs/reference/contextual/relationship-implicits.md @@ -59,6 +59,9 @@ The synthesized type names are formed from - the simple name(s) of the implemented type(s), leaving out any prefixes, - the simple name(s) of the toplevel argument type constructors to these types. +Tuples are treated as transparent, i.e. a type `F[(X, Y)]` would get the synthesized name +`F_X_Y`. Directly implemented function types `A => B` are represented as `A_to_B`. Function types used as arguments to other type constructors are represented as `Function`. + Anonymous given instances that define extension methods without also implementing a type get their name from the name of the first extension method and the toplevel type constructor of its first parameter. For example, the given instance diff --git a/tests/pos/i6938.scala b/tests/pos/i6938.scala new file mode 100644 index 000000000000..04ebf7cc440a --- /dev/null +++ b/tests/pos/i6938.scala @@ -0,0 +1,5 @@ +trait Foo[T] +object Foo with + given [T]: Foo[Tuple1[T]] + given [T, U]: Foo[(T, U)] + given [T, U, V]: Foo[(T, U, V)] \ No newline at end of file