Skip to content

Commit fd8bcea

Browse files
arainkombovel
andauthored
Disallow toplevel infix vals, vars, givens, methods and implicits (#17994)
Disallow infix toplevel definitions for anything that is not a `class`, `typealias`, `match type`, `extension method` and a `trait` (and `objects` as well but these are handled in their own PR). Part of #17738 Continuation of #17966 --------- Co-authored-by: Matt Bovel <[email protected]>
1 parent f4aa793 commit fd8bcea

File tree

4 files changed

+67
-2
lines changed

4 files changed

+67
-2
lines changed

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2608,10 +2608,10 @@ class AnonymousInstanceCannotBeEmpty(impl: untpd.Template)(using Context)
26082608
|"""
26092609
}
26102610

2611-
class ModifierNotAllowedForDefinition(flag: Flag)(using Context)
2611+
class ModifierNotAllowedForDefinition(flag: Flag, explanation: String = "")(using Context)
26122612
extends SyntaxMsg(ModifierNotAllowedForDefinitionID) {
26132613
def msg(using Context) = i"Modifier ${hl(flag.flagsString)} is not allowed for this definition"
2614-
def explain(using Context) = ""
2614+
def explain(using Context) = explanation
26152615
}
26162616

26172617
class RedundantModifier(flag: Flag)(using Context)

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -561,6 +561,8 @@ object Checking {
561561
fail(CannotHaveSameNameAs(sym, cls, CannotHaveSameNameAs.CannotBeOverridden))
562562
sym.setFlag(Private) // break the overriding relationship by making sym Private
563563
}
564+
if sym.isWrappedToplevelDef && !sym.isType && sym.flags.is(Infix, butNot = Extension) then
565+
fail(ModifierNotAllowedForDefinition(Flags.Infix, s"A top-level ${sym.showKind} cannot be infix."))
564566
checkApplicable(Erased,
565567
!sym.isOneOf(MutableOrLazy, butNot = Given) && !sym.isType || sym.isClass)
566568
checkCombination(Final, Open)

tests/neg/i17738-toplevel-infix.check

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
-- [E156] Syntax Error: tests/neg/i17738-toplevel-infix.scala:14:10 ----------------------------------------------------
2+
14 |infix val toplevelVal = ??? // error
3+
| ^
4+
| Modifier infix is not allowed for this definition
5+
|--------------------------------------------------------------------------------------------------------------------
6+
| Explanation (enabled by `-explain`)
7+
|- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
8+
| A top-level value cannot be infix.
9+
--------------------------------------------------------------------------------------------------------------------
10+
-- [E156] Syntax Error: tests/neg/i17738-toplevel-infix.scala:15:10 ----------------------------------------------------
11+
15 |infix var toplevelVar = ??? // error
12+
| ^
13+
| Modifier infix is not allowed for this definition
14+
|--------------------------------------------------------------------------------------------------------------------
15+
| Explanation (enabled by `-explain`)
16+
|- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
17+
| A top-level variable cannot be infix.
18+
--------------------------------------------------------------------------------------------------------------------
19+
-- [E156] Syntax Error: tests/neg/i17738-toplevel-infix.scala:16:10 ----------------------------------------------------
20+
16 |infix def toplevelDef = ??? // error
21+
| ^
22+
| Modifier infix is not allowed for this definition
23+
|--------------------------------------------------------------------------------------------------------------------
24+
| Explanation (enabled by `-explain`)
25+
|- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
26+
| A top-level method cannot be infix.
27+
--------------------------------------------------------------------------------------------------------------------
28+
-- [E156] Syntax Error: tests/neg/i17738-toplevel-infix.scala:17:12 ----------------------------------------------------
29+
17 |infix given toplevelGiven: Int = ??? // error
30+
| ^
31+
| Modifier infix is not allowed for this definition
32+
|--------------------------------------------------------------------------------------------------------------------
33+
| Explanation (enabled by `-explain`)
34+
|- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
35+
| A top-level given instance cannot be infix.
36+
--------------------------------------------------------------------------------------------------------------------
37+
-- [E156] Syntax Error: tests/neg/i17738-toplevel-infix.scala:18:19 ----------------------------------------------------
38+
18 |infix implicit val toplevelImplicit: Int = ??? // error
39+
| ^
40+
| Modifier infix is not allowed for this definition
41+
|--------------------------------------------------------------------------------------------------------------------
42+
| Explanation (enabled by `-explain`)
43+
|- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
44+
| A top-level value cannot be infix.
45+
--------------------------------------------------------------------------------------------------------------------

tests/neg/i17738-toplevel-infix.scala

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// scalac: -explain
2+
infix type A[b, a] = Nothing
3+
4+
infix type B[b, a] = b match {
5+
case Int => a
6+
}
7+
8+
infix class C[A, B]
9+
infix trait D[A, B]
10+
11+
extension (x: Boolean)
12+
infix def or (y: => Boolean) = x || y
13+
14+
infix val toplevelVal = ??? // error
15+
infix var toplevelVar = ??? // error
16+
infix def toplevelDef = ??? // error
17+
infix given toplevelGiven: Int = ??? // error
18+
infix implicit val toplevelImplicit: Int = ??? // error

0 commit comments

Comments
 (0)