Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extend -Xlint:nullary-override for the reverse (nilary) case #8293

Merged
merged 2 commits into from Mar 27, 2020

Conversation

som-snytt
Copy link
Contributor

@som-snytt som-snytt commented Aug 1, 2019

If def m is overriding a def m() -Xlint:nullary-override now reports it as well, unless the def m() is defined in Java (such as Object's toString or hashCode) which are exempt.

@scala-jenkins scala-jenkins added this to the 2.13.1 milestone Aug 1, 2019
@som-snytt
Copy link
Contributor Author

The limited isJavaDefined test doesn't help here, and also the early warning beats the error; a late warning would be suppressed; maybe issue them after typer?

+t6534.scala:9: warning: nullary method assumes an empty parameter list from the overridden definition
+class Bippy4(val x: Int) extends AnyVal { override def hashCode = -1 }          // error
+                                                       ^
 t6534.scala:9: error: redefinition of hashCode method. See SIP-15, criterion 4. is not allowed in value class
 class Bippy4(val x: Int) extends AnyVal { override def hashCode = -1 }          // error

@lrytz
Copy link
Member

lrytz commented Jan 31, 2020

I think we should postpone any nullary/nilary changes to 2.13.3 (will do that for the other related PRs as well)

@lrytz lrytz modified the milestones: 2.13.2, 2.13.3 Jan 31, 2020
@som-snytt
Copy link
Contributor Author

This just enhances the optional warning and encourages alignment with Scala 3.

Copy link
Member

@dwijnand dwijnand left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. It could be that this needs to be pushed further into -Xsource:2.14 or even on-by-default-land, but we can tweak that post-merge.

Lint warns when an override adds an empty
parameter section, but not the other way
around, when an empty parameter section is
automatically supplied to match the overridden
member.

An overriding nullary method has already been
upgraded to its matching nilary, so refchecks
is unfortunately too late.
@som-snytt
Copy link
Contributor Author

Added a commit (not prematurely squashed) to use the warning category; the test tests that the warning is nowarnable; and the doc for nowarn is fixed.

Copy link
Member

@dwijnand dwijnand left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a great addition. Thanks, Som.

@SethTisue
Copy link
Member

I think we should postpone any nullary/nilary changes to 2.13.3

repeating this just to make sure nobody hits “merge” for now

@som-snytt
Copy link
Contributor Author

This just enhances the optional warning and encourages alignment with Scala 3.

repeating this in case @lrytz retracts his objection because it uses his warning framework. Or his nowarning framework.

@lrytz
Copy link
Member

lrytz commented Mar 19, 2020

in case @lrytz retracts his objection

I was swimming in some confusion about the entrie situation when I made that comment :-) We should still merge improvements in this area that are non-controversial.

For the issue here, maybe we can first investigate the viability of an alternative approach: allow f to override f() without synthetically inserting the parameter list. It might be less risky than it sounds, because f() can override f today.

$> ~/Applications/bin/scala-runners/scala -213x -Xsource:3
Welcome to Scala 2.13.2-bin-b4428c8 (Java HotSpot(TM) 64-Bit GraalVM EE 19.2.1, Java 1.8.0_231).
Type in expressions for evaluation. Or try :help.

scala> class C { def f = 0 }; class D extends C { override def f() = 1 }
class C
class D

scala> (new D).f
               ^
       warning: Auto-application to `()` is deprecated. Supply the empty argument list `()` explicitly to invoke method f,
       or remove the empty argument list from its definition (Java-defined methods are exempt).
       In Scala 3, an unapplied method like this will be eta-expanded into a function.
val res0: Int = 1

@lrytz
Copy link
Member

lrytz commented Mar 19, 2020

(by "allow" i mean the implementation; for users, any mismatch in overriding should trigger a warning)

@som-snytt
Copy link
Contributor Author

