diff --git a/docs/docs/reference/contextual-implicit/relationship-implicits.md b/docs/docs/reference/contextual-implicit/relationship-implicits.md index 7c1e6faa7a0b..399dcde7ff9f 100644 --- a/docs/docs/reference/contextual-implicit/relationship-implicits.md +++ b/docs/docs/reference/contextual-implicit/relationship-implicits.md @@ -28,12 +28,23 @@ Implicit instances can be mapped to combinations of implicit objects, classes an class ListOrd[T](implicit ord: Ord[T]) extends Ord[List[T]] { ... } final implicit def ListOrd[T](implicit ord: Ord[T]): ListOrd[T] = new ListOrd[T] ``` - 3. Alias implicits map to implicit methods. If the implicit has neither type parameters nor a given clause, the result of creating an instance is cached in a variable. If in addition the right hand side is pure and cheap to compute, a simple `val` can be used instead. E.g., + 3. Alias implicits map to implicit methods. If the implicit has neither type parameters nor a given clause, the result of creating an instance is cached in a variable. There are two cases that can be optimized: + + - If the right hand side is a simple reference, we can + use a forwarder to that reference without caching it. + - If the right hand side is more complex, but still known to be pure, we can + create a `val` that computes it ahead of time. + + Examples: + ```scala implicit global for ExecutionContext = new ForkJoinContext() implicit config for Config = default.config + + def ctx: Context + implicit for Context = ctx ``` - map to + would map to ```scala private[this] var global$cache: ExecutionContext | Null = null final implicit def global: ExecutionContext = { @@ -42,6 +53,8 @@ Implicit instances can be mapped to combinations of implicit objects, classes an } final implicit val config: Config = default.config + + final implicit def Context_repr = ctx ``` ### Anonymous Implicits diff --git a/docs/docs/reference/contextual-repr/relationship-implicits.md b/docs/docs/reference/contextual-repr/relationship-implicits.md index e756b3d0d6bc..17745b6dbda6 100644 --- a/docs/docs/reference/contextual-repr/relationship-implicits.md +++ b/docs/docs/reference/contextual-repr/relationship-implicits.md @@ -28,12 +28,23 @@ Representative clauses can be mapped to combinations of implicit objects, classe class ListOrd[T](implicit ord: Ord[T]) extends Ord[List[T]] { ... } final implicit def ListOrd[T](implicit ord: Ord[T]): ListOrd[T] = new ListOrd[T] ``` - 3. Alias representatives map to implicit methods. If the representative has neither type parameters nor a given clause, the result of creating an instance is cached in a variable. If in addition the right hand side is pure and cheap to compute, a simple `val` can be used instead. E.g., + 3. Alias representatives map to implicit methods. If the representative has neither type parameters nor a given clause, the result of creating an instance is cached in a variable. There are two cases that can be optimized: + + - If the right hand side is a simple reference, we can simply + use a forwarder to that reference without caching it. + - If the right hand side is more complex, but still known to be pure, we can + create a `val` that computes it ahead of time. + + Examples: + ```scala repr global of ExecutionContext = new ForkJoinContext() repr config of Config = default.config + + def ctx: Context + repr of Context = ctx ``` - map to + would map to ```scala private[this] var global$cache: ExecutionContext | Null = null final implicit def global: ExecutionContext = { @@ -42,6 +53,8 @@ Representative clauses can be mapped to combinations of implicit objects, classe } final implicit val config: Config = default.config + + final implicit def Context_repr = ctx ``` ### Anonymous Representatives diff --git a/docs/docs/reference/dropped-features/weak-conformance.md b/docs/docs/reference/dropped-features/weak-conformance.md index aaa61adf415d..6e7f1fb9f61a 100644 --- a/docs/docs/reference/dropped-features/weak-conformance.md +++ b/docs/docs/reference/dropped-features/weak-conformance.md @@ -20,7 +20,7 @@ A less obvious example is the following one, which was also typed as a val n: Int = 3 val c: Char = 'X' - val n: Double = math.sqrt(3.0) + val d: Double = math.sqrt(3.0) List(n, c, d) // used to be: List[Double], now: List[AnyVal] Here, it is less clear why the type should be widened to