Skip to content

Commit cf0a97e

Browse files
committed
Special case experimental in Predef additions
1 parent 4a103c7 commit cf0a97e

File tree

5 files changed

+31
-2
lines changed

5 files changed

+31
-2
lines changed

compiler/src/dotty/tools/dotc/core/Annotations.scala

+13
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,9 @@ object Annotations {
276276
}
277277
}
278278

279+
/** This annotation is added by the compiler to all top-level definitions that
280+
* are compiled in experimental mode.
281+
*/
279282
object ExperimentalAnnotation {
280283

281284
/** Create an instance of `@experimental(<msg>)` */
@@ -301,4 +304,14 @@ object Annotations {
301304
}
302305
}
303306

307+
/** This annotation is added by the compiler to all experimental definitions
308+
* in stdLibPatches, where adding an explicit @experimental would lead to a cycle.
309+
*/
310+
class LazyExperimentalAnnotation(span: Span) extends LazyAnnotation:
311+
protected var mySym =
312+
(ctx: Context) ?=> defn.ExperimentalAnnot
313+
314+
protected var myTree =
315+
(ctx: Context) ?=> New(defn.ExperimentalAnnot.typeRef, Literal(Constant("")) :: Nil).withSpan(span)
316+
end LazyExperimentalAnnotation
304317
}

compiler/src/dotty/tools/dotc/core/Definitions.scala

+10
Original file line numberDiff line numberDiff line change
@@ -1461,6 +1461,10 @@ class Definitions {
14611461
makeNonClassSymbol(patch)
14621462
end match
14631463
sym.annotations = patch.annotations
1464+
if experimentalInPredef.contains(patch.name)
1465+
&& patchCls.name == tpnme.Predef.moduleClassName
1466+
then
1467+
sym.addAnnotation(Annotations.LazyExperimentalAnnotation(sym.span))
14641468
scope.enter(sym)
14651469
if patch.isClass then
14661470
patch2(scope.lookup(patch.name).asClass, patch)
@@ -1477,6 +1481,12 @@ class Definitions {
14771481
patchWith(LanguageModuleClassPatch)
14781482
end patchStdLibClass
14791483

1484+
/** Definitions that are assumed to be experimental in Predef.
1485+
* We can't mark them with @experimental since that causes a cycle.
1486+
* So we add the annotation instead when we patch Predef.
1487+
*/
1488+
private val experimentalInPredef: Set[Name] = Set("is".toTypeName)
1489+
14801490
// ----- Symbol sets ---------------------------------------------------
14811491

14821492
@tu lazy val topClasses: Set[Symbol] = Set(AnyClass, MatchableClass, ObjectClass, AnyValClass)

library/src/scala/runtime/stdLibPatches/Predef.scala

+2-1
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,9 @@ object Predef:
7272
* TC { type Self = A }
7373
*
7474
* which is what is needed for a context bound `[A: TC]`.
75+
*
76+
* @experimental added by compiler in Definitions.patchStdLibClass
7577
*/
76-
@experimental
7778
infix type is[A <: AnyKind, B <: Any{type Self <: AnyKind}] = B { type Self = A }
7879

7980
end Predef

tests/neg/experimentalInPredef.scala

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
//> using options -Yno-experimental
2+
class C:
3+
type Self
4+
5+
def Test[T](witness: T is C) = () // error
6+

tests/run-tasty-inspector/stdlibExperimentalDefinitions.scala

-1
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,6 @@ val experimentalDefinitionInLibrary = Set(
8181
"scala.Precise",
8282
"scala.annotation.internal.WitnessNames",
8383
"scala.compiletime.package$package$.deferred",
84-
"scala.runtime.stdLibPatches.Predef$.is",
8584
)
8685

8786

0 commit comments

Comments
 (0)