The SIP implementation is now complete before review and before formal proposal.
It was very useful to experiment and understand better what the proposal should be.
lampepfl:main
β soronpo:precise
opened 04:13AM - 27 Jul 22 UTC
# Summary
This PR adds support for the Precise Type Annotation SIP.
# Linksβ¦
Official Proposal: TBD
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. Change desugaring for `precise` default arguments methods so they are annotated with the precise return type.
6. Change desugaring for exported defs and classes to keep precise annotations. This problem was only noticed during incremental compilation and therefore we have related test under `sbt-test/precise`.
7. Fix covariance interaction with `compiletime.ops` bug (that surfaced due to changes made by this SIP).
8. Add `def isPrecise: Boolean` to `Type`. This is overriden is various situations. All are covered by the tests.
9. Add `Precise` mode as bit 31. This is used to track whether we need to apply precise typing or not.
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 aliasing to accept only with 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.
# 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 https://github.com/scala/bug/issues/10838
Resolves https://github.com/lampepfl/dotty/issues/8231
# Acknowledgement
The work on this PR was sponsored by [DFiant](www.dfiant.works).
soronpo
September 2, 2022, 9:24pm
22
3 Likes
soronpo
September 14, 2023, 12:17pm
23
Update
We discussed this during the SIP meeting on Sep. 11th 2023, and indeed it was recognized that there is no way around precise mode and double typing in some cases. It was also mentioned that there is no apparent enough community/industry request for this to merit the possible complication and itβs not necessarily the right direction for Scala.
In light of all the above, Iβm withdrawing the SIP, at least until there is enough examples from the community of a need for this SIP.
2 Likes