Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Print the type parameter bounds of higher kinded types #13372

Merged
merged 2 commits into from
Aug 25, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala
Original file line number Diff line number Diff line change
Expand Up @@ -348,15 +348,17 @@ class PlainPrinter(_ctx: Context) extends Printer {
case None => "?"
}

protected def decomposeLambdas(bounds: TypeBounds): (String, TypeBounds) =
def decompose(tp: Type) = tp.stripTypeVar match
protected def decomposeLambdas(bounds: TypeBounds): (Text, TypeBounds) =
def decompose(tp: Type): (Text, Type) = tp.stripTypeVar match
case lam: HKTypeLambda =>
val names =
if lam.isDeclaredVarianceLambda then
lam.paramNames.lazyZip(lam.declaredVariances).map((name, v) =>
varianceSign(v) + name)
else lam.paramNames
(names.mkString("[", ", ", "]"), lam.resType)
else lam.paramNames.map(_.toString)
val infos = lam.paramInfos.map(toText)
val tparams = names.zip(infos).map(_ ~ _)
("[" ~ Text(tparams, ",") ~ "]", lam.resType)
case _ =>
("", tp)
bounds match
Expand Down
40 changes: 20 additions & 20 deletions tests/neg-custom-args/i11637.check
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
-- [E057] Type Mismatch Error: tests/neg-custom-args/i11637.scala:11:33 ------------------------------------------------
11 | var h = new HKT3_1[FunctorImpl](); // error // error
| ^
| Type argument test2.FunctorImpl does not conform to upper bound [Generic2[T] <: Set[T]] =>> Any
| Type argument test2.FunctorImpl does not conform to upper bound [Generic2[T <: String] <: Set[T]] =>> Any

Explanation
===========

I tried to show that
test2.FunctorImpl
conforms to
[Generic2[T] <: Set[T]] =>> Any
[Generic2[T <: String] <: Set[T]] =>> Any
but the comparison trace ended with `false`:

==> test2.FunctorImpl <: [Generic2[T] <: Set[T]] =>> Any
==> test2.FunctorImpl <: [Generic2[T] <: Set[T]] =>> Any (recurring)
==> type bounds [[T] <: Set[T]] <: type bounds [[T] <: Iterable[T]]
==> type bounds [[T] <: Set[T]] <: type bounds [[T] <: Iterable[T]] (recurring)
==> test2.FunctorImpl <: [Generic2[T <: String] <: Set[T]] =>> Any
==> test2.FunctorImpl <: [Generic2[T <: String] <: Set[T]] =>> Any (recurring)
==> type bounds [[T <: String] <: Set[T]] <: type bounds [[T] <: Iterable[T]]
==> type bounds [[T <: String] <: Set[T]] <: type bounds [[T] <: Iterable[T]] (recurring)
==> [T <: String] =>> Set[T] <: Iterable
==> [T <: String] =>> Set[T] <: Iterable (recurring)
==> type bounds [] <: type bounds [ <: String]
Expand All @@ -30,31 +30,31 @@ but the comparison trace ended with `false`:
<== type bounds [] <: type bounds [ <: String] = false
<== [T <: String] =>> Set[T] <: Iterable (recurring) = false
<== [T <: String] =>> Set[T] <: Iterable = false
<== type bounds [[T] <: Set[T]] <: type bounds [[T] <: Iterable[T]] (recurring) = false
<== type bounds [[T] <: Set[T]] <: type bounds [[T] <: Iterable[T]] = false
<== test2.FunctorImpl <: [Generic2[T] <: Set[T]] =>> Any (recurring) = false
<== test2.FunctorImpl <: [Generic2[T] <: Set[T]] =>> Any = false
<== type bounds [[T <: String] <: Set[T]] <: type bounds [[T] <: Iterable[T]] (recurring) = false
<== type bounds [[T <: String] <: Set[T]] <: type bounds [[T] <: Iterable[T]] = false
<== test2.FunctorImpl <: [Generic2[T <: String] <: Set[T]] =>> Any (recurring) = false
<== test2.FunctorImpl <: [Generic2[T <: String] <: Set[T]] =>> Any = false

