Skip to content

Commit

Permalink
Stabilise SIP-47
Browse files Browse the repository at this point in the history
  • Loading branch information
hamzaremmal committed Jun 28, 2024
1 parent f880d6e commit 6072739
Show file tree
Hide file tree
Showing 27 changed files with 24 additions and 75 deletions.
4 changes: 0 additions & 4 deletions compiler/src/dotty/tools/dotc/config/Feature.scala
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ object Feature:
val symbolLiterals = deprecated("symbolLiterals")
val fewerBraces = experimental("fewerBraces")
val saferExceptions = experimental("saferExceptions")
val clauseInterleaving = experimental("clauseInterleaving")
val pureFunctions = experimental("pureFunctions")
val captureChecking = experimental("captureChecking")
val into = experimental("into")
Expand Down Expand Up @@ -60,7 +59,6 @@ object Feature:
(symbolLiterals, "Allow symbol literals"),
(fewerBraces, "Enable support for using indentation for arguments"),
(saferExceptions, "Enable safer exceptions"),
(clauseInterleaving, "Enable clause interleaving"),
(pureFunctions, "Enable pure functions for capture checking"),
(captureChecking, "Enable experimental capture checking"),
(into, "Allow into modifier on parameter types"),
Expand Down Expand Up @@ -121,8 +119,6 @@ object Feature:

def namedTypeArgsEnabled(using Context) = enabled(namedTypeArguments)

def clauseInterleavingEnabled(using Context) = enabled(clauseInterleaving)

def genericNumberLiteralsEnabled(using Context) = enabled(genericNumberLiterals)