Since this PR doesn't introduce any options or cruft, I hear lrytz saying we can merge this and get the doc fix, and then further experiments with parens may update the check files.

The current spec is surely all about Java parens: implementing a trait in Java. But maybe there is no downside to letting overrides add or remove empty parens willy-nilly. Which is an apt pun for nillary.

The advance warning for eta-expansion is true only when expected type:

Starting dotty REPL...
scala> def f() = 42
def f(): Int

scala> f                                                                                                    
1 |f
  |^
  |method f must be called with () argument

scala> f: (() => Int)
val res0: () => Int = Lambda$1273/0x0000000802c5fc40@547aaa32

scala> def f = 42
def f: Int

scala> f: (() => Int)
1 |f: (() => Int)
  |^
  |Found:    Int
  |Required: () => Int

@dwijnand
Copy link
Member

The next change is to enable override warnings under -Xsource:2.14 (aka -Xsource:3).

@dwijnand dwijnand changed the title Also warn when parens are auto-supplied Extend -Xlint:nullary-override for the reverse (nilary) case Mar 26, 2020
@dwijnand dwijnand changed the title Extend -Xlint:nullary-override for the reverse (nilary) case Extend -Xlint:nullary-override for the reverse (nilary) case Mar 26, 2020
@dwijnand
Copy link
Member

@som-snytt I took the liberty of updating the PR title and description for the current state of the PR. But please check as I might've made mistakes (or killed your PR description "vibe" - edit away 😄).

Also, looking back again, I'm not sure about the tests: asides from the @warn addition, isn't the rest just duplications? Any reason for that?

Lastly, should this addition be under the same lint warning? It's simpler, but do we think users might want to enable one but not the other? -Xlint:nilary-override?

@som-snytt
Copy link
Contributor Author

@dwijnand thanks for the improved doc factor.

I think having both checks exercised in the nullary-override test shows that both warnings are shown and also that they are reported in an unexpected order.

It looks like I added the nowarn test when I added warning category support.

As to having a separate lint, the mechanics of that are just heavy enough to weigh against it. Also they are really the same, a mismatch in scala 3. Also too many options, and what would you name it.

@dwijnand
Copy link
Member

Also too many options, and what would you name it.

Xlint:nilary-override, but I'm fine with leaving it together.

@som-snytt
Copy link
Contributor Author

Right, except for a possible pun on "nilary clinton", it's not meaningful to folks not accustomed to paramss.

Copy link
Member

@lrytz lrytz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

investigate the viability of an alternative approach: allow f to override f() without synthetically inserting the parameter list.

For the record, previous discussion about this is here: #8445 (comment).

The adaptation leaks, that's why I'd prefer to change the implementation:

scala> class C { def name = "C"; override def toString = name }
defined class C

scala> (new C).name(0)
res0: Char = C

scala> (new C).toString(0)
                        ^
       error: no arguments allowed for nullary method toString: ()String

That said, I'm fine merging this as a step in the right direction.

@lrytz lrytz merged commit 59504a7 into scala:2.13.x Mar 27, 2020
@lrytz lrytz modified the milestones: 2.13.3, 2.13.2 Mar 27, 2020
@som-snytt
Copy link
Contributor Author

I agree it will be nice to respect the parens as written.

There is an analogy in constructors, although the different syntax ruins it:

scala> class C { def apply(i: Int) = 42+i }
defined class C

scala> new C
res0: C = C@52a33c3f

scala> new C(1)
             ^
       error: no arguments allowed for nullary constructor C: ()C

scala> (new C)(1)
res2: Int = 43

scala> (res2.toString)(0)
                       ^
       error: no arguments allowed for nullary method toString: ()String

@som-snytt som-snytt deleted the issue/warn-parenthetically branch March 27, 2020 11:38
@lrytz
Copy link
Member

lrytz commented Mar 27, 2020

The suggested change would likely also fix scala/bug#11158 (and be an alternative to #7625)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
6 participants