Skip to content

Commit 36cb527

Browse files
committed
Make into a preview feature
1 parent 0ec9468 commit 36cb527

File tree

17 files changed

+132
-140
lines changed

17 files changed

+132
-140
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,7 @@ object Flags {
250250
val (Local @ _, _, _) = newFlags(13, "<local>")
251251

252252
/** A field generated for a primary constructor parameter (no matter if it's a 'val' or not),
253-
* or an accessor of such a field.
253+
* or an accessor of such a field / An `into` modifier on a class
254254
*/
255255
val (ParamAccessorOrInto @ _, ParamAccessor @ _, Into @ _) = newFlags(14, "<paramaccessor>", "into")
256256

compiler/src/dotty/tools/dotc/core/tasty/TreePickler.scala

Lines changed: 43 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -858,64 +858,60 @@ class TreePickler(pickler: TastyPickler, attributes: Attributes) {
858858
if (flags.is(ParamAccessor) && sym.isTerm && !sym.isSetter)
859859
flags = flags &~ ParamAccessor // we only generate a tag for parameter setters
860860
pickleFlags(flags, sym.isTerm)
861-
if flags.is(Into) then
862-
// Temporary measure until we can change TastyFormat to include an INTO tag
863-
pickleAnnotation(sym, mdef, Annotation(defn.SilentIntoAnnot, util.Spans.NoSpan))
864861
val annots = sym.annotations.foreach(pickleAnnotation(sym, mdef, _))
865862
}
866863

867-
def pickleFlags(flags: FlagSet, isTerm: Boolean)(using Context): Unit = {
864+
def pickleFlags(flags: FlagSet, isTerm: Boolean)(using Context): Unit =
868865
import Flags.*
869-
def writeModTag(tag: Int) = {
866+
def writeModTag(tag: Int) =
870867
assert(isModifierTag(tag))
871868
writeByte(tag)
872-
}
869+
873870
if flags.is(Scala2x) then assert(attributes.scala2StandardLibrary)
874-
if (flags.is(Private)) writeModTag(PRIVATE)
875-
if (flags.is(Protected)) writeModTag(PROTECTED)
876-
if (flags.is(Final, butNot = Module)) writeModTag(FINAL)
877-
if (flags.is(Case)) writeModTag(CASE)
878-
if (flags.is(Override)) writeModTag(OVERRIDE)
879-
if (flags.is(Inline)) writeModTag(INLINE)
880-
if (flags.is(InlineProxy)) writeModTag(INLINEPROXY)
881-
if (flags.is(Macro)) writeModTag(MACRO)
882-
if (flags.is(JavaStatic)) writeModTag(STATIC)
883-
if (flags.is(Module)) writeModTag(OBJECT)
884-
if (flags.is(Enum)) writeModTag(ENUM)
885-
if (flags.is(Local)) writeModTag(LOCAL)
886-
if (flags.is(Synthetic)) writeModTag(SYNTHETIC)
887-
if (flags.is(Artifact)) writeModTag(ARTIFACT)
871+
if flags.is(Private) then writeModTag(PRIVATE)
872+
if flags.is(Protected) then writeModTag(PROTECTED)
873+
if flags.is(Final, butNot = Module) then writeModTag(FINAL)
874+
if flags.is(Case) then writeModTag(CASE)
875+
if flags.is(Override) then writeModTag(OVERRIDE)
876+
if flags.is(Inline) then writeModTag(INLINE)
877+
if flags.is(InlineProxy) then writeModTag(INLINEPROXY)
878+
if flags.is(Macro) then writeModTag(MACRO)
879+
if flags.is(JavaStatic) then writeModTag(STATIC)
880+
if flags.is(Module) then writeModTag(OBJECT)
881+
if flags.is(Enum) then writeModTag(ENUM)
882+
if flags.is(Local) then writeModTag(LOCAL)
883+
if flags.is(Synthetic) then writeModTag(SYNTHETIC)
884+
if flags.is(Artifact) then writeModTag(ARTIFACT)
888885
if flags.is(Transparent) then writeModTag(TRANSPARENT)
889886
if flags.is(Infix) then writeModTag(INFIX)
890887
if flags.is(Invisible) then writeModTag(INVISIBLE)
891-
if (flags.is(Erased)) writeModTag(ERASED)
892-
if (flags.is(Exported)) writeModTag(EXPORTED)
893-
if (flags.is(Given)) writeModTag(GIVEN)
894-
if (flags.is(Implicit)) writeModTag(IMPLICIT)
895-
if (flags.is(Tracked)) writeModTag(TRACKED)
896-
if (isTerm) {
897-
if (flags.is(Lazy, butNot = Module)) writeModTag(LAZY)
898-
if (flags.is(AbsOverride)) { writeModTag(ABSTRACT); writeModTag(OVERRIDE) }
899-
if (flags.is(Mutable)) writeModTag(MUTABLE)
900-
if (flags.is(Accessor)) writeModTag(FIELDaccessor)
901-
if (flags.is(CaseAccessor)) writeModTag(CASEaccessor)
902-
if (flags.is(HasDefault)) writeModTag(HASDEFAULT)
888+
if flags.is(Erased) then writeModTag(ERASED)
889+
if flags.is(Exported) then writeModTag(EXPORTED)
890+
if flags.is(Given) then writeModTag(GIVEN)
891+
if flags.is(Implicit) then writeModTag(IMPLICIT)
892+
if flags.is(Tracked) then writeModTag(TRACKED)
893+
if isTerm then
894+
if flags.is(Lazy, butNot = Module) then writeModTag(LAZY)
895+
if flags.is(AbsOverride) then { writeModTag(ABSTRACT); writeModTag(OVERRIDE) }
896+
if flags.is(Mutable) then writeModTag(MUTABLE)
897+
if flags.is(Accessor) then writeModTag(FIELDaccessor)
898+
if flags.is(CaseAccessor) then writeModTag(CASEaccessor)
899+
if flags.is(HasDefault) then writeModTag(HASDEFAULT)
903900
if flags.isAllOf(StableMethod) then writeModTag(STABLE) // other StableRealizable flag occurrences are either implied or can be recomputed
904-
if (flags.is(Extension)) writeModTag(EXTENSION)
905-
if (flags.is(ParamAccessor)) writeModTag(PARAMsetter)
906-
if (flags.is(SuperParamAlias)) writeModTag(PARAMalias)
907-
assert(!(flags.is(Label)))
908-
}
909-
else {
910-
if (flags.is(Sealed)) writeModTag(SEALED)
911-
if (flags.is(Abstract)) writeModTag(ABSTRACT)
912-
if (flags.is(Trait)) writeModTag(TRAIT)
913-
if (flags.is(Covariant)) writeModTag(COVARIANT)
914-
if (flags.is(Contravariant)) writeModTag(CONTRAVARIANT)
915-
if (flags.is(Opaque)) writeModTag(OPAQUE)
916-
if (flags.is(Open)) writeModTag(OPEN)
917-
}
918-
}
901+
if flags.is(Extension) then writeModTag(EXTENSION)
902+
if flags.is(ParamAccessor) then writeModTag(PARAMsetter)
903+
if flags.is(SuperParamAlias) then writeModTag(PARAMalias)
904+
assert(!flags.is(Label))
905+
else
906+
if flags.is(Sealed) then writeModTag(SEALED)
907+
if flags.is(Abstract) then writeModTag(ABSTRACT)
908+
if flags.is(Trait) then writeModTag(TRAIT)
909+
if flags.is(Covariant) then writeModTag(COVARIANT)
910+
if flags.is(Contravariant) then writeModTag(CONTRAVARIANT)
911+
if flags.is(Opaque) then writeModTag(OPAQUE)
912+
if flags.is(Open) then writeModTag(OPEN)
913+
if flags.is(Into) then writeModTag(INTO)
914+
end pickleFlags
919915

920916
private def isUnpicklable(owner: Symbol, ann: Annotation)(using Context) = ann match {
921917
case Annotation.Child(sym) => sym.isInaccessibleChildOf(owner)

compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -670,12 +670,7 @@ class TreeUnpickler(reader: TastyReader,
670670
}
671671
val annotOwner =
672672
if sym.owner.isClass then newLocalDummy(sym.owner) else sym.owner
673-
var annots = annotFns.map(_(annotOwner))
674-
if annots.exists(_.hasSymbol(defn.SilentIntoAnnot)) then
675-
// Temporary measure until we can change TastyFormat to include an INTO tag
676-
sym.setFlag(Into)
677-
annots = annots.filterNot(_.symbol == defn.SilentIntoAnnot)
678-
sym.annotations = annots
673+
sym.annotations = annotFns.map(_(annotOwner))
679674
if sym.isOpaqueAlias then sym.setFlag(Deferred)
680675
val isScala2MacroDefinedInScala3 = flags.is(Macro, butNot = Inline) && flags.is(Erased)
681676
ctx.owner match {
@@ -765,6 +760,7 @@ class TreeUnpickler(reader: TastyReader,
765760
case TRANSPARENT => addFlag(Transparent)
766761
case INFIX => addFlag(Infix)
767762
case TRACKED => addFlag(Tracked)
763+
case INTO => addFlag(Into)
768764
case PRIVATEqualified =>
769765
readByte()
770766
privateWithin = readWithin

compiler/src/dotty/tools/dotc/parsing/Parsers.scala

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3367,12 +3367,14 @@ object Parsers {
33673367
case IDENTIFIER =>
33683368
name match {
33693369
case nme.inline => Mod.Inline()
3370-
case nme.into => Mod.Into()
33713370
case nme.opaque => Mod.Opaque()
33723371
case nme.open => Mod.Open()
33733372
case nme.transparent => Mod.Transparent()
33743373
case nme.infix => Mod.Infix()
33753374
case nme.tracked => Mod.Tracked()
3375+
case nme.into =>
3376+
Feature.checkPreviewFeature("`into`", in.sourcePos())
3377+
Mod.Into()
33763378
case nme.erased if in.erasedEnabled => Mod.Erased()
33773379
case nme.update if Feature.ccEnabled => Mod.Update()
33783380
}

library/src/scala/Conversion.scala

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,9 @@ object Conversion:
4141
* conversions are tried from the type of `t` to `T`. `into[T]` types are erased to `T`
4242
* in all covariant positions of the types of parameter symbols.
4343
*/
44-
@experimental
4544
opaque type into[+T] >: T = T
4645

4746
/** Unwrap an `into` */
4847
extension [T](x: into[T])
49-
@experimental def underlying: T = x
48+
def underlying: T = x
5049
end Conversion
Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,10 @@
11
package scala.annotation.internal
22

3-
import language.experimental.captureChecking
4-
5-
import annotation.experimental
6-
73
/** An internal annotation on (part of) a parameter type that serves as a marker where
84
* the original type was of the form `into[T]`. These annotated types are mapped back
95
* to `into[T]` types when forming a method types from the parameter types. The idea is
106
* that `T @$into` is equivalent to `T`, whereas `into[T]` is only a known supertype of
117
* `T`. Hence, we don't need to use `.underlying` to go from an into type to its
128
* underlying type in the types of local parameters.
139
*/
14-
@experimental
1510
class $into extends annotation.StaticAnnotation

library/src/scala/language.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,7 @@ object language {
292292
* @see [[https://dotty.epfl.ch/docs/reference/experimental/into-modifier]]
293293
*/
294294
@compileTimeOnly("`into` can only be used at compile time in import statements")
295+
@deprecated("The into language import is no longer needed since the feature is now standard", since = "3.9")
295296
object into
296297

297298
/** Experimental support for named tuples.

library/src/scala/runtime/stdLibPatches/language.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ object language:
9999
* @see [[https://dotty.epfl.ch/docs/reference/experimental/into-modifier]]
100100
*/
101101
@compileTimeOnly("`into` can only be used at compile time in import statements")
102+
@deprecated("The into language import is no longer needed since the feature is now standard", since = "3.9")
102103
object into
103104

104105
/** Experimental support for named tuples.

tasty/src/dotty/tools/tasty/TastyFormat.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -512,6 +512,7 @@ object TastyFormat {
512512
final val SPLITCLAUSE = 46
513513
final val TRACKED = 47
514514
final val SUBMATCH = 48 // experimental.subCases
515+
final val INTO = 49
515516

516517
// Tree Cat. 2: tag Nat
517518
final val firstNatTreeTag = SHAREDterm

tests/neg/i23400.scala

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
import scala.language.experimental.into
1+
//> using options -preview
2+
// preview needed for into in 3.8
3+
24
import Conversion.into
35

46
import scala.deriving.Mirror

0 commit comments

Comments
 (0)