From 99176ac3865cb3f8f5353af107033048c4333b73 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Mon, 16 May 2022 17:42:16 +0200 Subject: [PATCH 1/3] Stabilize 3.2 APIs Stabilize the following APIs: * `scala.deriving.Mirror.fromTuple` * `scala.Tuple.:*" and `scala.Tuple.Append` * `scala.NonEmptyTuple.init` and `scala.Tuple.Init`, * `scala.NonEmptyTuple.last` and `scala.Tuple.Last`, * `scala.quoted.Quotes.reflectModule.AppliedTypeModule.apply` * `scala.quoted.Quotes.reflectModule.SymbolMethods.asQuotes` * `scala.quoted.Quotes.reflectModule.SymbolMethods.termRef` * `scala.quoted.Quotes.reflectModule.SymbolMethods.typeRef` * `scala.quoted.Quotes.reflectModule.TypeReprMethods.substituteTypes` * `scala.quoted.Quotes.reflectModule.TypeReprMethods.typeArgs` * `scala.quoted.Quotes.reflectModule.TypeTreeModule.ref` * `scala.Predef.eq` * `scala.Predef.ne` --- .../tools/dotc/coverage/CoverageTests.scala | 2 +- library/src/scala/Tuple.scala | 8 +-- library/src/scala/deriving/Mirror.scala | 1 - library/src/scala/quoted/Quotes.scala | 7 --- library/src/scala/runtime/Tuples.scala | 5 -- .../scala/runtime/stdLibPatches/Predef.scala | 4 -- project/MiMaFilters.scala | 7 +++ tests/coverage/pos/Inlined.scoverage.check | 54 +++++++++---------- .../stdlibExperimentalDefinitions.scala | 26 ++------- 9 files changed, 39 insertions(+), 75 deletions(-) diff --git a/compiler/test/dotty/tools/dotc/coverage/CoverageTests.scala b/compiler/test/dotty/tools/dotc/coverage/CoverageTests.scala index 9edc3f5b1cf9..1ec3058415d7 100644 --- a/compiler/test/dotty/tools/dotc/coverage/CoverageTests.scala +++ b/compiler/test/dotty/tools/dotc/coverage/CoverageTests.scala @@ -44,7 +44,7 @@ class CoverageTests: def runOnFile(p: Path): Boolean = scalaFile.matches(p) && (Properties.testsFilter.isEmpty || Properties.testsFilter.exists(p.toString.contains)) - + Files.walk(dir).filter(runOnFile).forEach(path => { val fileName = path.getFileName.toString.stripSuffix(".scala") val targetDir = computeCoverageInTmp(path, dir, run) diff --git a/library/src/scala/Tuple.scala b/library/src/scala/Tuple.scala index 52cf5c560ab9..192faa27b71b 100644 --- a/library/src/scala/Tuple.scala +++ b/library/src/scala/Tuple.scala @@ -1,6 +1,6 @@ package scala -import annotation.{experimental, showAsInfix} +import annotation.showAsInfix import compiletime._ import compiletime.ops.int._ @@ -22,7 +22,6 @@ sealed trait Tuple extends Product { runtime.Tuples.toIArray(this) /** Return a copy of `this` tuple with an element appended */ - @experimental inline def :* [This >: this.type <: Tuple, L] (x: L): Append[This, L] = runtime.Tuples.append(x, this).asInstanceOf[Append[This, L]] @@ -84,7 +83,6 @@ sealed trait Tuple extends Product { object Tuple { /** Type of a tuple with an element appended */ - @experimental type Append[X <: Tuple, Y] <: Tuple = X match { case EmptyTuple => Y *: EmptyTuple case x *: xs => x *: Append[xs, Y] @@ -96,7 +94,6 @@ object Tuple { } /** Type of the initial part of the tuple without its last element */ - @experimental type Init[X <: Tuple] <: Tuple = X match { case _ *: EmptyTuple => EmptyTuple case x *: xs => @@ -109,7 +106,6 @@ object Tuple { } /** Type of the last element of a tuple */ - @experimental type Last[X <: Tuple] = X match { case x *: EmptyTuple => x case _ *: xs => Last[xs] @@ -289,12 +285,10 @@ sealed trait NonEmptyTuple extends Tuple { runtime.Tuples.apply(this, 0).asInstanceOf[Head[This]] /** Get the initial part of the tuple without its last element */ - @experimental inline def init[This >: this.type <: NonEmptyTuple]: Init[This] = runtime.Tuples.init(this).asInstanceOf[Init[This]] /** Get the last of this tuple */ - @experimental inline def last[This >: this.type <: NonEmptyTuple]: Last[This] = runtime.Tuples.last(this).asInstanceOf[Last[This]] diff --git a/library/src/scala/deriving/Mirror.scala b/library/src/scala/deriving/Mirror.scala index d091f4ee559e..5de219dfe5c4 100644 --- a/library/src/scala/deriving/Mirror.scala +++ b/library/src/scala/deriving/Mirror.scala @@ -57,7 +57,6 @@ object Mirror { p.fromProduct(a) /** Create a new instance of type `T` with elements taken from tuple `t`. */ - @annotation.experimental def fromTuple(t: p.MirroredElemTypes): T = p.fromProduct(t) } diff --git a/library/src/scala/quoted/Quotes.scala b/library/src/scala/quoted/Quotes.scala index fedf7b5525fe..01530a4e8d15 100644 --- a/library/src/scala/quoted/Quotes.scala +++ b/library/src/scala/quoted/Quotes.scala @@ -1722,7 +1722,6 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching => * * @param sym The type symbol for which we are creating a type tree reference. */ - @experimental def ref(typeSymbol: Symbol): TypeTree } @@ -2644,11 +2643,9 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching => /** Substitute all types that refer in their symbol attribute to * one of the symbols in `from` by the corresponding types in `to`. */ - @experimental def substituteTypes(from: List[Symbol], to: List[TypeRepr]): TypeRepr /** The applied type arguments (empty if there is no such arguments) */ - @experimental def typeArgs: List[TypeRepr] end extension } @@ -2800,7 +2797,6 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching => /** Methods of the module object `val AppliedType` */ trait AppliedTypeModule { this: AppliedType.type => /** Applied the type constructor `T` to a list of type arguments `T_1,..,T_n` to create `T[T_1,..,T_n]` */ - @experimental def apply(tycon: TypeRepr, args: List[TypeRepr]): AppliedType def unapply(x: AppliedType): (TypeRepr, List[TypeRepr]) } @@ -3947,7 +3943,6 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching => * '{ val x = ???; x }.asTerm * ``` */ - @experimental def asQuotes: Nested /** Type reference to the symbol usable in the scope of its owner. @@ -3957,11 +3952,9 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching => * * @pre symbol.isType returns true */ - @experimental def typeRef: TypeRef /** Term reference to the symbol usable in the scope of its owner. */ - @experimental def termRef: TermRef end extension } diff --git a/library/src/scala/runtime/Tuples.scala b/library/src/scala/runtime/Tuples.scala index bfb863bcc0f0..c16d8c2a201a 100644 --- a/library/src/scala/runtime/Tuples.scala +++ b/library/src/scala/runtime/Tuples.scala @@ -1,7 +1,5 @@ package scala.runtime -import scala.annotation.experimental - object Tuples { inline val MaxSpecialized = 22 @@ -427,7 +425,6 @@ object Tuples { } } - @experimental def append(x: Any, self: Tuple): Tuple = (self: Any) match { case xxl: TupleXXL => xxlAppend(x, xxl).asInstanceOf[Tuple] case _ => specialCaseAppend(x, self) @@ -500,13 +497,11 @@ object Tuples { } } - @experimental def init(self: NonEmptyTuple): Tuple = (self: Any) match { case xxl: TupleXXL => xxlInit(xxl) case _ => specialCaseInit(self) } - @experimental def last(self: NonEmptyTuple): Any = (self: Any) match { case self: Product => self.productElement(self.productArity - 1) } diff --git a/library/src/scala/runtime/stdLibPatches/Predef.scala b/library/src/scala/runtime/stdLibPatches/Predef.scala index 080a3957f79f..27d00c0fcce5 100644 --- a/library/src/scala/runtime/stdLibPatches/Predef.scala +++ b/library/src/scala/runtime/stdLibPatches/Predef.scala @@ -1,7 +1,5 @@ package scala.runtime.stdLibPatches -import scala.annotation.experimental - object Predef: import compiletime.summonFrom @@ -54,13 +52,11 @@ object Predef: /** Enables an expression of type `T|Null`, where `T` is a subtype of `AnyRef`, to be checked for `null` * using `eq` rather than only `==`. This is needed because `Null` no longer has * `eq` or `ne` methods, only `==` and `!=` inherited from `Any`. */ - @experimental inline def eq(inline y: AnyRef | Null): Boolean = x.asInstanceOf[AnyRef] eq y.asInstanceOf[AnyRef] /** Enables an expression of type `T|Null`, where `T` is a subtype of `AnyRef`, to be checked for `null` * using `ne` rather than only `!=`. This is needed because `Null` no longer has * `eq` or `ne` methods, only `==` and `!=` inherited from `Any`. */ - @experimental inline def ne(inline y: AnyRef | Null): Boolean = !(x eq y) diff --git a/project/MiMaFilters.scala b/project/MiMaFilters.scala index f5b83f0a3d4e..e8f82f61de9c 100644 --- a/project/MiMaFilters.scala +++ b/project/MiMaFilters.scala @@ -10,5 +10,12 @@ object MiMaFilters { ProblemFilters.exclude[DirectMissingMethodProblem]("scala.quoted.runtime.QuoteUnpickler.unpickleTypeV2"), ProblemFilters.exclude[MissingClassProblem]("scala.annotation.since"), + + // APIs will be added in 3.2.0 + ProblemFilters.exclude[ReversedMissingMethodProblem]("scala.quoted.Quotes#reflectModule#AppliedTypeModule.apply"), + ProblemFilters.exclude[ReversedMissingMethodProblem]("scala.quoted.Quotes#reflectModule#SymbolMethods.asQuotes"), + ProblemFilters.exclude[ReversedMissingMethodProblem]("scala.quoted.Quotes#reflectModule#SymbolMethods.typeRef"), + ProblemFilters.exclude[ReversedMissingMethodProblem]("scala.quoted.Quotes#reflectModule#SymbolMethods.termRef"), + ProblemFilters.exclude[ReversedMissingMethodProblem]("scala.quoted.Quotes#reflectModule#TypeTreeModule.ref"), ) } diff --git a/tests/coverage/pos/Inlined.scoverage.check b/tests/coverage/pos/Inlined.scoverage.check index 7d0e717a7aac..f3cb3b5d9026 100644 --- a/tests/coverage/pos/Inlined.scoverage.check +++ b/tests/coverage/pos/Inlined.scoverage.check @@ -42,9 +42,9 @@ Inlined$package$ Object covtest.Inlined$package$ testInlined -378 -405 -11 +340 +367 +9 Scala3RunTime Select false @@ -59,9 +59,9 @@ Inlined$package$ Object covtest.Inlined$package$ testInlined -378 -420 -11 +340 +382 +9 assertFailed Apply false @@ -76,9 +76,9 @@ Inlined$package$ Object covtest.Inlined$package$ testInlined -378 -420 -11 +340 +382 +9 Block true @@ -127,9 +127,9 @@ Inlined$package$ Object covtest.Inlined$package$ testInlined -378 -405 -11 +340 +367 +9 Scala3RunTime Select false @@ -144,9 +144,9 @@ Inlined$package$ Object covtest.Inlined$package$ testInlined -378 -420 -11 +340 +382 +9 assertFailed Apply false @@ -161,9 +161,9 @@ Inlined$package$ Object covtest.Inlined$package$ testInlined -378 -420 -11 +340 +382 +9 Block true @@ -212,9 +212,9 @@ Inlined$package$ Object covtest.Inlined$package$ testInlined -378 -405 -11 +340 +367 +9 Scala3RunTime Select false @@ -229,9 +229,9 @@ Inlined$package$ Object covtest.Inlined$package$ testInlined -378 -420 -11 +340 +382 +9 assertFailed Apply false @@ -246,9 +246,9 @@ Inlined$package$ Object covtest.Inlined$package$ testInlined -378 -420 -11 +340 +382 +9 Block true diff --git a/tests/run-custom-args/tasty-inspector/stdlibExperimentalDefinitions.scala b/tests/run-custom-args/tasty-inspector/stdlibExperimentalDefinitions.scala index 0d86b5c05caa..6ceb8e7870ad 100644 --- a/tests/run-custom-args/tasty-inspector/stdlibExperimentalDefinitions.scala +++ b/tests/run-custom-args/tasty-inspector/stdlibExperimentalDefinitions.scala @@ -50,37 +50,17 @@ val experimentalDefinitionInLibrary = Set( "scala.compiletime.ops.string$.Substring", //// New APIs: Mirror - // Can be stabilized in 3.2.0 or later. - "scala.deriving.Mirror$.fromTuple", // Probably for 3.2.0 + // Can be stabilized in 3.3.0 or later. "scala.deriving.Mirror$.fromProductTyped", // This API is a bit convoluted. We may need some more feedback before we can stabilize it. - //// New APIs: Tuples - // Should be stabilized in 3.2.0. - "scala.Tuple.:*", "scala.Tuple$.Append", "scala.runtime.Tuples$.append", - "scala.NonEmptyTuple.init", "scala.Tuple$.Init", "scala.runtime.Tuples$.init", - "scala.Tuple$.Last", "scala.NonEmptyTuple.last", "scala.runtime.Tuples$.last", - - //// New APIs: Quotes - // Should be stabilized in 3.2.0. - "scala.quoted.Quotes.reflectModule.AppliedTypeModule.apply", - "scala.quoted.Quotes.reflectModule.SymbolMethods.asQuotes", - "scala.quoted.Quotes.reflectModule.SymbolMethods.termRef", - "scala.quoted.Quotes.reflectModule.SymbolMethods.typeRef", - "scala.quoted.Quotes.reflectModule.TypeReprMethods.substituteTypes", - "scala.quoted.Quotes.reflectModule.TypeReprMethods.typeArgs", - "scala.quoted.Quotes.reflectModule.TypeTreeModule.ref", - // Can be stabilized in 3.2.0 (unsure) or later + //// New APIs: Quotes + // Can be stabilized in 3.3.0 (unsure) or later "scala.quoted.Quotes.reflectModule.CompilationInfoModule.XmacroSettings", // Cant be stabilized yet. // Need newClass variant that can add constructor parameters. // Need experimental annotation macros to check that design works. "scala.quoted.Quotes.reflectModule.ClassDefModule.apply", "scala.quoted.Quotes.reflectModule.SymbolModule.newClass", - - //// New extension methods: Explicit Nulls - // Should be stabilized in 3.2.0. - "scala.Predef$.eq", - "scala.Predef$.ne", ) From f6b3b53eca1a8ac6afc4b2ba161ef0efabbe9245 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Tue, 17 May 2022 15:32:25 +0200 Subject: [PATCH 2/3] Make coverage test resilient to changes in stdlib --- tests/coverage/pos/Inlined.scala | 5 +- tests/coverage/pos/Inlined.scoverage.check | 156 +++++++++++++++------ 2 files changed, 116 insertions(+), 45 deletions(-) diff --git a/tests/coverage/pos/Inlined.scala b/tests/coverage/pos/Inlined.scala index ebe0503716a7..5e51f037220f 100644 --- a/tests/coverage/pos/Inlined.scala +++ b/tests/coverage/pos/Inlined.scala @@ -3,6 +3,9 @@ package covtest // Checks that we use the new positions of the inlined code properly def testInlined(): Unit = val l = 1 - assert(l == 1) // scala.Predef.assert is inline in dotty + assert(l == 1) assert(l == List(l).length) assert(List(l).length == 1) + +transparent inline def assert(inline assertion: Boolean): Unit = + if !assertion then scala.runtime.Scala3RunTime.assertFailed() diff --git a/tests/coverage/pos/Inlined.scoverage.check b/tests/coverage/pos/Inlined.scoverage.check index f3cb3b5d9026..7c0cb17efece 100644 --- a/tests/coverage/pos/Inlined.scoverage.check +++ b/tests/coverage/pos/Inlined.scoverage.check @@ -36,15 +36,15 @@ false l == 1 1 -../../../library/src/scala/runtime/stdLibPatches/Predef.scala +Inlined.scala covtest Inlined$package$ Object covtest.Inlined$package$ testInlined -340 -367 -9 +288 +315 +10 Scala3RunTime Select false @@ -53,15 +53,15 @@ false scala.runtime.Scala3RunTime 2 -../../../library/src/scala/runtime/stdLibPatches/Predef.scala +Inlined.scala covtest Inlined$package$ Object covtest.Inlined$package$ testInlined -340 -382 -9 +288 +330 +10 assertFailed Apply false @@ -70,15 +70,15 @@ false scala.runtime.Scala3RunTime.assertFailed() 3 -../../../library/src/scala/runtime/stdLibPatches/Predef.scala +Inlined.scala covtest Inlined$package$ Object covtest.Inlined$package$ testInlined -340 -382 -9 +288 +330 +10 Block true @@ -93,8 +93,8 @@ Inlined$package$ Object covtest.Inlined$package$ testInlined -197 -204 +155 +162 6 apply Apply @@ -110,8 +110,8 @@ Inlined$package$ Object covtest.Inlined$package$ testInlined -192 -211 +150 +169 6 == Apply @@ -121,15 +121,15 @@ false l == List(l).length 6 -../../../library/src/scala/runtime/stdLibPatches/Predef.scala +Inlined.scala covtest Inlined$package$ Object covtest.Inlined$package$ testInlined -340 -367 -9 +288 +315 +10 Scala3RunTime Select false @@ -138,15 +138,15 @@ false scala.runtime.Scala3RunTime 7 -../../../library/src/scala/runtime/stdLibPatches/Predef.scala +Inlined.scala covtest Inlined$package$ Object covtest.Inlined$package$ testInlined -340 -382 -9 +288 +330 +10 assertFailed Apply false @@ -155,15 +155,15 @@ false scala.runtime.Scala3RunTime.assertFailed() 8 -../../../library/src/scala/runtime/stdLibPatches/Predef.scala +Inlined.scala covtest Inlined$package$ Object covtest.Inlined$package$ testInlined -340 -382 -9 +288 +330 +10 Block true @@ -178,8 +178,8 @@ Inlined$package$ Object covtest.Inlined$package$ testInlined -222 -229 +180 +187 7 apply Apply @@ -195,8 +195,8 @@ Inlined$package$ Object covtest.Inlined$package$ testInlined -222 -241 +180 +199 7 == Apply @@ -206,15 +206,15 @@ false List(l).length == 1 11 -../../../library/src/scala/runtime/stdLibPatches/Predef.scala +Inlined.scala covtest Inlined$package$ Object covtest.Inlined$package$ testInlined -340 -367 -9 +288 +315 +10 Scala3RunTime Select false @@ -223,15 +223,15 @@ false scala.runtime.Scala3RunTime 12 -../../../library/src/scala/runtime/stdLibPatches/Predef.scala +Inlined.scala covtest Inlined$package$ Object covtest.Inlined$package$ testInlined -340 -382 -9 +288 +330 +10 assertFailed Apply false @@ -240,15 +240,15 @@ false scala.runtime.Scala3RunTime.assertFailed() 13 -../../../library/src/scala/runtime/stdLibPatches/Predef.scala +Inlined.scala covtest Inlined$package$ Object covtest.Inlined$package$ testInlined -340 -382 -9 +288 +330 +10 Block true @@ -273,3 +273,71 @@ false false def testInlined +15 +Inlined.scala +covtest +Inlined$package$ +Object +covtest.Inlined$package$ +assert +288 +315 +10 +Scala3RunTime +Select +false +0 +false +scala.runtime.Scala3RunTime + +16 +Inlined.scala +covtest +Inlined$package$ +Object +covtest.Inlined$package$ +assert +288 +330 +10 +assertFailed +Apply +false +0 +false +scala.runtime.Scala3RunTime.assertFailed() + +17 +Inlined.scala +covtest +Inlined$package$ +Object +covtest.Inlined$package$ +assert +288 +330 +10 + +Block +true +0 +false +scala.runtime.Scala3RunTime.assertFailed() + +18 +Inlined.scala +covtest +Inlined$package$ +Object +covtest.Inlined$package$ +assert +202 +231 +9 +assert +DefDef +false +0 +false +transparent inline def assert + From 4c80d356ffb0d585019921cc67d36e60b6543243 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Thu, 19 May 2022 18:15:02 +0200 Subject: [PATCH 3/3] Update library/src/scala/quoted/Quotes.scala Co-authored-by: Guillaume Martres --- library/src/scala/quoted/Quotes.scala | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/library/src/scala/quoted/Quotes.scala b/library/src/scala/quoted/Quotes.scala index 01530a4e8d15..23d5404718aa 100644 --- a/library/src/scala/quoted/Quotes.scala +++ b/library/src/scala/quoted/Quotes.scala @@ -3954,7 +3954,10 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching => */ def typeRef: TypeRef - /** Term reference to the symbol usable in the scope of its owner. */ + /** Term reference to the symbol usable in the scope of its owner. + * + * @pre symbol.isType returns false + */ def termRef: TermRef end extension }