**Problem**
Slash syntax is currently implemented via a series of implicit
converters (Conversion), which is not nice, partly because
the behavior is difficult to follow.
**Solution**
This removes all the implicit converters and moves the slashes
into:
1. / methods under Reference for subproject scoping.
2. / methods under ScopeAxis with Reference type constraint
for the initial Zero scoping.
3. Return RefThenConfig structure for intermediate config scoping.
4. / method under `Scoped`, which is base trait for the keys
to implement task scoping e.g. `compile / scalacOptions`.
5. Extension methods for ConfigKey.
6. Extension methods for AttributeKey.
Problem
Currently Scala 3.x - 2.13 sandwich doesn't seem to work for projectMatrix.
This is due to isScala2Scala3Sandwich checking for "3." while projectMatrix
uses scalaBinaryVersion, which is 3.
Solution
This consolidates the implementation of isScala2Scala3Sandwich with the one
in Defaults module, and check for both "3" and "3."
To build the index of all aggregate keys, we were computing the reverse
aggregation of each key, before indexing them.
And so each aggregate key was indexed many times, once for each
aggregated project. It was parallelized to reduce the latency.
In this PR, we compute the reverse aggregation of all the keys at once,
removing all duplication. We cannot parallelize this process anymore
but we don't need to, because it is a lot faster. It reduces the total
CPU time by 12%. The impact for the user depends on its number of cores.
Settings0 used to be a Map[Scope, AttributeMap], and is now a
Map[ScopedKey[x], x].
This is better because we don't need to decompose all ScopedKey[x]
into a Scope and an AttributeKey[x], for recomposing it back later,
which duplicates all ScopedKey[x]. It reduces the number of long-living
ScopedKey[x] by 8%, and the total number of instances by 1.4%.
Also it improves the performance of Settings0, which was responsible of
2.95% of the total CPU time, and is now responsible of 0.41%.