def scala2ExperimentalMacroEnabled(using Context) = enabled(scala2macros)
Expand Down
11 changes: 1 addition & 10 deletions compiler/src/dotty/tools/dotc/parsing/Parsers.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3877,16 +3877,7 @@ object Parsers {
val mods1 = addFlag(mods, Method)
val ident = termIdent()
var name = ident.name.asTermName
val paramss =
if in.featureEnabled(Feature.clauseInterleaving) then
// If you are making interleaving stable manually, please refer to the PR introducing it instead, section "How to make non-experimental"
typeOrTermParamClauses(ParamOwner.Def, numLeadParams)
else
val tparams = typeParamClauseOpt(ParamOwner.Def)
val vparamss = termParamClauses(ParamOwner.Def, numLeadParams)

joinParams(tparams, vparamss)

val paramss = typeOrTermParamClauses(ParamOwner.Def, numLeadParams)
var tpt = fromWithinReturnType { typedOpt() }

if (migrateTo3) newLineOptWhenFollowedBy(LBRACE)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,9 @@
---
layout: doc-page
title: "Generalized Method Syntax"
nightlyOf: https://docs.scala-lang.org/scala3/reference/experimental/generalized-method-syntax.html
nightlyOf: https://docs.scala-lang.org/scala3/reference/other-new-features/generalized-method-syntax.html
---

This feature is not yet part of the Scala 3 language definition. It can be made available by a language import:

```scala
import scala.language.experimental.clauseInterleaving
```

The inclusion of using clauses is not the only way in which methods have been updated, type parameter clauses are now allowed in any number and at any position.

## Syntax Changes
Expand Down Expand Up @@ -51,7 +45,7 @@ trait DB {
}
```

Note that simply replacing `V` by `k.Value` would not be equivalent. For example, if `k.Value` is `Some[Int]`, only the above allows:
Note that simply replacing `V` by `k.Value` would not be equivalent. For example, if `k.Value` is `Some[Int]`, only the above allows:
`getOrElse(k)[Option[Int]](None)`, which returns a `Number`.

## Details
Expand Down
1 change: 1 addition & 0 deletions library/src/scala/runtime/stdLibPatches/language.scala
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ object language:
* @see [[https://github.com/scala/improvement-proposals/blob/main/content/clause-interleaving.md]]
*/
@compileTimeOnly("`clauseInterleaving` can only be used at compile time in import statements")
@deprecated("`clauseInterleaving` is now standard, no language import is needed", since = "3.6")
object clauseInterleaving

/** Experimental support for pure function type syntax
Expand Down
2 changes: 0 additions & 2 deletions scaladoc-testcases/src/tests/extensionParams.scala
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,6 @@ extension (using Unit)(a: Int)
def f14(): Any
= ???

import scala.language.experimental.clauseInterleaving

extension (using String)(using Int)(a: Animal)(using Unit)(using Number)
def f16(b: Any)[T](c: T): T
= ???
Expand Down
2 changes: 0 additions & 2 deletions scaladoc-testcases/src/tests/methodsAndConstructors.scala
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package tests.methodsAndConstructors

import scala.language.experimental.clauseInterleaving

class A
class B extends A
class C
Expand Down
3 changes: 1 addition & 2 deletions tests/neg/interleaving-ab.scala
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import scala.language.experimental.clauseInterleaving

object Ab:
given String = ""
given Double = 0

def illegal[A][B](x: A)(using B): B = summon[B] // error: Type parameter lists must be separated by a term or using parameter list

def ab[A](x: A)[B](using B): B = summon[B]
def test =
ab[Int](0: Int) // error
1 change: 0 additions & 1 deletion tests/neg/interleaving-params.scala
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import scala.language.experimental.clauseInterleaving

class Params{
def bar[T](x: T)[T]: String = ??? // error
Expand Down
1 change: 0 additions & 1 deletion tests/neg/interleaving-signatureCollision.scala
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import scala.language.experimental.clauseInterleaving

object signatureCollision:
def f[T](x: T)[U](y: U) = (x,y)
Expand Down
28 changes: 14 additions & 14 deletions tests/neg/interleaving-typeApply.check
Original file line number Diff line number Diff line change
@@ -1,29 +1,29 @@
-- [E057] Type Mismatch Error: tests/neg/interleaving-typeApply.scala:10:11 --------------------------------------------
10 | f3[String]() // error
| ^
| Type argument String does not conform to upper bound Int
|
| longer explanation available when compiling with `-explain`
-- [E057] Type Mismatch Error: tests/neg/interleaving-typeApply.scala:11:16 --------------------------------------------
11 | f5[Int][Unit] // error
-- [E057] Type Mismatch Error: tests/neg/interleaving-typeApply.scala:9:11 ---------------------------------------------
9 | f3[String]() // error
| ^
| Type argument String does not conform to upper bound Int
|
| longer explanation available when compiling with `-explain`
-- [E057] Type Mismatch Error: tests/neg/interleaving-typeApply.scala:10:16 --------------------------------------------
10 | f5[Int][Unit] // error
| ^
| Type argument Unit does not conform to upper bound String
|
| longer explanation available when compiling with `-explain`
-- [E057] Type Mismatch Error: tests/neg/interleaving-typeApply.scala:12:19 --------------------------------------------
12 | f5[String][Unit] // error // error
-- [E057] Type Mismatch Error: tests/neg/interleaving-typeApply.scala:11:19 --------------------------------------------
11 | f5[String][Unit] // error // error
| ^
| Type argument Unit does not conform to upper bound String
|
| longer explanation available when compiling with `-explain`
-- [E057] Type Mismatch Error: tests/neg/interleaving-typeApply.scala:12:11 --------------------------------------------
12 | f5[String][Unit] // error // error
-- [E057] Type Mismatch Error: tests/neg/interleaving-typeApply.scala:11:11 --------------------------------------------
11 | f5[String][Unit] // error // error
| ^
| Type argument String does not conform to upper bound Int
|
| longer explanation available when compiling with `-explain`
-- [E057] Type Mismatch Error: tests/neg/interleaving-typeApply.scala:13:11 --------------------------------------------
13 | f7[String]()[Unit] // error
-- [E057] Type Mismatch Error: tests/neg/interleaving-typeApply.scala:12:11 --------------------------------------------
12 | f7[String]()[Unit] // error
| ^
| Type argument String does not conform to upper bound Int
|
Expand Down
3 changes: 1 addition & 2 deletions tests/neg/interleaving-typeApply.scala
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import scala.language.experimental.clauseInterleaving

object typeApply:

def f3[T <: Int](using DummyImplicit)[U <: String](): T => T = ???
def f5[T <: Int](using DummyImplicit)[U <: String]: [X <: Unit] => X => X = ???
def f7[T <: Int](using DummyImplicit)[U <: String]()[X <: Unit]: X => X = ???
Expand Down
1 change: 0 additions & 1 deletion tests/neg/interleaving-unmatched.scala
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import scala.language.experimental.clauseInterleaving

object unmatched:
def f1[T (x: T)] = ??? // error
Expand Down
8 changes: 4 additions & 4 deletions tests/neg/namedTypeParams.check
Original file line number Diff line number Diff line change
Expand Up @@ -92,11 +92,11 @@
| illegal repeated type application
| You might have meant something like:
| Test.f[Y = String, Int]
-- [E102] Syntax Error: tests/neg/namedTypeParams.scala:33:9 -----------------------------------------------------------
33 | f2[Y = String][X = Int](1, "") // error: Y is undefined
-- [E102] Syntax Error: tests/neg/namedTypeParams.scala:32:9 -----------------------------------------------------------
32 | f2[Y = String][X = Int](1, "") // error: Y is undefined
| ^^^^^^
| Type parameter Y is undefined. Expected one of X.
-- [E102] Syntax Error: tests/neg/namedTypeParams.scala:34:9 -----------------------------------------------------------
34 | f2[Y = String](1, "") // error: Y is undefined
-- [E102] Syntax Error: tests/neg/namedTypeParams.scala:33:9 -----------------------------------------------------------
33 | f2[Y = String](1, "") // error: Y is undefined
| ^^^^^^
| Type parameter Y is undefined. Expected one of X.
1 change: 0 additions & 1 deletion tests/neg/namedTypeParams.scala
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ object Test:

object TestInterleaving:
import language.experimental.namedTypeArguments
import language.experimental.clauseInterleaving
def f2[X](using DummyImplicit)[Y](x: X, y: Y): Int = ???

f2[Y = String][X = Int](1, "") // error: Y is undefined
Expand Down
6 changes: 0 additions & 6 deletions tests/neg/overrides.scala
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,6 @@ class A[T] {

def next: T = ???

import scala.language.experimental.clauseInterleaving

def b[U <: T](x: Int)[V >: T](y: String) = false
}

Expand All @@ -57,8 +55,6 @@ class B extends A[Int] {

override def next(): Int = ??? // error: incompatible type

import scala.language.experimental.clauseInterleaving

override def b[T <: Int](x: Int)(y: String) = true // error
}

Expand All @@ -68,8 +64,6 @@ class C extends A[String] {

override def next: Int = ??? // error: incompatible type

import scala.language.experimental.clauseInterleaving

override def b[T <: String](x: Int)[U >: Int](y: String) = true // error: incompatible type
}

Expand Down
1 change: 0 additions & 1 deletion tests/pos/interleaving-ba.scala
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import scala.language.experimental.clauseInterleaving

object BA {
given String = ""
Expand Down
1 change: 0 additions & 1 deletion tests/pos/interleaving-chainedParams.scala
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import scala.language.experimental.clauseInterleaving

object chainedParams{

Expand Down
1 change: 0 additions & 1 deletion tests/pos/interleaving-classless.scala
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import scala.language.experimental.clauseInterleaving

def f1[T]()[U](x: T, y: U): (T, U) = (x, y)
def f2[T](x: T)[U](y: U): (T, U) = (x, y)
Expand Down
1 change: 0 additions & 1 deletion tests/pos/interleaving-functor.scala
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import scala.language.experimental.clauseInterleaving

object functorInterleaving:
//taken from https://dotty.epfl.ch/docs/reference/contextual/type-classes.html
Expand Down
1 change: 0 additions & 1 deletion tests/pos/interleaving-newline.scala
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import scala.language.experimental.clauseInterleaving

object newline {
def multipleLines
Expand Down
1 change: 0 additions & 1 deletion tests/pos/interleaving-overload.scala
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import scala.language.experimental.clauseInterleaving

class A{

Expand Down
1 change: 0 additions & 1 deletion tests/pos/interleaving-params.scala
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import scala.language.experimental.clauseInterleaving

class Params{
type U
Expand Down
1 change: 0 additions & 1 deletion tests/pos/interleaving-signatureCollision.scala
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import scala.language.experimental.clauseInterleaving
import scala.annotation.targetName

object signatureCollision:
Expand Down
2 changes: 0 additions & 2 deletions tests/pos/interleaving-typeApply.scala
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import scala.language.experimental.clauseInterleaving

object typeApply:

Expand All @@ -12,7 +11,6 @@ object typeApply:
def f7[T <: Int](using DummyImplicit)[U <: String]()[X <: Unit]: X => X = ???

@main def test = {
import scala.language.experimental.namedTypeArguments
f0[Int][String]
f1[Int][String]
f2[Int][String]()
Expand Down
1 change: 0 additions & 1 deletion tests/pos/namedTypeParams.scala
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ object Test {
}

object TestInterleaving{
import language.experimental.clauseInterleaving
def f2[X](using DummyImplicit)[Y](x: X, y: Y): Int = ???

f2[X = Int][Y = String](1, "")
Expand Down
5 changes: 0 additions & 5 deletions tests/pos/overrides.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ class A[T] {

def f(x: T)(y: T = x) = y

import scala.language.experimental.clauseInterleaving

def b[U <: T](x: Int)[V >: T](y: String) = false

}
Expand All @@ -15,9 +13,6 @@ class B extends A[Int] {

f(2)()


import scala.language.experimental.clauseInterleaving

override def b[T <: Int](x: Int)[U >: Int](y: String) = true

}
1 change: 0 additions & 1 deletion tests/run/interleaving.scala
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import scala.language.experimental.clauseInterleaving

object Test extends App {
trait Key { type Value }
Expand Down

0 comments on commit 6072739

Please sign in to comment.