diff --git a/compiler/src/dotty/tools/dotc/transform/CheckUnused.scala b/compiler/src/dotty/tools/dotc/transform/CheckUnused.scala index 29af47ce844e..b9076ea4b6c0 100644 --- a/compiler/src/dotty/tools/dotc/transform/CheckUnused.scala +++ b/compiler/src/dotty/tools/dotc/transform/CheckUnused.scala @@ -367,7 +367,7 @@ object CheckUnused: explicitParamInScope += memDef else if currScopeType.top == ScopeType.Local then localDefInScope += memDef - else if currScopeType.top == ScopeType.Template && memDef.symbol.is(Private, butNot = SelfName) then + else if memDef.shouldReportPrivateDef then privateDefInScope += memDef /** Register pattern variable */ @@ -589,10 +589,13 @@ object CheckUnused: private def isValidParam(using Context): Boolean = val sym = memDef.symbol - (sym.is(Param) || sym.isAllOf(PrivateParamAccessor)) && + (sym.is(Param) || sym.isAllOf(PrivateParamAccessor | Local, butNot = CaseAccessor)) && !isSyntheticMainParam(sym) && !sym.shouldNotReportParamOwner + private def shouldReportPrivateDef(using Context): Boolean = + currScopeType.top == ScopeType.Template && !memDef.symbol.isConstructor && memDef.symbol.is(Private, butNot = SelfName | Synthetic | CaseAccessor) + extension (imp: tpd.Import) /** Enum generate an import for its cases (but outside them), which should be ignored */ def isGeneratedByEnum(using Context): Boolean = diff --git a/tests/neg-custom-args/fatal-warnings/i15503c.scala b/tests/neg-custom-args/fatal-warnings/i15503c.scala index e34587fa5802..0d6d704d5296 100644 --- a/tests/neg-custom-args/fatal-warnings/i15503c.scala +++ b/tests/neg-custom-args/fatal-warnings/i15503c.scala @@ -17,4 +17,11 @@ class A: val x = 1 // OK def y = 2 // OK - def z = g // OK \ No newline at end of file + def z = g // OK + +package foo.test.contructors: + case class A private (x:Int) // OK + class B private (val x: Int) // OK + class C private (private val x: Int) // error + class D private (private val x: Int): // OK + def y = x \ No newline at end of file diff --git a/tests/neg-custom-args/fatal-warnings/i15503i.scala b/tests/neg-custom-args/fatal-warnings/i15503i.scala index 60a1ad4741fd..c4d95c7904fa 100644 --- a/tests/neg-custom-args/fatal-warnings/i15503i.scala +++ b/tests/neg-custom-args/fatal-warnings/i15503i.scala @@ -73,4 +73,51 @@ package foo.test.companionprivate: object A: private def b = c // OK - def c = List(1,2,3) // OK \ No newline at end of file + def c = List(1,2,3) // OK + +package foo.test.possibleclasses: + case class AllCaseClass( + k: Int, // OK + private val y: Int // OK /* Kept as it can be taken from pattern */ + )( + s: Int, // error /* But not these */ + val t: Int, // OK + private val z: Int // error + ) + + case class AllCaseUsed( + k: Int, // OK + private val y: Int // OK + )( + s: Int, // OK + val t: Int, // OK + private val z: Int // OK + ) { + def a = k + y + s + t + z + } + + class AllClass( + k: Int, // error + private val y: Int // error + )( + s: Int, // error + val t: Int, // OK + private val z: Int // error + ) + + class AllUsed( + k: Int, // OK + private val y: Int // OK + )( + s: Int, // OK + val t: Int, // OK + private val z: Int // OK + ) { + def a = k + y + s + t + z + } + +package foo.test.from.i16675: + case class PositiveNumber private (i: Int) // OK + object PositiveNumber: + def make(i: Int): Option[PositiveNumber] = //OK + Option.when(i >= 0)(PositiveNumber(i)) // OK \ No newline at end of file