Skip to content

Attempt at fixing Applications.scala:95 #1589 #3780

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

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ public enum ErrorMessageID {
UnableToEmitSwitchID,
MissingCompanionForStaticID,
PolymorphicMethodMissingTypeInParentID,
NotAValidResultTypeOfUnapplyID
;

public int errorNumber() {
Expand Down
17 changes: 17 additions & 0 deletions compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2074,4 +2074,21 @@ object messages {
|$rsym does not override any method in $parentSym. Structural refinement does not allow for
|polymorphic methods."""
}

case class NotAValidResultTypeOfUnapply(sym: Symbol, resultType: Type, args: List[untpd.Tree])(implicit ctx: Context) extends Message(NotAValidResultTypeOfUnapplyID) {
val kind = "Reference"
val resultClassName = resultType.classSymbol.name
val msg = hl"Cannot extract (${sym.name}) from ${sym.owner}. $resultClassName is not a valid extractor return type"
val explanation =
hl"""${sym.name} method of ${sym.owner} has been tried as a candidate to extract ${args.map(_.show).mkString("[", ", ", "]")}
|Its return type: ${s"$resultClassName"} is not a valid return type for an extractor.
|
|The return type of an extractor should be chosen as follows:
| - If it is just a test, return a ${"Boolean"}. For instance ${"case even()"}
| - If it returns a single sub-value of type ${s"$resultClassName"}, return an ${s"Option[$resultClassName]"}
| - If you want to return several sub-values ${"T1,...,Tn"}, group them in an optional tuple ${"Option[(T1,...,Tn)]"}.
Copy link
Contributor

Choose a reason for hiding this comment

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

This is not telling the full story, we also need to mention option-less pattern matching
and talk about unapplySeq.

Copy link
Contributor

Choose a reason for hiding this comment

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

I believe unapplySeq has been deprecated in #3747

""".stripMargin

}

}
5 changes: 3 additions & 2 deletions compiler/src/dotty/tools/dotc/typer/Applications.scala
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import language.implicitConversions
import reporting.diagnostic.Message
import reporting.trace
import Constants.{Constant, IntTag, LongTag}
import dotty.tools.dotc.reporting.diagnostic.messages.UnapplyInvalidNumberOfArguments
import dotty.tools.dotc.reporting.diagnostic.messages.{NotAValidResultTypeOfUnapply, UnapplyInvalidNumberOfArguments}

import scala.collection.mutable.ListBuffer

Expand Down Expand Up @@ -93,7 +93,8 @@ object Applications {
def getTp = extractorMemberType(unapplyResult, nme.get, pos)

def fail = {
ctx.error(i"$unapplyResult is not a valid result type of an $unapplyName method of an extractor", pos)
// ctx.error(i"$unapplyResult is not a valid result type of an $unapplyName method of an extractor", pos)
ctx.error(NotAValidResultTypeOfUnapply(unapplyFn.symbol, unapplyResult, args), pos)
Nil
}

Expand Down
28 changes: 24 additions & 4 deletions compiler/test/dotty/tools/dotc/reporting/ErrorMessagesTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,10 @@ package dotty.tools
package dotc
package reporting

import core.Contexts.Context
import diagnostic.messages._
import dotty.tools.dotc.core.Flags
import dotty.tools.dotc.core.Flags.FlagSet
import dotty.tools.dotc.core.Contexts.Context
import dotty.tools.dotc.core.Types.WildcardType
import dotty.tools.dotc.parsing.Tokens
import dotty.tools.dotc.reporting.diagnostic.messages._
import org.junit.Assert._
import org.junit.Test

Expand Down Expand Up @@ -1294,4 +1292,26 @@ class ErrorMessagesTests extends ErrorMessagesTest {
assertEquals("method get", rsym.show)
assertEquals("class Object", parentSym.show)
}

@Test def notAValidReturnTypeOfUnapply =
checkMessagesAfter("frontend") {
"""
|object Test {
| object Foo {
| def unapply(arg: String): String = arg.toUpperCase
| }
| val Foo(unextractedValue) = "test"
|}
""".stripMargin
}.expect { (ictx, messages) =>
implicit val ctx: Context = ictx

assertMessageCount(1, messages)
val NotAValidResultTypeOfUnapply(sym, resultType, args) = messages.head
assertEquals("method unapply", sym.show)
assertEquals("String", resultType.show)
assertEquals(1, args.length)
assertEquals("unextractedValue", args.head.show)
}

}