Skip to content

Commit dfba6d1

Browse files
committed
Disallow inline given aliases with functions as RHS
```scala inline given a: Conversion[String, Item] = Item(_) // error ``` will now produce this error: ``` 5 | inline given a: Conversion[String, Item] = Item(_) // error | ^^^^^^^ |inline given alias cannot have a function value as right-hand side. |Either drop `inline` or rewrite the given with an explicit `apply` method. |----------------------------------------------------------------------------- | Explanation (enabled by `-explain`) |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | A function value on the right-hand side of an inline given alias would expand to | an anonymous class. Each application of the inline given would then create a | fresh copy of that class, which can increase code size in surprising ways. | For that reason, functions are disallowed as right hand sides of inline given aliases. | You should either drop `inline` or rewrite to an explicit `apply` method. E.g. | | inline given Conversion[A, B] = x => x.toB // error | | should be re-formulated as | | inline given Conversion[A, B] with | def apply(x: A) = x.toB | ``` Fixes scala#16497
1 parent 716d93d commit dfba6d1

File tree

4 files changed

+31
-0
lines changed

4 files changed

+31
-0
lines changed

compiler/src/dotty/tools/dotc/reporting/ErrorMessageID.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,7 @@ enum ErrorMessageID(val isActive: Boolean = true) extends java.lang.Enum[ErrorMe
187187
case MissingArgumentID // errorNumer 171
188188
case MissingImplicitArgumentID // errorNumber 172
189189
case CannotBeAccessedID // errorNumber 173
190+
case InlineGivenCannotBeFunctionID // errorNumber 174
190191

191192
def errorNumber = ordinal - 1
192193

compiler/src/dotty/tools/dotc/reporting/messages.scala

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2769,4 +2769,23 @@ extends ReferenceMsg(CannotBeAccessedID):
27692769
i"$whatCanNot be accessed as a member of $pre$where.$whyNot"
27702770
def explain(using Context) = ""
27712771

2772+
class InlineGivenCannotBeFunction()(using Context)
2773+
extends SyntaxMsg(InlineGivenCannotBeFunctionID):
2774+
def msg(using Context) =
2775+
i"""inline given alias cannot have a function value as right-hand side.
2776+
|Either drop `inline` or rewrite the given with an explicit `apply` method."""
2777+
def explain(using Context) =
2778+
i"""A function value on the right-hand side of an inline given alias would expand to
2779+
|an anonymous class. Each application of the inline given would then create a
2780+
|fresh copy of that class, which can increase code size in surprising ways.
2781+
|For that reason, functions are disallowed as right hand sides of inline given aliases.
2782+
|You should either drop `inline` or rewrite to an explicit `apply` method. E.g.
2783+
|
2784+
| inline given Conversion[A, B] = x => x.toB // error
2785+
|
2786+
|should be re-formulated as
2787+
|
2788+
| inline given Conversion[A, B] with
2789+
| def apply(x: A) = x.toB
2790+
"""
27722791

compiler/src/dotty/tools/dotc/typer/Typer.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2374,6 +2374,8 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
23742374
if sym.isInlineMethod then
23752375
if StagingContext.level > 0 then
23762376
report.error("inline def cannot be within quotes", sym.sourcePos)
2377+
if sym.is(Given) && ddef.rhs.isInstanceOf[untpd.Function] then
2378+
report.error(InlineGivenCannotBeFunction(), ddef.rhs.srcPos)
23772379
val rhsToInline = PrepareInlineable.wrapRHS(ddef, tpt1, rhs1)
23782380
PrepareInlineable.registerInlineInfo(sym, rhsToInline)
23792381

tests/neg/inline-givens.scala

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
2+
class Item(x: String)
3+
4+
inline given a: Conversion[String, Item] =
5+
Item(_) // error
6+
7+
inline given b: Conversion[String, Item] with
8+
def apply(x: String) = Item(x)
9+

0 commit comments

Comments
 (0)