diff --git a/compiler/src/dotty/tools/dotc/core/Flags.scala b/compiler/src/dotty/tools/dotc/core/Flags.scala index e3d907d6abd6..3c76ad61bf0e 100644 --- a/compiler/src/dotty/tools/dotc/core/Flags.scala +++ b/compiler/src/dotty/tools/dotc/core/Flags.scala @@ -134,7 +134,7 @@ object Flags { } /** The list of non-empty names of flags that are set in the given flag set */ - def flagStrings(privateWithin: String): Seq[String] = { + def flagStrings(privateWithin: String = ""): Seq[String] = { var rawStrings = (2 to MaxFlag).flatMap(x.flagString(_)) // DOTTY problem: cannot drop with (_) if (!privateWithin.isEmpty && !x.is(Protected)) rawStrings = rawStrings :+ "private" diff --git a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala index 1c8bedc8ed7b..928f4055a659 100644 --- a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala +++ b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala @@ -3844,19 +3844,21 @@ object Parsers { */ def refineStatSeq(): List[Tree] = { val stats = new ListBuffer[Tree] - def checkLegal(tree: Tree): List[Tree] = { - val isLegal = tree match { - case tree: ValDef => tree.rhs.isEmpty && !tree.mods.flags.is(Mutable) - case tree: DefDef => tree.rhs.isEmpty - case tree: TypeDef => true - case _ => false - } - if (isLegal) tree :: Nil - else { - syntaxError("illegal refinement", tree.span) - Nil - } - } + def checkLegal(tree: Tree): List[Tree] = + val problem = tree match + case tree: MemberDef if !(tree.mods.flags & ModifierFlags).isEmpty => + i"refinement cannot be ${(tree.mods.flags & ModifierFlags).flagStrings().mkString("`", "`, `", "`")}" + case tree: ValOrDefDef => + if tree.rhs.isEmpty then "" + else "refinement in cannot have a right-hand side" + case tree: TypeDef => + if !tree.isClassDef then "" + else "refinement cannot be a class or trait" + case _ => + "this kind of definition cannot be a refinement" + if problem.isEmpty then tree :: Nil + else { syntaxError(problem, tree.span); Nil } + while (!isStatSeqEnd) { if (isDclIntro) stats ++= checkLegal(defOrDcl(in.offset, Modifiers())) diff --git a/tests/neg/i8150.scala b/tests/neg/i8150.scala new file mode 100644 index 000000000000..d286201acf81 --- /dev/null +++ b/tests/neg/i8150.scala @@ -0,0 +1,3 @@ +trait A +trait B +type T = {given(given a: A) as B} // error: refinement cannot be `given` \ No newline at end of file