diff options
-rw-r--r-- | src/dotty/tools/dotc/typer/Applications.scala | 19 | ||||
-rw-r--r-- | tests/neg/extractors.scala | 27 |
2 files changed, 44 insertions, 2 deletions
diff --git a/src/dotty/tools/dotc/typer/Applications.scala b/src/dotty/tools/dotc/typer/Applications.scala index 37a9f0ba0..13616ea6c 100644 --- a/src/dotty/tools/dotc/typer/Applications.scala +++ b/src/dotty/tools/dotc/typer/Applications.scala @@ -659,8 +659,23 @@ trait Applications extends Compatibility { self: Typer => def typedUnApply(tree: untpd.Apply, selType: Type)(implicit ctx: Context): Tree = track("typedUnApply") { val Apply(qual, args) = tree - def notAnExtractor(tree: Tree) = - errorTree(tree, s"${qual.show} cannot be used as an extractor in a pattern because it lacks an unapply or unapplySeq method") + def notAnExtractor(unapplyFn: Tree) = { + val methodStr = unapplyFn.symbol.name match { + case nme.unapply => "unapply" + case nme.unapplySeq => "unapplySeq" + case _ => "unapply or unapplySeq" + } + val because = unapplyFn.tpe.widen match { + case mt: MethodType => + i"its $methodStr method of type $mt" + ( + if (mt.isDependent) i" has a dependent type" + else if (mt.paramTypes.length != 1) i" does not take a single parameter" + else " is not eligible (this could be an internal compiler error)") + case _ => + "it lacks a unapply or unapplySeq method" + } + errorTree(unapplyFn, s"${qual.show} cannot be used as an extractor in a pattern $because") + } /** If this is a term ref tree, try to typecheck with its type name. * If this refers to a type alias, follow the alias, and if diff --git a/tests/neg/extractors.scala b/tests/neg/extractors.scala new file mode 100644 index 000000000..88600da76 --- /dev/null +++ b/tests/neg/extractors.scala @@ -0,0 +1,27 @@ +object A {} + +object B { + + def unapply[T](x: T): Option[x.type] = ??? + +} + +object C { + def unapply[T](x: T, y: T): Option[T] = ??? +} + +object D { + def unapply[T](): Option[T] = ??? +} + +object Test { + + val x: Any = ??? + x match { + case A(y) => ??? // error: A cannot be used as an extractor in a pattern it lacks a unapply or unapplySeq method + case B(y) => ??? // error: B cannot be used as an extractor in a pattern its unapply method of type (x: T)Option[T(x)] has a dependent type + case C(y) => ??? // error: C cannot be used as an extractor in a pattern its unapply method of type (x: T, y: T)Option[T] does not take a single parameter + case D(y) => ??? // error: D cannot be used as an extractor in a pattern its unapply method of type ()Option[T] does not take a single parameter + } + +} |