Skip to content

Commit 9430ee9

Browse files
committed
Deprecation warnings for old syntax: alphanumeric infix operators
This is the first part of #18870
1 parent 312e4bb commit 9430ee9

File tree

25 files changed

+113
-27
lines changed

25 files changed

+113
-27
lines changed

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

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1081,6 +1081,7 @@ trait Checking {
10811081
!name.isOperatorName &&
10821082
!meth.isDeclaredInfix &&
10831083
!meth.maybeOwner.is(Scala2x) &&
1084+
// TODO check is meth was compiled with 3.4+ compiler
10841085
!infixOKSinceFollowedBy(tree.right) =>
10851086
val (kind, alternative) =
10861087
if (ctx.mode.is(Mode.Type))
@@ -1089,13 +1090,14 @@ trait Checking {
10891090
("extractor", (n: Name) => s"prefix syntax $n(...)")
10901091
else
10911092
("method", (n: Name) => s"method syntax .$n(...)")
1092-
def rewriteMsg = Message.rewriteNotice("The latter", version = `future-migration`)
1093-
report.errorOrMigrationWarning(
1093+
def rewriteMsg = Message.rewriteNotice("The latter", version = `3.4-migration`)
1094+
report.gradualErrorOrMigrationWarning(
10941095
em"""Alphanumeric $kind $name is not declared ${hlAsKeyword("infix")}; it should not be used as infix operator.
10951096
|Instead, use ${alternative(name)} or backticked identifier `$name`.$rewriteMsg""",
10961097
tree.op.srcPos,
1097-
from = future)
1098-
if sourceVersion == `future-migration` then {
1098+
warnFrom = `3.4`,
1099+
errorFrom = future)
1100+
if sourceVersion.isMigrating && sourceVersion.isAtLeast(`3.4-migration`) then {
10991101
patch(Span(tree.op.span.start, tree.op.span.start), "`")
11001102
patch(Span(tree.op.span.end, tree.op.span.end), "`")
11011103
}

compiler/test-resources/repl/i1374

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
scala> implicit class Padder(val sb: StringBuilder) extends AnyVal { def pad2(width: Int) = { 1 to width - sb.length foreach { sb append '*' }; sb } }
1+
scala> implicit class Padder(val sb: StringBuilder) extends AnyVal { infix def pad2(width: Int) = { 1 to width - sb.length foreach { sb append '*' }; sb } }
22
// defined class Padder
33
def Padder(sb: StringBuilder): Padder
44
scala> val greeting = new StringBuilder("Hello, kitteh!")

compiler/test-resources/type-printer/infix

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ def foo: (Int &: String) & Boolean
2929
scala> def foo: Int &: (Boolean & String) = ???
3030
def foo: Int &: (Boolean & String)
3131
scala> import scala.annotation.showAsInfix
32-
scala> @scala.annotation.showAsInfix class Mappy[T,U]
32+
scala> @scala.annotation.showAsInfix infix class Mappy[T,U]
3333
// defined class Mappy
3434
scala> def foo: (Int Mappy Boolean) && String = ???
3535
def foo: (Int Mappy Boolean) && String

language-server/test/dotty/tools/languageserver/util/embedded/CodeMarker.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import PositionContext.PosCtx
1313
class CodeMarker(val name: String) extends Embedded {
1414

1515
/** A range of positions between this marker and `other`. */
16-
def to(other: CodeMarker): CodeRange = CodeRange(this, other)
16+
infix def to(other: CodeMarker): CodeRange = CodeRange(this, other)
1717

1818
/** The file containing this marker. */
1919
def file: PosCtx[TestFile] = posCtx.positionOf(this)._1

scaladoc-testcases/src/tests/infixTypes.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ package infixTypes
44
import annotation.showAsInfix
55

66
@showAsInfix
7-
trait SomeTrait[A, B]
7+
infix trait SomeTrait[A, B]
88

9-
trait SomeTrait2[A, B]
9+
infix trait SomeTrait2[A, B]
1010

1111
def someTrait1[C, D]: C SomeTrait D
1212
= ???

scaladoc/src/dotty/tools/scaladoc/tasty/comments/MemberLookup.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -236,9 +236,9 @@ object MemberLookup extends MemberLookup {
236236
// Scaladoc overloading support allows terminal * (and they're meaningless)
237237
val cleanStr = str.stripSuffix("*")
238238

239-
if cleanStr endsWith "$" then
239+
if cleanStr.endsWith("$") then
240240
Selector(cleanStr.init, SelectorKind.ForceTerm)
241-
else if cleanStr endsWith "!" then
241+
else if cleanStr.endsWith("!") then
242242
Selector(cleanStr.init, SelectorKind.ForceType)
243243
else
244244
Selector(cleanStr, SelectorKind.NoForce)

scaladoc/src/dotty/tools/scaladoc/tasty/comments/wiki/Parser.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -675,7 +675,7 @@ sealed class CharReader(buffer: String) { reader =>
675675

676676
var offset: Int = 0
677677
def char: Char =
678-
if (offset >= buffer.length) endOfText else buffer charAt offset
678+
if (offset >= buffer.length) endOfText else buffer.charAt(offset)
679679

680680
final def nextChar() =
681681
offset += 1
@@ -712,7 +712,7 @@ sealed class CharReader(buffer: String) { reader =>
712712
jumpWhitespace()
713713
val (ok0, chars0) =
714714
if (chars.charAt(0) == ' ')
715-
(offset > poff, chars substring 1)
715+
(offset > poff, chars.substring(1))
716716
else
717717
(true, chars)
718718
val ok = ok0 && jump(chars0)

scaladoc/test/dotty/tools/scaladoc/testUtils.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ def tastyFiles(name: String, allowEmpty: Boolean = false, rootPck: String = "tes
7171
}
7272
def collectFiles(dir: File): List[File] = listFilesSafe(dir).toList.flatMap {
7373
case f if f.isDirectory => collectFiles(f)
74-
case f if f.getName endsWith ".tasty" => f :: Nil
74+
case f if f.getName.endsWith(".tasty") => f :: Nil
7575
case _ => Nil
7676
}
7777
val outputDir = BuildInfo.test_testcasesOutputDir

tests/init-global/pos/i18628.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,10 @@ trait Parsers {
5555
}
5656

5757
def flatMap[U](f: T => Parser[U]): Parser[U]
58-
= Parser{ in => this(in) flatMapWithNext(f)}
58+
= Parser{ in => this(in).flatMapWithNext(f)}
5959

6060
def map[U](f: T => U): Parser[U] //= flatMap{x => success(f(x))}
61-
= Parser{ in => this(in) map(f)}
61+
= Parser{ in => this(in).map(f)}
6262

6363
def ^^ [U](f: T => U): Parser[U] = map(f)
6464
}

tests/init/pos/Properties.scala

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ private[scala] trait PropertiesTrait {
2525
val props = new java.util.Properties
2626
val stream = pickJarBasedOn getResourceAsStream propFilename
2727
if (stream ne null)
28-
quietlyDispose(props load stream, stream.close)
28+
quietlyDispose(props.load(stream), stream.close)
2929

3030
props
3131
}
@@ -47,8 +47,8 @@ private[scala] trait PropertiesTrait {
4747
final def setProp(name: String, value: String) = System.setProperty(name, value)
4848
final def clearProp(name: String) = System.clearProperty(name)
4949

50-
final def envOrElse(name: String, alt: String) = Option(System getenv name) getOrElse alt
51-
final def envOrNone(name: String) = Option(System getenv name)
50+
final def envOrElse(name: String, alt: String) = Option(System.getenv(name)) getOrElse alt
51+
final def envOrNone(name: String) = Option(System.getenv(name))
5252

5353
final def envOrSome(name: String, alt: Option[String]) = envOrNone(name) orElse alt
5454

@@ -68,7 +68,7 @@ private[scala] trait PropertiesTrait {
6868
val releaseVersion =
6969
for {
7070
v <- scalaPropOrNone("maven.version.number")
71-
if !(v endsWith "-SNAPSHOT")
71+
if !(v.endsWith("-SNAPSHOT"))
7272
} yield v
7373

7474
/** The development Scala version, if this is not a final release.
@@ -82,7 +82,7 @@ private[scala] trait PropertiesTrait {
8282
val developmentVersion =
8383
for {
8484
v <- scalaPropOrNone("maven.version.number")
85-
if v endsWith "-SNAPSHOT"
85+
if v.endsWith("-SNAPSHOT")
8686
ov <- scalaPropOrNone("version.number")
8787
} yield ov
8888

tests/init/pos/i15465.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ class TestSuite:
22
protected val it = new ItWord
33

44
protected final class ItWord:
5-
def should(string: String) = new ItVerbString("should", string)
5+
infix def should(string: String) = new ItVerbString("should", string)
66

77
private def registerTestToRun(fun: => Any): Unit = ()
88

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
//> using options -Werror
2+
3+
import language.`3.4`
4+
5+
class Foo:
6+
def x(i: Int) = i
7+
infix def y(i: Int) = i
8+
9+
def test(foo: Foo): Unit =
10+
foo x 1 // error (because it was compiled with 3.4+)
11+
foo y 2 // ok: is marked as infix
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
-- Error: tests/neg/alphanumeric-infix-operator.scala:8:6 --------------------------------------------------------------
2+
8 | foo x 1 // error (because it was compiled with 3.4+)
3+
| ^
4+
| Alphanumeric method x is not declared infix; it should not be used as infix operator.
5+
| Instead, use method syntax .x(...) or backticked identifier `x`.
6+
| The latter can be rewritten automatically under -rewrite -source 3.4-migration.
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
//> using options -Werror
2+
3+
class Foo:
4+
def x(i: Int) = i
5+
infix def y(i: Int) = i
6+
7+
def test(foo: Foo): Unit =
8+
foo x 1 // error (because it was compiled with 3.4+)
9+
foo y 2 // ok: is marked as infix

tests/neg/i10901.scala

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,23 +13,23 @@ object BugExp4Point2D {
1313

1414
// N - N
1515
@targetName("point2DConstant")
16-
def º(y: T2): Point2D[T1,T2] = ???
16+
infix def º(y: T2): Point2D[T1,T2] = ???
1717

1818

1919
// N - C
2020
@targetName("point2DConstantData")
21-
def º(y: ColumnType[T2]): Point2D[T1,T2] = ???
21+
infix def º(y: ColumnType[T2]): Point2D[T1,T2] = ???
2222

2323

2424

2525
extension [T1:Numeric, T2:Numeric](x: ColumnType[T1])
2626
// C - C
2727
@targetName("point2DData")
28-
def º(y: ColumnType[T2]): Point2D[T1,T2] = ???
28+
infix def º(y: ColumnType[T2]): Point2D[T1,T2] = ???
2929

3030
// C - N
3131
@targetName("point2DDataConstant")
32-
def º(y: T2): Point2D[T1,T2] = ???
32+
infix def º(y: T2): Point2D[T1,T2] = ???
3333

3434

3535
}

tests/neg/i2033.check

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,9 @@
1313
6 | val out = new ObjectOutputStream(println)
1414
| ^^^^^^^
1515
|method println is eta-expanded even though java.io.OutputStream does not have the @FunctionalInterface annotation.
16+
-- Warning: tests/neg/i2033.scala:7:18 ---------------------------------------------------------------------------------
17+
7 | val arr = bos toByteArray () // error
18+
| ^^^^^^^^^^^
19+
| Alphanumeric method toByteArray is not declared infix; it should not be used as infix operator.
20+
| Instead, use method syntax .toByteArray(...) or backticked identifier `toByteArray`.
21+
| The latter can be rewritten automatically under -rewrite -source 3.4-migration.

tests/neg/rewrite-messages.check

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,4 @@
88
| ^^^
99
| Alphanumeric method foo is not declared infix; it should not be used as infix operator.
1010
| Instead, use method syntax .foo(...) or backticked identifier `foo`.
11-
| The latter can be rewritten automatically under -rewrite -source future-migration.
11+
| The latter can be rewritten automatically under -rewrite -source 3.4-migration.

tests/neg/syntax-error-recovery.check

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,3 +136,9 @@
136136
| Discarded non-Unit value of type Null. You may want to use `()`.
137137
|
138138
| longer explanation available when compiling with `-explain`
139+
-- Warning: tests/neg/syntax-error-recovery.scala:61:2 -----------------------------------------------------------------
140+
61 | println(bam)
141+
| ^^^^^^^
142+
| Alphanumeric method println is not declared infix; it should not be used as infix operator.
143+
| Instead, use method syntax .println(...) or backticked identifier `println`.
144+
| The latter can be rewritten automatically under -rewrite -source 3.4-migration.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
class A:
2+
def x(i: Int) = i
3+
infix def y(i: Int) = i
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
class B:
2+
def x(i: Int) = i
3+
infix def y(i: Int) = i
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
class C:
2+
def x(i: Int) = i
3+
infix def y(i: Int) = i
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
class D:
2+
def x(i: Int) = i
3+
infix def y(i: Int) = i
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
//> using options -Werror
2+
3+
import language.`3.4`
4+
5+
def test1(a: A, b: B, c: C, d: D): Unit =
6+
a x 1 // ok: was compiled with 3.0
7+
b x 1 // ok: was compiled with 3.1
8+
c x 1 // ok: was compiled with 3.2
9+
d x 1 // ok: was compiled with 3.3
10+
11+
// ok: is marked as infix
12+
a y 2
13+
b y 2
14+
c y 2
15+
d y 2
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import language.future
2+
3+
def test2(a: A, b: B, c: C, d: D): Unit =
4+
a x 1 // ok: was compiled with 3.0
5+
b x 1 // ok: was compiled with 3.1
6+
c x 1 // ok: was compiled with 3.2
7+
d x 1 // ok: was compiled with 3.3
8+
9+
// ok: is marked as infix
10+
a y 2
11+
b y 2
12+
c y 2
13+
d y 2

tests/semanticdb/metac.expect

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3460,6 +3460,7 @@ Text => empty
34603460
Language => Scala
34613461
Symbols => 12 entries
34623462
Occurrences => 33 entries
3463+
Diagnostics => 1 entries
34633464
Synthetics => 4 entries
34643465

34653466
Symbols:
@@ -3511,6 +3512,11 @@ Occurrences:
35113512
[20:4..20:13): scalameta -> scala/reflect/Selectable#selectDynamic().
35123513
[21:4..21:19): StructuralTypes -> example/StructuralTypes.
35133514

3515+
Diagnostics:
3516+
[14:20..14:23): [warning] Alphanumeric method foo is not declared infix; it should not be used as infix operator.
3517+
Instead, use method syntax .foo(...) or backticked identifier `foo`.
3518+
The latter can be rewritten automatically under -rewrite -source 3.4-migration.
3519+
35143520
Synthetics:
35153521
[12:2..12:6):user => reflectiveSelectable(*)
35163522
[13:2..13:6):user => reflectiveSelectable(*)

0 commit comments

Comments
 (0)