Skip to content

Commit

Permalink
Disallow toplevel infix vals, vars, givens, methods and implicits (#1…
Browse files Browse the repository at this point in the history
…7994)

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]>
  • Loading branch information
arainko and mbovel authored Jul 13, 2023
1 parent f4aa793 commit fd8bcea
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 2 deletions.
4 changes: 2 additions & 2 deletions compiler/src/dotty/tools/dotc/reporting/messages.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2608,10 +2608,10 @@ class AnonymousInstanceCannotBeEmpty(impl: untpd.Template)(using Context)
|"""
}

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

class RedundantModifier(flag: Flag)(using Context)
Expand Down
2 changes: 2 additions & 0 deletions compiler/src/dotty/tools/dotc/typer/Checking.scala
Original file line number Diff line number Diff line change
Expand Up @@ -561,6 +561,8 @@ object Checking {
fail(CannotHaveSameNameAs(sym, cls, CannotHaveSameNameAs.CannotBeOverridden))
sym.setFlag(Private) // break the overriding relationship by making sym Private
}
if sym.isWrappedToplevelDef && !sym.isType && sym.flags.is(Infix, butNot = Extension) then
fail(ModifierNotAllowedForDefinition(Flags.Infix, s"A top-level ${sym.showKind} cannot be infix."))
checkApplicable(Erased,
!sym.isOneOf(MutableOrLazy, butNot = Given) && !sym.isType || sym.isClass)
checkCombination(Final, Open)
Expand Down
45 changes: 45 additions & 0 deletions tests/neg/i17738-toplevel-infix.check
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
-- [E156] Syntax Error: tests/neg/i17738-toplevel-infix.scala:14:10 ----------------------------------------------------
14 |infix val toplevelVal = ??? // error
| ^
| Modifier infix is not allowed for this definition
|--------------------------------------------------------------------------------------------------------------------
| Explanation (enabled by `-explain`)
|- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| A top-level value cannot be infix.
--------------------------------------------------------------------------------------------------------------------
-- [E156] Syntax Error: tests/neg/i17738-toplevel-infix.scala:15:10 ----------------------------------------------------
15 |infix var toplevelVar = ??? // error
| ^
| Modifier infix is not allowed for this definition
|--------------------------------------------------------------------------------------------------------------------
| Explanation (enabled by `-explain`)
|- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| A top-level variable cannot be infix.
--------------------------------------------------------------------------------------------------------------------
-- [E156] Syntax Error: tests/neg/i17738-toplevel-infix.scala:16:10 ----------------------------------------------------
16 |infix def toplevelDef = ??? // error
| ^
| Modifier infix is not allowed for this definition
|--------------------------------------------------------------------------------------------------------------------
| Explanation (enabled by `-explain`)
|- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| A top-level method cannot be infix.
--------------------------------------------------------------------------------------------------------------------
-- [E156] Syntax Error: tests/neg/i17738-toplevel-infix.scala:17:12 ----------------------------------------------------
17 |infix given toplevelGiven: Int = ??? // error
| ^
| Modifier infix is not allowed for this definition
|--------------------------------------------------------------------------------------------------------------------
| Explanation (enabled by `-explain`)
|- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| A top-level given instance cannot be infix.
--------------------------------------------------------------------------------------------------------------------
-- [E156] Syntax Error: tests/neg/i17738-toplevel-infix.scala:18:19 ----------------------------------------------------
18 |infix implicit val toplevelImplicit: Int = ??? // error
| ^
| Modifier infix is not allowed for this definition
|--------------------------------------------------------------------------------------------------------------------
| Explanation (enabled by `-explain`)
|- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| A top-level value cannot be infix.
--------------------------------------------------------------------------------------------------------------------
18 changes: 18 additions & 0 deletions tests/neg/i17738-toplevel-infix.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// scalac: -explain
infix type A[b, a] = Nothing

infix type B[b, a] = b match {
case Int => a
}

infix class C[A, B]
infix trait D[A, B]

extension (x: Boolean)
infix def or (y: => Boolean) = x || y

infix val toplevelVal = ??? // error
infix var toplevelVar = ??? // error
infix def toplevelDef = ??? // error
infix given toplevelGiven: Int = ??? // error
infix implicit val toplevelImplicit: Int = ??? // error

0 comments on commit fd8bcea

Please sign in to comment.