Skip to content

SIP Implementation: Precise type annotation #15765

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 17 commits into from
Closed

Conversation

soronpo
Copy link
Contributor

@soronpo soronpo commented Jul 27, 2022

Summary

This PR adds support for the Precise Type Annotation SIP.

Links

Official Proposal: scala/improvement-proposals#48
Discussion: https://contributors.scala-lang.org/t/pre-sip-exact-type-annotation/5835

Implementation

The implementation includes the following:

  1. Add scala.annotation.precise annotation class to be applied on type parameters. This class is only available under @experimental, but the underlying implementation can still affect performance of the compiler for existing applications.
  2. Add printing of @precise in PlainPrinter.
  3. Add def paramPrecises: List[Boolean] to LambdaType and thus propagate precise parameter indications to PolyType and HKLambdaType. paramPrecises for MethodType always yields Nil. This is the most disruptive change that affects most of the files. An alternative and more fragile approach could have used mutation similarly to variance propagation.
  4. Add apply constructors with paramPrecises argument for the PolyType/HKLambdaType Quotes API under @experimental. When this SIP is officially accepted, at the next minor release the apply methods can be combined with paramPrecises as an optional argument.
  5. Add Precise mode as bit 31. This is used to track whether we need to apply precise typing or not.
  6. Add support for precise default arguments methods by enabling precise mode for them in Namer.
  7. Change desugaring for exported defs and implicit classes to keep precise annotations. This problem was only noticed during incremental compilation and therefore we have related test under sbt-test/precise.
  8. Fix covariance interaction with compiletime.ops bug (that surfaced due to changes made by this SIP).
  9. Add def isPrecise: Boolean to Type. This is overriden is various situations. All are covered by the tests.
  10. Change constraints logic to prevent widening when the type parameter is precise or in precise mode, or when the parameter is upper-bound by a precise type, or when the parameter is from a precise position in an applied type.
  11. Add check for overriding with the same precise annotations.
  12. Add check for poly types to match only with the same precise annotations.
  13. Add check for type/opaque aliasing. Type aliasing must match or be "less precise" (the checks for precise params is done after dealiasing). Opaque type aliasing must match the same precise annotations.
  14. Add check for class extension can be more precise, but not the other way around.
  15. Add precise conversion history stack to TyperState. This is used to store arguments that experienced implicit conversions that should have been precisely typed.
  16. Changed typing logic in ProtoTypes, Application and Typer to accommodate various situations where precise typing needs to be applied. In situations where the compiler knows the method before typing the arguments, then typing only occurs once, and according to the precise types. However, when we have unknown method until arguments are typed (overloading, extension methods, and implicit conversions), then we need to redo the typing with the proper precise typing enforced.
  17. Lock precise variables when summoning implicits to prevent widening to bounds.

Testing

I've been "dogfooding" this myself as the implementation progressed via our library that required a lot of precise argument usages. Consequently, this PR has quite extensive checks that try to cover a wide range of language feature interactions with @precise. Please look at the tests and suggest other interactions I may have missed covering.
Performance tests have yet to be carried out

Related Issues

Resolves scala/bug#10838
Resolves #8231

Acknowledgement

The work on this PR was sponsored by DFiant.

@soronpo soronpo force-pushed the precise branch 3 times, most recently from ac31672 to 8ec5b35 Compare August 7, 2022 13:48
@soronpo soronpo force-pushed the precise branch 2 times, most recently from b7cf6dd to 65850f8 Compare August 18, 2022 02:41
@soronpo soronpo added the needs-minor-release This PR cannot be merged until the next minor release label Aug 18, 2022
@soronpo soronpo force-pushed the precise branch 4 times, most recently from d4016a6 to aada2ca Compare August 22, 2022 10:12
@soronpo soronpo force-pushed the precise branch 7 times, most recently from f18a306 to 3df158a Compare August 30, 2022 23:19
@soronpo soronpo removed the needs-minor-release This PR cannot be merged until the next minor release label Aug 30, 2022
@soronpo soronpo marked this pull request as ready for review August 30, 2022 23:57
@soronpo soronpo requested review from sjrd, mbovel and odersky August 31, 2022 02:39
@SethTisue SethTisue marked this pull request as draft August 31, 2022 19:43
@soronpo
Copy link
Contributor Author

soronpo commented Sep 2, 2022

Added formal proposal scala/improvement-proposals#48

@soronpo soronpo force-pushed the precise branch 2 times, most recently from 6a65432 to 0555be1 Compare September 8, 2022 19:09
add `paramPrecise` to `ParamInfo`
add `paramPrecises` to LambdaType and propagate it through all dependent code that construct new lambdas (poly, method, higher-kinded), and including the user-facing macro quotes API
precise indicator context is added to the proto.
precise mode is activated when precise typing is required, and disabled when there in no-longer an expression context (like Block stats).
for this purpose, additional context was required in `TyperState`.
a stack was used for the conversion history.
Also, a more general fix for scala#12802 was applied.
…f precise implicit conversions, the mechanism changed slightly so it caused the reported to change to error order)
…e information that the opaque may have. E.g.:

`opaque type Foo[@PRECISE T] = T`
…ecise type is used with compiletime-ops (the reason is that default covariant widening kept this bug from surfacing)
@soronpo
Copy link
Contributor Author

soronpo commented Sep 9, 2022

OK, I did a complete rebase and split the PR into change-related commits. I'll update the SIP proposal to reflect the latest changes.
I consider this work now complete and waiting for reviews.

@soronpo
Copy link
Contributor Author

soronpo commented Sep 14, 2023

This SIP is withdrawn. See scala/improvement-proposals#48 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
1 participant