diff --git a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala index 7e4d94dc1f93..a931ac555fbd 100644 --- a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala +++ b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala @@ -1839,7 +1839,7 @@ object Parsers { val start = in.offset var mods = annotsAsMods() if (owner.isTypeName) { - mods = modifiers(start = mods) | ParamAccessor + mods = addFlag(modifiers(start = mods), ParamAccessor) mods = atPos(start, in.offset) { if (in.token == VAL) { diff --git a/compiler/src/dotty/tools/dotc/typer/Checking.scala b/compiler/src/dotty/tools/dotc/typer/Checking.scala index 942628519545..c7c1351f3fe5 100644 --- a/compiler/src/dotty/tools/dotc/typer/Checking.scala +++ b/compiler/src/dotty/tools/dotc/typer/Checking.scala @@ -338,9 +338,10 @@ object Checking { def checkWithDeferred(flag: FlagSet) = if (sym.is(flag)) fail(AbstractMemberMayNotHaveModifier(sym, flag)) - def checkNoConflict(flag1: FlagSet, flag2: FlagSet) = - if (sym.is(allOf(flag1, flag2))) - fail(i"illegal combination of modifiers: `$flag1` and `$flag2` for: $sym") + def checkNoConflict(flag1: FlagSet, flag2: FlagSet, msg: => String) = + if (sym.is(allOf(flag1, flag2))) fail(msg) + def checkCombination(flag1: FlagSet, flag2: FlagSet) = + checkNoConflict(flag1, flag2, i"illegal combination of modifiers: `$flag1` and `$flag2` for: $sym") def checkApplicable(flag: FlagSet, ok: Boolean) = if (!ok && !sym.is(Synthetic)) fail(i"modifier `$flag` is not allowed for this definition") @@ -373,10 +374,11 @@ object Checking { } if (sym.isValueClass && sym.is(Trait) && !sym.isRefinementClass) fail(CannotExtendAnyVal(sym)) - checkNoConflict(Final, Sealed) - checkNoConflict(Private, Protected) - checkNoConflict(Abstract, Override) - checkNoConflict(Lazy, Inline) + checkCombination(Final, Sealed) + checkCombination(Private, Protected) + checkCombination(Abstract, Override) + checkCombination(Lazy, Inline) + checkNoConflict(Lazy, ParamAccessor, s"parameter may not be `lazy`") if (sym.is(Inline)) checkApplicable(Inline, sym.isTerm && !sym.is(Mutable | Module)) if (sym.is(Lazy)) checkApplicable(Lazy, !sym.is(Method | Mutable)) if (sym.isType && !sym.is(Deferred)) diff --git a/tests/neg/i4058.scala b/tests/neg/i4058.scala new file mode 100644 index 000000000000..b2026ef1ca82 --- /dev/null +++ b/tests/neg/i4058.scala @@ -0,0 +1,12 @@ +class A(sealed val a: Int) { // error + sealed lazy val b = 10 // error +} +class B(lazy val a: Int) // error: parameter may not be lazy +class C(abstract val a: Int)// error +class D { + def f(sealed a: Int) = 0 // error + def g(lazy a: Int) = 0 // error + def g(override a: Int) = 0 // error + def g(abstract a: Int) = 0 // error +} +sealed erased class E // error