@@ -1035,19 +1035,51 @@ object desugar {
10351035 Bind (name, Ident (nme.WILDCARD )).withSpan(tree.span)
10361036 }
10371037
1038- def defTree (tree : Tree )(implicit ctx : Context ): Tree = tree match {
1039- case tree : ValDef => valDef(tree)
1040- case tree : TypeDef =>
1041- if (tree.isClassDef) classDef(tree)
1042- else if (tree.mods.is(Opaque , butNot = Synthetic )) opaqueAlias(tree)
1043- else tree
1044- case tree : DefDef =>
1045- if (tree.name.isConstructorName) tree // was already handled by enclosing classDef
1046- else defDef(tree)
1047- case tree : ModuleDef => moduleDef(tree)
1048- case tree : PatDef => patDef(tree)
1038+ /** The type of tests that check whether a MemberDef is OK for some flag.
1039+ * The test succeeds if the partial function is defined and returns true.
1040+ */
1041+ type MemberDefTest = PartialFunction [MemberDef , Boolean ]
1042+
1043+ val legalOpaque : MemberDefTest = {
1044+ case TypeDef (_, rhs) =>
1045+ def rhsOK (tree : Tree ): Boolean = tree match {
1046+ case _ : TypeBoundsTree | _ : Template => false
1047+ case LambdaTypeTree (_, body) => rhsOK(body)
1048+ case _ => true
1049+ }
1050+ rhsOK(rhs)
1051+ }
1052+
1053+ /** Check that modifiers are legal for the definition `tree`.
1054+ * Right now, we only check for `opaque`. TODO: Move other modifier checks here.
1055+ */
1056+ def checkModifiers (tree : Tree )(implicit ctx : Context ): Tree = tree match {
1057+ case tree : MemberDef =>
1058+ var tested : MemberDef = tree
1059+ def fail (msg : String ) = ctx.error(msg, tree.sourcePos)
1060+ def checkApplicable (flag : FlagSet , test : MemberDefTest ): Unit =
1061+ if (tested.mods.is(flag) && ! (test.isDefinedAt(tree) && test(tree))) {
1062+ fail(i " modifier ` $flag` is not allowed for this definition " )
1063+ tested = tested.withMods(tested.mods.withoutFlags(flag))
1064+ }
1065+ checkApplicable(Opaque , legalOpaque)
1066+ tested
1067+ case _ =>
1068+ tree
10491069 }
10501070
1071+ def defTree (tree : Tree )(implicit ctx : Context ): Tree =
1072+ checkModifiers(tree) match {
1073+ case tree : ValDef => valDef(tree)
1074+ case tree : TypeDef =>
1075+ if (tree.isClassDef) classDef(tree) else tree
1076+ case tree : DefDef =>
1077+ if (tree.name.isConstructorName) tree // was already handled by enclosing classDef
1078+ else defDef(tree)
1079+ case tree : ModuleDef => moduleDef(tree)
1080+ case tree : PatDef => patDef(tree)
1081+ }
1082+
10511083 /** { stats; <empty > }
10521084 * ==>
10531085 * { stats; () }
0 commit comments