Skip to content

Allow experimental language imports in experimental scopes #13396

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

Closed
wants to merge 5 commits into from

Conversation

odersky
Copy link
Contributor

@odersky odersky commented Aug 26, 2021

An experimental language import is permitted if the enclosing
scope is an experimental scope, or if all non-synthetic statements in that
scope are @experimental definitions.

Fixes #13392
Alternative to #13394

An experimental language import is permitted of the enclosing
scope is an experimental scopes, or if all statements in that
scope are @experimental definitions.
}

class Test7 {
import scala.language.experimental
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Deleted since we now check experimental imports after typer, and Test7 produces errors at Typer

@nicolasstucki
Copy link
Contributor

nicolasstucki commented Aug 26, 2021

Alternative to #13394

I would not say that it is an alternative, it is an orthogonal improvement. This makes imports experimental scope aware while #13394 allows the import of erasedDefinitions in any scope. This PR will help use experimental imports locally in experimental definitions. On the other hand #13394 allows the use of erased in top-level experimental definitions. Note that only #13394 will unblock the definition of CanThrow.

This PR and #13394 complement each other.

@@ -0,0 +1,7 @@
import language.experimental.erasedDefinitions // error
Copy link
Contributor

Choose a reason for hiding this comment

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

Copy link
Contributor Author

Choose a reason for hiding this comment

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

See pos-curstomArgs/experimental.erased for the same example that compiles. It's not CanThrow that triggers the error but other.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I tested pos-curstomArgs/experimental.erased manually with -Yno-experimental. I assume that will be tested anyway since we start with a stable compiler. Or do we need a separate pos test that asserts -Yno-experimental`?

Copy link
Contributor

@nicolasstucki nicolasstucki Aug 26, 2021

Choose a reason for hiding this comment

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

That is the same behavior as in master.

import language.experimental.erasedDefinitions
import annotation.experimental

@experimental
erased class CanThrow[-E <: Exception]

Compiles with snapshot build without error but fails when we add -Yno-experimental.

If we cannot compile it with -Yno-experimental we will not be able to re-bootstrap on a stable compiler.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I tested it manually with -Yno-experimental and verified that it compiles

Copy link
Contributor

Choose a reason for hiding this comment

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

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ah I see what goes on. The generated package object is not experimental.

Copy link
Contributor

Choose a reason for hiding this comment

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

The error message of is also unhelpful. If a user does this change they will have no idea why it started failing.

import language.experimental.erasedDefinitions // error
import annotation.experimental

@experimental
erased class CanThrow[-E <: Exception]
+ object Foo

The scope of CanThrow is still experimental. But now it it says Experimental features may only be used with a nightly or snapshot version of the compiler which has not changed.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We now disregard synthetic definitions in the check. That also takes care of compiler-generated companion objects.

Copy link
Contributor

Choose a reason for hiding this comment

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

@odersky
Copy link
Contributor Author

odersky commented Aug 26, 2021

I would not say that it is an alternative, it is an orthogonal improvement. This makes imports experimental scope aware while #13394 allows the import of erasedDefinitions in any scope.

Yes, and isn't that a problem by itself? EDIT: No, since we test manually afterwards at use sites. But are we sure we found all
use sites?

This PR will help use experimental imports locally in experimental definitions. On the other hand #13394 allows the use of erased in top-level experimental definitions. Note that only #13394 will unblock the definition of CanThrow.

Not true. I believe I have been quite precise in my spec and implementation and it does allow CanThrow as it is.

@odersky
Copy link
Contributor Author

odersky commented Aug 26, 2021

The main difference where #13394 allows more:

  • You can have toplevel @experimental erased definitions in the same source file as other definitions that are neither erased nor experimental.

Where #13396 allows more:

  • You can have other experimental imports in experimental scopes or in source files where all toplevel definitions are @experimental. erased is not a special case.

@nicolasstucki
Copy link
Contributor

nicolasstucki commented Aug 26, 2021

It seems this design does not allow us to add experimental erased methods.

Here we assume that Foo and Foo.foo already exists and has some stable methods. How would we add erased def bar?

import language.experimental.erasedDefinitions // error
import annotation.experimental

object Foo:
  def foo = 1
  @experimental
  erased def bar = 2

@odersky
Copy link
Contributor Author

odersky commented Aug 26, 2021

It seems this design does not allow us to add experimental erased methods.

That's correct. If we want that we need #13394. With #13396, any class containing an erased method would have to be experimental as well.

@nicolasstucki
Copy link
Contributor

The extra scope rules should be added to experimental-defs.md.

@nicolasstucki
Copy link
Contributor

It seems this design does not allow us to add experimental erased methods.

That's correct. If we want that we need #13394. With #13396, any class containing an erased method would have to be experimental as well.

We will probably need to define new erased definitions in the future before we stabilize erased.

@odersky
Copy link
Contributor Author

odersky commented Aug 26, 2021

We will probably need to define new erased definitions in the future before we stabilize erased.

Yes, maybe. I still dislike #13394 since it mixes two things that should stay separate. But maybe we need it. On the other hand, maybe it's better to spend our energy on stabilizing erased?

# Conflicts:
#	compiler/src/dotty/tools/dotc/typer/Checking.scala
@nicolasstucki
Copy link
Contributor

#13417 made me realize that rule (2) from #13392 is completely untested. If we remove that rule all tests still pass.

@nicolasstucki
Copy link
Contributor

Also noticed that rule (1) is not properly tested. I added the tests in #13417.

@nicolasstucki
Copy link
Contributor

Actually all tests in this PR pass on master.

@nicolasstucki
Copy link
Contributor

Replaced with #13417

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.

Cannot use experimental language features in @experimental code
2 participants