You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Eta-expand 0-arity method if expected type is Function0
Reverse course from the deprecation introduced in 2.12.
(4.3) condition for eta-expansion by -Xsource level:
- until 2.13:
- for arity > 0: function or sam type is expected
- for arity == 0: Function0 is expected -- SAM types do not eta-expand
because it could be an accidental SAM scala/bug#9489
- 2.14:
- for arity > 0: unconditional
- for arity == 0: a function-ish type of arity 0 is expected (including SAM)
- 3.0: auto-application takes precedence, but otherwise we always eta-expand
warnings:
- 2.12: eta-expansion of zero-arg methods was deprecated (scala/bug#7187)
- 2.13: deprecation dropped in favor of setting the scene for uniform eta-expansion in 3.0
- 2.14: expected type is a SAM that is not annotated with `@FunctionalInterface`
(4.2) condition for auto-application by -Xsource level:
- until 2.14: none (assuming condition for (4.3) was not met)
- in 3.0: `meth.isJavaDefined`
elses"$pt, which is SAM-equivalent to ${samToFunctionType(pt)}"
896
+
897
+
reporter.warning(tree.pos, s"An unapplied 0-arity method was eta-expanded (due to the expected type ${ptHelp}), rather than applied to `()`.\n"+
898
+
s"Write ${Apply(warnTree, Nil)} to invoke method ${meth.decodedName}, or change the expected type.")
899
+
}
900
+
901
+
defwarnEtaSam() = {
902
+
valsam= samOf(pt)
903
+
if (sam.exists &&!sam.owner.hasAnnotation(definitions.FunctionalInterfaceClass))
904
+
reporter.warning(tree.pos, s"Eta-expansion performed to meet expected type $pt, even though ${sam.owner} is not annotated with `@FunctionalInterface`.")
907
905
}
908
-
// (4.3) eta-expand method value when function or sam type is expected (for experimentation, always eta-expand under 2.14 source level)
909
-
elseif (isFunctionProto(pt) || settings.isScala214) { // TODO: decide on `settings.isScala214`
910
-
if (settings.isScala212 && mt.params.isEmpty) // implies isFunctionType(pt)
911
-
currentRun.reporting.deprecationWarning(tree.pos, NoSymbol, "Eta-expansion of zero-argument methods is deprecated. "+
912
-
s"To avoid this warning, write ${Function(Nil, Apply(tree, Nil))}.", "2.12.0")
913
906
914
-
typedEtaExpansion(tree, mode, pt)
907
+
// note that isFunctionProto(pt) does not work properly for Function0
// (4.2) condition for auto-application by -Xsource level
945
+
//
946
+
// until 2.14: none (assuming condition for (4.3) was not met)
947
+
// in 3.0: `meth.isJavaDefined`
948
+
defcanAutoApply:Boolean=
949
+
if (sourceLevel3) meth.isJavaDefined
950
+
else {
951
+
if (sourceLevel2_14 &&!meth.isJavaDefined)
952
+
context.deprecationWarning(tree.pos, NoSymbol, s"Auto-application to `()` is deprecated. Write ${Apply(warnTree, Nil)} to invoke method ${meth.decodedName},"+
953
+
s"or remove the empty argument list from its definition (Java-defined methods are exempt).\n"+
954
+
s"In Scala 3, an unapplied method will be eta-expanded, as in: ${Function(Nil, Apply(warnTree, Nil))}.", "2.14.0")
955
+
true
956
+
}
957
+
958
+
if (!meth.isConstructor && canEtaExpand) { if (!expectingFunctionOfArity) warnEtaSam(); typedEtaExpansion(tree, mode, pt) }
val t2: () => Any = m2 // error, no eta-expansion of zero-args methods
6
+
t7187-2.14.scala:14: warning: An unapplied 0-arity method was eta-expanded (due to the expected type () => Any), rather than applied to `()`.
7
+
Write m2() to invoke method m2, or change the expected type.
8
+
val t2: () => Any = m2 // eta-expanded with lint warning
9
+
^
10
+
t7187-2.14.scala:15: warning: An unapplied 0-arity method was eta-expanded (due to the expected type AcciSamZero, which is SAM-equivalent to () => Int), rather than applied to `()`.
11
+
Write m2() to invoke method m2, or change the expected type.
12
+
val t2AcciSam: AcciSamZero = m2 // eta-expanded with lint warning + sam warning
13
+
^
14
+
t7187-2.14.scala:15: warning: Eta-expansion performed to meet expected type AcciSamZero, even though trait AcciSamZero is not annotated with `@FunctionalInterface`.
15
+
val t2AcciSam: AcciSamZero = m2 // eta-expanded with lint warning + sam warning
16
+
^
17
+
t7187-2.14.scala:16: warning: An unapplied 0-arity method was eta-expanded (due to the expected type SamZero, which is SAM-equivalent to () => Int), rather than applied to `()`.
18
+
Write m2() to invoke method m2, or change the expected type.
19
+
val t2Sam: SamZero = m2 // eta-expanded with lint warning
val t1f: Any = foo() _ // error: _ must follow method
3
7
^
4
-
t7187.scala:11: error: type mismatch;
8
+
t7187.scala:19: error: type mismatch;
5
9
found : String
6
10
required: () => Any
7
-
val t2a: () => Any = bar // error: no eta-expansion of zero-arglist-methods
11
+
val t2a: () => Any = bar // error: no eta-expansion of zero-arglist-methods (nullary methods)
8
12
^
9
-
t7187.scala:12: error: not enough arguments for method apply: (i: Int)Char in class StringOps.
13
+
t7187.scala:20: error: not enough arguments for method apply: (i: Int)Char in class StringOps.
10
14
Unspecified value parameter i.
11
15
val t2b: () => Any = bar() // error: bar doesn't take arguments, so expanded to bar.apply(), which misses an argument
12
16
^
13
-
t7187.scala:15: error: not enough arguments for method apply: (i: Int)Char in class StringOps.
17
+
t7187.scala:23: error: not enough arguments for method apply: (i: Int)Char in class StringOps.
14
18
Unspecified value parameter i.
15
19
val t2e: Any = bar() _ // error: not enough arguments for method apply
16
20
^
17
-
t7187.scala:18: error: type mismatch;
18
-
found : String
19
-
required: () => Any
20
-
val t3a: () => Any = baz // eta-expansion (deprecated) in 2.12, error in 2.13
21
+
t7187.scala:26: warning: An unapplied 0-arity method was eta-expanded (due to the expected type () => Any), rather than applied to `()`.
22
+
Write baz() to invoke method baz, or change the expected type.
23
+
val t3a: () => Any = baz // eta-expansion, but lint warning
21
24
^
22
-
t7187.scala:21: error: _ must follow method; cannot follow String
25
+
t7187.scala:29: error: _ must follow method; cannot follow String
23
26
val t3d: Any = baz() _ // error: _ must follow method
24
27
^
25
-
t7187.scala:24: error: type mismatch;
26
-
found : String
27
-
required: () => Any
28
-
val t4a: () => Any = zap // eta-expansion (deprecated) in 2.12, error in 2.13
28
+
t7187.scala:32: warning: An unapplied 0-arity method was eta-expanded (due to the expected type () => Any), rather than applied to `()`.
29
+
Write zap() to invoke method zap, or change the expected type.
30
+
val t4a: () => Any = zap // eta-expansion, but lint warning
29
31
^
30
-
t7187.scala:25: error: type mismatch;
31
-
found : String
32
-
required: () => Any
32
+
t7187.scala:33: warning: An unapplied 0-arity method was eta-expanded (due to the expected type () => Any), rather than applied to `()`.
33
+
Write zap()() to invoke method zap, or change the expected type.
33
34
val t4b: () => Any = zap() // ditto
34
35
^
35
-
t7187.scala:30: error: missing argument list for method zup in class EtaExpandZeroArg
36
+
t7187.scala:38: error: missing argument list for method zup in class EtaExpandZeroArg
36
37
Unapplied methods are only converted to functions when a function type is expected.
37
38
You can make this conversion explicit by writing `zup _` or `zup(_)` instead of `zup`.
38
39
val t5a = zup // error in 2.13, eta-expansion in 2.14
39
40
^
40
-
9 errors found
41
+
t7187.scala:40: warning: Eta-expansion performed to meet expected type AcciSamOne, even though trait AcciSamOne is not annotated with `@FunctionalInterface`.
42
+
val t5AcciSam: AcciSamOne = zup // ok, but warning
0 commit comments