Skip to content

Let inline val implement abstract inline def/val #8832

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
Show file tree
Hide file tree
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
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/typer/RefChecks.scala
Original file line number Diff line number Diff line change
Expand Up @@ -398,7 +398,7 @@ object RefChecks {
overrideError("is an extension method, cannot override a normal method")
else if (other.isAllOf(ExtensionMethod) && !member.isAllOf(ExtensionMethod)) // (1.9.2)
overrideError("is a normal method, cannot override an extension method")
else if other.isInlineMethod && !member.isInlineMethod then // (1.10)
else if other.is(Inline) && !member.is(Inline) then // (1.10)
overrideError("is not inline, cannot implement an inline method")
else if (other.isScala2Macro && !member.isScala2Macro) // (1.11)
overrideError("cannot be used here - only Scala-2 macros can override Scala-2 macros")
Expand Down
11 changes: 5 additions & 6 deletions compiler/src/dotty/tools/dotc/typer/Typer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3082,18 +3082,17 @@ class Typer extends Namer
checkEqualityEvidence(tree, pt)
tree
}
else if (methPart(tree).symbol.isAllOf(Inline | Deferred) && !ctx.inInlineMethod) then
errorTree(tree, i"Deferred inline ${methPart(tree).symbol.showLocated} cannot be invoked")
else if (Inliner.isInlineable(tree) &&
!ctx.settings.YnoInline.value &&
!suppressInline) {
tree.tpe <:< wildApprox(pt)
val errorCount = ctx.reporter.errorCount
val meth = methPart(tree).symbol
if meth.is(Deferred) then
errorTree(tree, i"Deferred inline ${meth.showLocated} cannot be invoked")
else
val inlined = Inliner.inlineCall(tree)
if ((inlined ne tree) && errorCount == ctx.reporter.errorCount) readaptSimplified(inlined)
else inlined
val inlined = Inliner.inlineCall(tree)
if ((inlined ne tree) && errorCount == ctx.reporter.errorCount) readaptSimplified(inlined)
else inlined
}
else if (tree.symbol.isScala2Macro &&
// raw and s are eliminated by the StringInterpolatorOpt phase
Expand Down
8 changes: 8 additions & 0 deletions tests/neg/abstract-inline-val.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
trait C:
inline def x: Int
inline val y: Int

def test: Unit =
val c: C = ???
c.x // error
c.y // error
11 changes: 11 additions & 0 deletions tests/pos/abstract-inline-val.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
trait C:
inline def x: Int
inline val y: Int

class C1 extends C:
inline val x = 1
inline val y = 2
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A side note: in inline val, we require the rhs to be a literal type, which is not really related to inline. Meanwhile, const-folding can be achieved by annotating the constant type explicitly.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, inline val requires a literal type result type and a pure body. This is a consequence of being marked as inline, as these are the only values that can be soundly inlined. We use constant folding to inline it because thee type already provides this functionality.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's more about semantics than soundness. There is an inconsistency between inline vals and inline parameters.


class C2 extends C:
inline def x = 3
inline val y = 4