diff --git a/docs/_docs/reference/dropped-features/type-projection.md b/docs/_docs/reference/dropped-features/type-projection.md index 08b5ffb34eca..9b9f643ceb6e 100644 --- a/docs/_docs/reference/dropped-features/type-projection.md +++ b/docs/_docs/reference/dropped-features/type-projection.md @@ -4,15 +4,18 @@ title: "Dropped: General Type Projection" nightlyOf: https://docs.scala-lang.org/scala3/reference/dropped-features/type-projection.html --- -Scala so far allowed general type projection `T#A` where `T` is an arbitrary type -and `A` names a type member of `T`. +Scala 2 allowed general type projection `T#A` where `T` is an arbitrary type and `A` names a type member of `T`. +This turns out to be [unsound](https://github.com/scala/scala3/issues/1050) (at least when combined with other Scala 3 features). -Scala 3 disallows this if `T` is an abstract type (class types and type aliases -are fine). This change was made because unrestricted type projection -is [unsound](https://github.com/lampepfl/dotty/issues/1050). - -This restriction rules out the [type-level encoding of a combinator -calculus](https://michid.wordpress.com/2010/01/29/scala-type-level-encoding-of-the-ski-calculus/). +To remedy this, Scala 3 only allows type projection if `T` is a concrete type (any type which is not abstract), an example for such a type would be a class type (`class T`). +A type is abstract if it is: +* An abstract type member (`type T` without `= SomeType`) +* A type parameter (`[T]`) +* An alias to an abstract type (`type T = SomeAbstractType`). +There are no restriction on `A` apart from the fact it has to be a member type of `T`, for example a subclass (`class T { class A }`). To rewrite code using type projections on abstract types, consider using path-dependent types or implicit parameters. + +This restriction rules out the [type-level encoding of a combinator +calculus](https://michid.wordpress.com/2010/01/29/scala-type-level-encoding-of-the-ski-calculus/). \ No newline at end of file