summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Zaugg <jzaugg@gmail.com>2013-04-21 15:06:45 -0700
committerJason Zaugg <jzaugg@gmail.com>2013-04-21 15:06:45 -0700
commitd484c17dbc47559dad8a7ae544d14a285cdfb8b2 (patch)
treee086b72d212c478a615816f20de96ec2a2bc1806
parente8b37c79ca0535da56f852d922c1f88c3fd0e005 (diff)
parente7aadd00392a512ddcf53396d489f0f17bfac231 (diff)
downloadscala-d484c17dbc47559dad8a7ae544d14a285cdfb8b2.tar.gz
scala-d484c17dbc47559dad8a7ae544d14a285cdfb8b2.tar.bz2
scala-d484c17dbc47559dad8a7ae544d14a285cdfb8b2.zip
Merge pull request #2358 from adriaanm/ticket-7330
SI-7330 better error when pattern's not a value
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala35
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala18
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala5
-rw-r--r--test/files/neg/t414.check2
-rw-r--r--test/files/neg/t4879.check4
-rw-r--r--test/files/neg/t7330.check5
-rw-r--r--test/files/neg/t7330.scala5
7 files changed, 43 insertions, 31 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala
index 4bf7f78167..49049f110d 100644
--- a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala
@@ -589,6 +589,10 @@ trait ContextErrors {
setError(tree)
}
+ // typedPattern
+ def PatternMustBeValue(pat: Tree, pt: Type) =
+ issueNormalTypeError(pat, s"pattern must be a value: $pat"+ typePatternAdvice(pat.tpe.typeSymbol, pt.typeSymbol))
+
// SelectFromTypeTree
def TypeSelectionFromVolatileTypeError(tree: Tree, qual: Tree) = {
val hiBound = qual.tpe.bounds.hi
@@ -920,33 +924,10 @@ trait ContextErrors {
def IncompatibleScrutineeTypeError(tree: Tree, pattp: Type, pt: Type) =
issueNormalTypeError(tree, "scrutinee is incompatible with pattern type" + foundReqMsg(pattp, pt))
- def PatternTypeIncompatibleWithPtError2(pat: Tree, pt1: Type, pt: Type) = {
- def errMsg = {
- val sym = pat.tpe.typeSymbol
- val clazz = sym.companionClass
- val addendum = (
- if (sym.isModuleClass && clazz.isCaseClass && (clazz isSubClass pt1.typeSymbol)) {
- // TODO: move these somewhere reusable.
- val typeString = clazz.typeParams match {
- case Nil => "" + clazz.name
- case xs => xs map (_ => "_") mkString (clazz.name + "[", ",", "]")
- }
- val caseString = (
- clazz.caseFieldAccessors
- map (_ => "_") // could use the actual param names here
- mkString (clazz.name + "(", ",", ")")
- )
- (
- "\nNote: if you intended to match against the class, try `case _: " +
- typeString + "` or `case " + caseString + "`"
- )
- }
- else ""
- )
- "pattern type is incompatible with expected type"+foundReqMsg(pat.tpe, pt) + addendum
- }
- issueNormalTypeError(pat, errMsg)
- }
+ def PatternTypeIncompatibleWithPtError2(pat: Tree, pt1: Type, pt: Type) =
+ issueNormalTypeError(pat,
+ "pattern type is incompatible with expected type"+ foundReqMsg(pat.tpe, pt) +
+ typePatternAdvice(pat.tpe.typeSymbol, pt1.typeSymbol))
def PolyAlternativeError(tree: Tree, argtypes: List[Type], sym: Symbol, err: PolyAlternativeErrorKind.ErrorType) = {
import PolyAlternativeErrorKind._
diff --git a/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala b/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala
index 9376cb5237..4950a7efef 100644
--- a/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala
@@ -286,6 +286,24 @@ trait TypeDiagnostics {
)
}
+ def typePatternAdvice(sym: Symbol, ptSym: Symbol) = {
+ val clazz = if (sym.isModuleClass) sym.companionClass else sym
+ val caseString =
+ if (clazz.isCaseClass && (clazz isSubClass ptSym))
+ ( clazz.caseFieldAccessors
+ map (_ => "_") // could use the actual param names here
+ mkString (s"`case ${clazz.name}(", ",", ")`")
+ )
+ else
+ "`case _: " + (clazz.typeParams match {
+ case Nil => "" + clazz.name
+ case xs => xs map (_ => "_") mkString (clazz.name + "[", ",", "]")
+ })+ "`"
+
+ "\nNote: if you intended to match against the class, try "+ caseString
+
+ }
+
case class TypeDiag(tp: Type, sym: Symbol) extends Ordered[TypeDiag] {
// save the name because it will be mutated until it has been
// distinguished from the other types in the same error message
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index c21dfe6ec7..a57c34c032 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -5707,7 +5707,10 @@ trait Typers extends Modes with Adaptations with Tags {
// as a compromise, context.enrichmentEnabled tells adaptToMember to go ahead and enrich,
// but arbitrary conversions (in adapt) are disabled
// TODO: can we achieve the pattern matching bit of the string interpolation SIP without this?
- typingInPattern(context.withImplicitsDisabledAllowEnrichment(typed(tree, PATTERNmode, pt)))
+ typingInPattern(context.withImplicitsDisabledAllowEnrichment(typed(tree, PATTERNmode, pt))) match {
+ case tpt if tpt.isType => PatternMustBeValue(tpt, pt); tpt
+ case pat => pat
+ }
}
/** Types a (fully parameterized) type tree */
diff --git a/test/files/neg/t414.check b/test/files/neg/t414.check
index e15dbaea71..30211eef8e 100644
--- a/test/files/neg/t414.check
+++ b/test/files/neg/t414.check
@@ -1,7 +1,7 @@
t414.scala:5: error: pattern type is incompatible with expected type;
found : Empty.type
required: IntMap[a]
-Note: if you intended to match against the class, try `case _: Empty[_]` or `case Empty()`
+Note: if you intended to match against the class, try `case Empty()`
case Empty =>
^
t414.scala:7: error: type mismatch;
diff --git a/test/files/neg/t4879.check b/test/files/neg/t4879.check
index 21cd329640..c7edd583c8 100644
--- a/test/files/neg/t4879.check
+++ b/test/files/neg/t4879.check
@@ -1,13 +1,13 @@
t4879.scala:6: error: pattern type is incompatible with expected type;
found : C.type
required: C
-Note: if you intended to match against the class, try `case _: C` or `case C(_)`
+Note: if you intended to match against the class, try `case C(_)`
case C => true
^
t4879.scala:10: error: pattern type is incompatible with expected type;
found : D.type
required: D[T,U,V]
-Note: if you intended to match against the class, try `case _: D[_,_,_]` or `case D(_,_,_)`
+Note: if you intended to match against the class, try `case D(_,_,_)`
case D => true
^
two errors found
diff --git a/test/files/neg/t7330.check b/test/files/neg/t7330.check
new file mode 100644
index 0000000000..b96d656d2b
--- /dev/null
+++ b/test/files/neg/t7330.check
@@ -0,0 +1,5 @@
+t7330.scala:4: error: pattern must be a value: Y[_]
+Note: if you intended to match against the class, try `case _: Y[_]`
+ 0 match { case Y[_] => }
+ ^
+one error found
diff --git a/test/files/neg/t7330.scala b/test/files/neg/t7330.scala
new file mode 100644
index 0000000000..13a943a02b
--- /dev/null
+++ b/test/files/neg/t7330.scala
@@ -0,0 +1,5 @@
+class Y[T]
+class Test {
+ // TypeTree is not a valid tree for a pattern
+ 0 match { case Y[_] => }
+} \ No newline at end of file