The tests were made under the empty constraint

-- [E057] Type Mismatch Error: tests/neg-custom-args/i11637.scala:11:21 ------------------------------------------------
11 | var h = new HKT3_1[FunctorImpl](); // error // error
| ^
| Type argument test2.FunctorImpl does not conform to upper bound [Generic2[T] <: Set[T]] =>> Any
| Type argument test2.FunctorImpl does not conform to upper bound [Generic2[T <: String] <: Set[T]] =>> Any

Explanation
===========

I tried to show that
test2.FunctorImpl
conforms to
[Generic2[T] <: Set[T]] =>> Any
[Generic2[T <: String] <: Set[T]] =>> Any
but the comparison trace ended with `false`:

==> test2.FunctorImpl <: [Generic2[T] <: Set[T]] =>> Any
==> test2.FunctorImpl <: [Generic2[T] <: Set[T]] =>> Any (recurring)
==> type bounds [[T] <: Set[T]] <: type bounds [[T] <: Iterable[T]]
==> type bounds [[T] <: Set[T]] <: type bounds [[T] <: Iterable[T]] (recurring)
==> test2.FunctorImpl <: [Generic2[T <: String] <: Set[T]] =>> Any
==> test2.FunctorImpl <: [Generic2[T <: String] <: Set[T]] =>> Any (recurring)
==> type bounds [[T <: String] <: Set[T]] <: type bounds [[T] <: Iterable[T]]
==> type bounds [[T <: String] <: Set[T]] <: type bounds [[T] <: Iterable[T]] (recurring)
==> [T <: String] =>> Set[T] <: Iterable
==> [T <: String] =>> Set[T] <: Iterable (recurring)
==> type bounds [] <: type bounds [ <: String]
Expand All @@ -69,9 +69,9 @@ but the comparison trace ended with `false`:
<== type bounds [] <: type bounds [ <: String] = false
<== [T <: String] =>> Set[T] <: Iterable (recurring) = false
<== [T <: String] =>> Set[T] <: Iterable = false
<== type bounds [[T] <: Set[T]] <: type bounds [[T] <: Iterable[T]] (recurring) = false
<== type bounds [[T] <: Set[T]] <: type bounds [[T] <: Iterable[T]] = false
<== test2.FunctorImpl <: [Generic2[T] <: Set[T]] =>> Any (recurring) = false
<== test2.FunctorImpl <: [Generic2[T] <: Set[T]] =>> Any = false
<== type bounds [[T <: String] <: Set[T]] <: type bounds [[T] <: Iterable[T]] (recurring) = false
<== type bounds [[T <: String] <: Set[T]] <: type bounds [[T] <: Iterable[T]] = false
<== test2.FunctorImpl <: [Generic2[T <: String] <: Set[T]] =>> Any (recurring) = false
<== test2.FunctorImpl <: [Generic2[T <: String] <: Set[T]] =>> Any = false

The tests were made under the empty constraint
14 changes: 14 additions & 0 deletions tests/printing/i13306.check
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[[syntax trees at end of typer]] // tests/printing/i13306.scala
package example {
class MyClass() extends Object() {}
class MembersContainer() extends Object() {
type MyType[T >: Nothing <: example.MyClass] = Comparable[T]
}
final lazy module val Exports: example.Exports = new example.Exports()
final module class Exports() extends Object() { this: example.Exports.type =>
val instance: example.MembersContainer = new example.MembersContainer()
export example.Exports.instance.*
final type MyType[T <: example.MyClass] = Comparable[T]
Copy link
Member

@bishabosha bishabosha Aug 25, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i noticed the lower bound does not print either, implying it's Nothing, however it is still inconsistent with how a TypeBoundsTree is printed - if you look at the original MyType - but that would lead to very verbose error messages I think.

One solution could be some print mode parameter which knows if we are printing "full trees" or just the type, which could allow you to decide when to always print the lower bound

}
}

12 changes: 12 additions & 0 deletions tests/printing/i13306.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package example

class MyClass

class MembersContainer {
type MyType[T <: MyClass] = Comparable[T]
}

object Exports {
val instance = new MembersContainer
export instance.*
}