From 7044e39a531a1e4056e3b71069ed9ce1fc0c3dc5 Mon Sep 17 00:00:00 2001 From: "Paolo G. Giarrusso" Date: Wed, 16 Jan 2019 15:03:32 +0100 Subject: [PATCH 1/2] Fix typo --- compiler/src/dotty/tools/dotc/typer/Namer.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/src/dotty/tools/dotc/typer/Namer.scala b/compiler/src/dotty/tools/dotc/typer/Namer.scala index 90611e820dda..c107b091d4b5 100644 --- a/compiler/src/dotty/tools/dotc/typer/Namer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Namer.scala @@ -270,7 +270,7 @@ class Namer { typer: Typer => /** Check that flags are OK for symbol. This is done early to avoid * catastrophic failure when we create a TermSymbol with TypeFlags, or vice versa. - * A more complete check is done in checkWellformed. + * A more complete check is done in checkWellFormed. */ def checkFlags(flags: FlagSet) = if (flags.isEmpty) flags From 986c2dffb83d4193ed6204fd570bbeb323f3ce44 Mon Sep 17 00:00:00 2001 From: "Paolo G. Giarrusso" Date: Wed, 16 Jan 2019 14:54:02 +0100 Subject: [PATCH 2/2] Refix #4936: Move check from Parsers back to Desugar This follows again the original strategy in 1ecf67bbac2c8a8867882948753c6c92a739637d. This check is at the latest possible point: a few lines later, `RetainedModuleValFlags` excludes `Abstract` and `Sealed` while `ModuleValCreationFlags` adds `Final`. Unlike in Parsers, at this point in Desugar we get Synthetic objects. We also get objects with flags but without corresponding mods; they might all be synthetic, but let's harden flagSpan anyway. --- compiler/src/dotty/tools/dotc/ast/Desugar.scala | 11 +++++++++++ compiler/src/dotty/tools/dotc/parsing/Parsers.scala | 10 ---------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/ast/Desugar.scala b/compiler/src/dotty/tools/dotc/ast/Desugar.scala index 3f835bbb96e2..f0221b47ad7b 100644 --- a/compiler/src/dotty/tools/dotc/ast/Desugar.scala +++ b/compiler/src/dotty/tools/dotc/ast/Desugar.scala @@ -701,6 +701,17 @@ object desugar { val impl = mdef.impl val mods = mdef.mods def isEnumCase = mods.isEnumCase + + def flagSourcePos(flag: FlagSet) = mods.mods.find(_.flags == flag).fold(mdef.sourcePos)(_.sourcePos) + + if (mods.is(Abstract)) + ctx.error(hl"""$Abstract modifier cannot be used for objects""", flagSourcePos(Abstract)) + if (mods.is(Sealed)) + ctx.error(hl"""$Sealed modifier is redundant for objects""", flagSourcePos(Sealed)) + // Maybe this should be an error; see https://github.com/scala/bug/issues/11094. + if (mods.is(Final) && !mods.is(Synthetic)) + ctx.warning(hl"""$Final modifier is redundant for objects""", flagSourcePos(Final)) + if (mods is Package) PackageDef(Ident(moduleName), cpy.ModuleDef(mdef)(nme.PACKAGE, impl).withMods(mods &~ Package) :: Nil) else if (isEnumCase) diff --git a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala index 35011a34b75a..63c36ba56e7c 100644 --- a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala +++ b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala @@ -2415,16 +2415,6 @@ object Parsers { def objectDefRest(start: Offset, mods: Modifiers, name: TermName): ModuleDef = { val template = templateOpt(emptyConstructor) - - def flagSpan(flag: FlagSet) = mods.mods.find(_.flags == flag).get.span - if (mods is Abstract) - syntaxError(hl"""${Abstract} modifier cannot be used for objects""", flagSpan(Abstract)) - if (mods is Sealed) - syntaxError(hl"""${Sealed} modifier is redundant for objects""", flagSpan(Sealed)) - // Maybe this should be an error; see https://github.com/scala/bug/issues/11094. - if (mods is Final) - warning(hl"""${Final} modifier is redundant for objects""", source atSpan flagSpan(Final)) - finalizeDef(ModuleDef(name, template), mods, start) }