Skip to content

doc(inline): fix listing in override and fixes in transparent section #8848

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

Merged
merged 2 commits into from
May 4, 2020
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 37 additions & 35 deletions docs/docs/reference/metaprogramming/inline.md
Original file line number Diff line number Diff line change
Expand Up @@ -147,40 +147,40 @@ funkyAssertEquals(computeActual(), computeExpected(), computeDelta())
Inline methods can override other non-inline methods. The rules are as follows:

1. If an inline method `f` implements or overrides another, non-inline method, the inline method can also be invoked at runtime. For instance, consider the scenario:
```scala
abstract class A {
def f(): Int
def g(): Int = f()
}
class B extends A {
inline def f() = 22
override inline def g() = f() + 11
}
val b = B()
val a: A = b
// inlined invocatons
assert(b.f() == 22)
assert(b.g() == 33)
// dynamic invocations
assert(a.f() == 22)
assert(a.g() == 33)
```
The inlined invocations and the dynamically dispatched invocations give the same results.
```scala
abstract class A {
def f(): Int
def g(): Int = f()
}
class B extends A {
inline def f() = 22
override inline def g() = f() + 11
}
val b = B()
val a: A = b
// inlined invocatons
assert(b.f() == 22)
assert(b.g() == 33)
// dynamic invocations
assert(a.f() == 22)
assert(a.g() == 33)
```
The inlined invocations and the dynamically dispatched invocations give the same results.

2. Inline methods are effectively final.

3. Inline methods can also be abstract. An abstract inline method can be implemented only by other inline methods. It cannot be invoked directly:
```scala
abstract class A {
inline def f(): Int
}
object B extends A {
inline def f(): Int = 22
}
B.f() // OK
val a: A = B
a.f() // error: cannot inline f() in A.
```
```scala
abstract class A {
inline def f(): Int
}
object B extends A {
inline def f(): Int = 22
}
B.f() // OK
val a: A = B
a.f() // error: cannot inline f() in A.
```

### Relationship to @inline

Expand Down Expand Up @@ -260,18 +260,20 @@ class B extends A {
}

transparent inline def choose(b: Boolean): A =
if b then A() else B
if b then new A() else new B()

val obj1 = choose(true) // static type is A
val obj2 = choose(false) // static type is B

// obj1.m() // compile-time error: `m` is not defined on `A`
obj2.m() // OK
```
Here, the inline method `choose` returns an object of either of the two types `A` and `B`. If `choose` had been declared with a normal return type `: A`, the result
of its expansion would always be of type `A`, even though the computed value might be of the subtype `B`. The inline method is a "blackbox" in the sense that details of its implementation do not leak out. But if a `transparent` modifier is given,
the expansion is the type of the expanded body. If the argument `b`
is `true`, that type is `A`, otherwise it is `B`. Consequently, calling `meth` on `obj2`
Here, the inline method `choose` returns an instance of either of the two types `A` or `B`.
If `choose` had not been declared to be `transparent`, the result
of its expansion would always be of type `A`, even though the computed value might be of the subtype `B`.
The inline method is a "blackbox" in the sense that details of its implementation do not leak out.
But if a `transparent` modifier is given, the expansion is the type of the expanded body. If the argument `b`
is `true`, that type is `A`, otherwise it is `B`. Consequently, calling `m` on `obj2`
type-checks since `obj2` has the same type as the expansion of `choose(false)`, which is `B`.
Transparent inline methods are "whitebox" in the sense that the type
of an application of such a method can be more specialized than its declared
Expand Down