diff --git a/compiler/src/dotty/tools/dotc/config/Feature.scala b/compiler/src/dotty/tools/dotc/config/Feature.scala index 056f2703becb..ac7b62ddb5a4 100644 --- a/compiler/src/dotty/tools/dotc/config/Feature.scala +++ b/compiler/src/dotty/tools/dotc/config/Feature.scala @@ -60,6 +60,9 @@ object Feature: def dependentEnabled(using Context) = enabled(nme.dependent, defn.LanguageExperimentalModule.moduleClass) + def namedTypeArgsEnabled(using Context) = + enabled(nme.namedTypeArguments, defn.LanguageExperimentalModule.moduleClass) + def scala2ExperimentalMacroEnabled(using Context) = enabled("macros".toTermName, defn.LanguageExperimentalModule.moduleClass) diff --git a/compiler/src/dotty/tools/dotc/core/StdNames.scala b/compiler/src/dotty/tools/dotc/core/StdNames.scala index dc0bc7938255..dc67e3701604 100644 --- a/compiler/src/dotty/tools/dotc/core/StdNames.scala +++ b/compiler/src/dotty/tools/dotc/core/StdNames.scala @@ -528,6 +528,7 @@ object StdNames { val moduleClass : N = "moduleClass" val name: N = "name" val nameDollar: N = "$name" + val namedTypeArguments: N = "namedTypeArguments" val ne: N = "ne" val newFreeTerm: N = "newFreeTerm" val newFreeType: N = "newFreeType" diff --git a/compiler/src/dotty/tools/dotc/typer/Applications.scala b/compiler/src/dotty/tools/dotc/typer/Applications.scala index e2bb30797380..bc4ee4159e2f 100644 --- a/compiler/src/dotty/tools/dotc/typer/Applications.scala +++ b/compiler/src/dotty/tools/dotc/typer/Applications.scala @@ -1057,6 +1057,11 @@ trait Applications extends Compatibility { def typedNamedArgs(args: List[untpd.Tree])(using Context): List[NamedArg] = for (arg @ NamedArg(id, argtpt) <- args) yield { + if !Feature.namedTypeArgsEnabled then + report.error( + i"""Named type arguments are experimental, + |they must be enabled with a `experimental.namedTypeArguments` language import or setting""", + arg.srcPos) val argtpt1 = typedType(argtpt) cpy.NamedArg(arg)(id, argtpt1).withType(argtpt1.tpe) } diff --git a/docs/docs/internals/syntax.md b/docs/docs/internals/syntax.md index 9819bd4ee770..e347fee22dd9 100644 --- a/docs/docs/internals/syntax.md +++ b/docs/docs/internals/syntax.md @@ -161,7 +161,7 @@ SimpleType ::= SimpleLiteral SimpleType1 ::= id Ident(name) | Singleton ‘.’ id Select(t, name) | Singleton ‘.’ ‘type’ SingletonTypeTree(p) - | ‘(’ ArgTypes ‘)’ Tuple(ts) + | ‘(’ Types ‘)’ Tuple(ts) | Refinement RefinedTypeTree(EmptyTree, refinement) | ‘$’ ‘{’ Block ‘}’ | SimpleType1 TypeArgs AppliedTypeTree(t, args) @@ -170,16 +170,13 @@ Singleton ::= SimpleRef | SimpleLiteral | Singleton ‘.’ id -- not yet | Singleton ‘(’ Singletons ‘)’ --- not yet | Singleton ‘[’ ArgTypes ‘]’ +-- not yet | Singleton ‘[’ Types ‘]’ Singletons ::= Singleton { ‘,’ Singleton } -ArgTypes ::= Types FunArgType ::= Type | ‘=>’ Type PrefixOp(=>, t) ParamType ::= [‘=>’] ParamValueType ParamValueType ::= Type [‘*’] PostfixOp(t, "*") -TypeArgs ::= ‘[’ ArgTypes ‘]’ ts -NamedTypeArg ::= id ‘=’ Type NamedArg(id, t) -NamedTypeArgs ::= ‘[’ NamedTypeArg {‘,’ NamedTypeArg} ‘]’ nts +TypeArgs ::= ‘[’ Types ‘]’ ts Refinement ::= ‘{’ [RefineDcl] {semi [RefineDcl]} ‘}’ ds TypeBounds ::= [‘>:’ Type] [‘<:’ Type] TypeBoundsTree(lo, hi) TypeParamBounds ::= TypeBounds {‘:’ Type} ContextBounds(typeBounds, tps) diff --git a/library/src/scalaShadowing/language.scala b/library/src/scalaShadowing/language.scala index 3c2ab45c2b0d..fe16ce0e10ef 100644 --- a/library/src/scalaShadowing/language.scala +++ b/library/src/scalaShadowing/language.scala @@ -213,6 +213,9 @@ object language { /** Experimental support for richer dependent types */ object dependent + + /** Experimental support for named type arguments */ + object namedTypeArguments } /** Where imported, a backwards compatibility mode for Scala2 is enabled */ @@ -242,9 +245,6 @@ object language { */ object adhocExtensions - /** Experimental support for richer dependent types */ - object dependent - /** Source version */ object `3.0-migration` object `3.0` diff --git a/tests/neg/i2771.scala b/tests/neg/i2771.scala index e0477475cd07..b6e15f4dc663 100644 --- a/tests/neg/i2771.scala +++ b/tests/neg/i2771.scala @@ -1,3 +1,4 @@ +import language.experimental.namedTypeArguments trait A { type L[X] } trait B { type L } trait C { type M <: A } diff --git a/tests/neg/i5328.scala b/tests/neg/i5328.scala index 14e2cab5115d..beeea542f262 100644 --- a/tests/neg/i5328.scala +++ b/tests/neg/i5328.scala @@ -1,3 +1,4 @@ +import language.experimental.namedTypeArguments class C[X, Y] { def apply[Z](x: X, y: Y, z: Z) = (x, y, z) } object Test { diff --git a/tests/neg/namedTypeParams.scala b/tests/neg/namedTypeParams.scala index 6284926dc9d8..8ed7c92241ea 100644 --- a/tests/neg/namedTypeParams.scala +++ b/tests/neg/namedTypeParams.scala @@ -1,7 +1,12 @@ class C[T] class D[type T] // error: identifier expected, but `type` found +object Test0: + def f[X, Y](x: X, y: Y): Int = ??? + f[X = Int, Y = Int](1, 2) // error: experimental // error: experimental + object Test { + import language.experimental.namedTypeArguments val x: C[T = Int] = // error: ']' expected, but `=` found // error new C[T = Int] // error: ']' expected, but `=` found // error diff --git a/tests/pos-custom-args/erased/i7868.scala b/tests/pos-custom-args/erased/i7868.scala index 5352b260ec5f..21d5f79ad93b 100644 --- a/tests/pos-custom-args/erased/i7868.scala +++ b/tests/pos-custom-args/erased/i7868.scala @@ -1,3 +1,4 @@ +import language.experimental.namedTypeArguments import scala.compiletime._ final case class Coproduct[+Set, +Value, Index <: Int](value: Value & Set, index: Index) diff --git a/tests/pos/gadt-GadtStlc.scala b/tests/pos/gadt-GadtStlc.scala index 26910347ffed..d3a645486a33 100644 --- a/tests/pos/gadt-GadtStlc.scala +++ b/tests/pos/gadt-GadtStlc.scala @@ -1,3 +1,4 @@ +import language.experimental.namedTypeArguments object GadtStlc { // creates type-level "strings" like M[M[M[W]]] object W diff --git a/tests/pos/gadt-TypeSafeLambda.scala b/tests/pos/gadt-TypeSafeLambda.scala index 04d1df268f55..ae3a53448ded 100644 --- a/tests/pos/gadt-TypeSafeLambda.scala +++ b/tests/pos/gadt-TypeSafeLambda.scala @@ -1,3 +1,4 @@ +import language.experimental.namedTypeArguments object TypeSafeLambda { trait Category[Arr[_, _]] { diff --git a/tests/pos/i3666-gadt.scala b/tests/pos/i3666-gadt.scala index 16614e9e949e..382019660e3d 100644 --- a/tests/pos/i3666-gadt.scala +++ b/tests/pos/i3666-gadt.scala @@ -1,3 +1,4 @@ +import language.experimental.namedTypeArguments object i3666 { sealed trait Exp[T] case class Num(n: Int) extends Exp[Int] diff --git a/tests/pos/i3955.scala b/tests/pos/i3955.scala index 081c44e26c1b..79e67bacb0af 100644 --- a/tests/pos/i3955.scala +++ b/tests/pos/i3955.scala @@ -1,3 +1,4 @@ +import language.experimental.namedTypeArguments object Foo { inline def f[S, T](x: S): T = ??? def g(x: Int) = f[T = Any](x) diff --git a/tests/pos/i5328.scala b/tests/pos/i5328.scala index 9f3fabb2b5f0..f6f2a89dbe81 100644 --- a/tests/pos/i5328.scala +++ b/tests/pos/i5328.scala @@ -1,3 +1,4 @@ +import language.experimental.namedTypeArguments class C[X, Y] { def apply[Z](x: X, y: Y, z: Z) = (x, y, z) } object Test { diff --git a/tests/pos/kindPolySemiGroup.scala b/tests/pos/kindPolySemiGroup.scala index 8ee2db278874..b267ad8f9124 100644 --- a/tests/pos/kindPolySemiGroup.scala +++ b/tests/pos/kindPolySemiGroup.scala @@ -1,4 +1,5 @@ // Adapted from github:mandubian/kind-polymorphic-semigroup.scala +import language.experimental.namedTypeArguments sealed trait HList case class HCons[+HD, +TL](hd: HD, tl: TL) extends HList case object HNil extends HList diff --git a/tests/pos/reference/named-typeargs.scala b/tests/pos/named-typeargs.scala similarity index 81% rename from tests/pos/reference/named-typeargs.scala rename to tests/pos/named-typeargs.scala index a909734939ff..10687b209fc0 100644 --- a/tests/pos/reference/named-typeargs.scala +++ b/tests/pos/named-typeargs.scala @@ -1,3 +1,4 @@ +import language.experimental.namedTypeArguments package namedTypeArgsR { object t1 { diff --git a/tests/pos/namedTypeParams.scala b/tests/pos/namedTypeParams.scala index d4088296bb8a..a8c38972838c 100644 --- a/tests/pos/namedTypeParams.scala +++ b/tests/pos/namedTypeParams.scala @@ -1,3 +1,4 @@ +import language.experimental.namedTypeArguments object Test { def f[X, Y](x: X, y: Y): Int = ??? diff --git a/tests/pos/t1513a.scala b/tests/pos/t1513a.scala index 605e098d31e5..fda45dca46d1 100644 --- a/tests/pos/t1513a.scala +++ b/tests/pos/t1513a.scala @@ -1,3 +1,4 @@ +import language.experimental.namedTypeArguments object Test { // Heterogeneous lists and natural numbers as defined in shapeless. diff --git a/tests/pos/t1513b.scala b/tests/pos/t1513b.scala index 546649383890..2e2e0efbd24a 100644 --- a/tests/pos/t1513b.scala +++ b/tests/pos/t1513b.scala @@ -1,3 +1,4 @@ +import language.experimental.namedTypeArguments object Test { def f[ T1 <: String, diff --git a/tests/pos/typeclass-encoding3.scala b/tests/pos/typeclass-encoding3.scala index 070c52f4af4f..8b1d10487423 100644 --- a/tests/pos/typeclass-encoding3.scala +++ b/tests/pos/typeclass-encoding3.scala @@ -1,3 +1,4 @@ +import language.experimental.namedTypeArguments object Test { /* -------------------------------------------------------------------------- diff --git a/tests/run-staging/staged-streams_1.scala b/tests/run-staging/staged-streams_1.scala index 72f6e3926d5c..d01f703dbea6 100644 --- a/tests/run-staging/staged-streams_1.scala +++ b/tests/run-staging/staged-streams_1.scala @@ -1,6 +1,8 @@ import scala.quoted._ import scala.quoted.staging._ import scala.quoted.util._ +import language.experimental.namedTypeArguments + /** * Port of the strymonas library as described in O. Kiselyov et al., Stream fusion, to completeness (POPL 2017) */ diff --git a/tests/run/creator-applys.scala b/tests/run/creator-applys.scala index 7904aff6ff0a..87b46de4e562 100644 --- a/tests/run/creator-applys.scala +++ b/tests/run/creator-applys.scala @@ -1,3 +1,4 @@ +import language.experimental.namedTypeArguments object Test extends App { class A { def run = "A" diff --git a/tests/run/hmap-covariant.scala b/tests/run/hmap-covariant.scala index 75e7333eb452..c4c426e81a1d 100644 --- a/tests/run/hmap-covariant.scala +++ b/tests/run/hmap-covariant.scala @@ -1,3 +1,4 @@ +import language.experimental.namedTypeArguments trait Tuple case class TCons[+H, +T <: Tuple](h: H, t: T) extends Tuple case object TNil extends Tuple diff --git a/tests/run/hmap.scala b/tests/run/hmap.scala index e189ca132f46..099cd127a116 100644 --- a/tests/run/hmap.scala +++ b/tests/run/hmap.scala @@ -1,3 +1,5 @@ +import language.experimental.namedTypeArguments + trait Tuple case class TCons[H, T <: Tuple](h: H, t: T) extends Tuple case object TNil extends Tuple diff --git a/tests/run/polymorphic-functions.scala b/tests/run/polymorphic-functions.scala index 1667460ddbb8..e723fa34cf79 100644 --- a/tests/run/polymorphic-functions.scala +++ b/tests/run/polymorphic-functions.scala @@ -1,3 +1,4 @@ +import language.experimental.namedTypeArguments object Test extends App { // Types type F0 = [T] => List[T] => Option[T]