Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Special handling of experimental.captureChecking import #17427

Merged
merged 6 commits into from
May 30, 2023

Conversation

odersky
Copy link
Contributor

@odersky odersky commented May 6, 2023

The question is, how do we introduce capture checking safely. There are
two conflicting requirements:

  • Capture checking should not leak into standard Scala. It should be
    meaningful only in code that has capture checking explicitly enabled.
  • We need to be able to build up libraries that express capture information
    and that can be consumed from other code. This needs to start with
    the standard library itself.

So far, everything related to capture checking was marked experimental. This means
all code that refers to a capture checking abstraction in any way whatsoever needs
to be declared experimental. That clearly does not work for the new use cases.

But fortunately, capture checking has some properties that enable a different scheme.
Specifically, a file compiled under capture checking looks like a completely normal
component (both Tasty and binary) to any other file that uses it and that is not compiled
with captureChecking. Only when the consumer is also compiled with capture checking,
the capturing types of the original file will be revealed. The same holds for binaries.
Capture checking has no effect at all on the binaries that get generated and all types
and annotations needed for capture checking are erased.

This allows the following more flexible scheme:

  • We can turn capture checking on with a setting or language import in any source file.
    The sources do not have to be @experimental.
  • If capture checking is turned on, a number of annotations and other symbols that
    are needed for capture checking and are normally experimental are also made available.

The important property is that capture checking in one component cannot poison other normal components. Like
@experimental itself, the whole scheme is transitive.

With the new scheme we do not need a special exemption for the dotty package anymore, so the code
implementing the exception is dropped.

Copy link
Contributor

@Linyxus Linyxus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Otherwise LGTM!

.updated(NonEmptyTupleClass, ProductClass)
.updated(PairClass, ObjectClass)
@tu lazy val specialErasure: collection.Map[Symbol, ClassSymbol] =
val m = mutable.Map[Symbol, ClassSymbol]()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The map changes from an immutable one to a mutable one. Shall we freeze it after initializing it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It can't be changed from outside, since it is declared as a collection.Map. So in that sense it is frozen.

@@ -363,8 +363,6 @@ object SymUtils:
self.hasAnnotation(defn.ExperimentalAnnot)
|| isDefaultArgumentOfExperimentalMethod
|| (!self.is(Package) && self.owner.isInExperimentalScope)
|| self.topLevelClass.ownersIterator.exists(p =>
p.is(Package) && p.owner.isRoot && p.name == tpnme.dotty)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shall we drop this special case in the main compiler as well?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, I overlooked it was in the wrong codebase!

@odersky odersky force-pushed the cc-experimental-handling branch from 192d02c to a918722 Compare May 17, 2023 07:34
@nicolasstucki nicolasstucki self-assigned this May 17, 2023
odersky added 6 commits May 26, 2023 15:18
The Pure marker trait is now a class in the scala package that
gets erased to Object.
The question is, how do we introduce capture checking safely. There are
two conflicting requirements:

 - Capture checking should not leak into standard Scala. It should be
   meaningful only in code that has capture checking explicitly enabled.
 - We need to be able to build up libraries that express capture information
   and that can be consumed from other code. This needs to start with
   the standard library itself.

So far, everything related to capture checking was marked experimental. This means
all code that refers to a capture checking abstraction in any way whatsoever needs
to be declared experimental. That clearly does not work for the new use cases.

But fortunately, capture checking has some properties that enable a different scheme.
Specifically, a file compiled under capture checking looks like a completely normal
component (both Tasty and binary) to any other file that uses it and that is not compiled
with captureChecking. Only when the consumer is also compiled with capture checking,
the capturing types of the original file will be revealed. The same holds for binaries.
Capture checking has no effect at all on the binaries that get generated and all types
and annotations needed for capture checking are erased.

This allows the following more flexible scheme:

 - We can turn capture checking on with a setting or language import in any source file.
   The sources do not have to be @experimental.
 - If capture checking is turned on, a number of annotations and other symbols that
   are normally experimental are also made available.

The important property is that capture checking in one component cannot poison other normal components. Like
@experimental itself, the whole scheme is transitive.

With the new scheme we do not need a special exemption for the dotty package anymore, so that part
is dropped.
Previously: test was exempted because it was in dotty package

Now: test is exempted since it language imports captureChecking
@odersky odersky force-pushed the cc-experimental-handling branch from 0662749 to e6d1242 Compare May 26, 2023 14:56
@odersky odersky merged commit 060676e into scala:main May 30, 2023
@odersky odersky deleted the cc-experimental-handling branch May 30, 2023 09:36
@Kordyjan Kordyjan added this to the 3.4.0 milestone Aug 1, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants