From 5429dfa83808e53040b4535d7d1c0d3c9543fe29 Mon Sep 17 00:00:00 2001 From: Som Snytt Date: Thu, 20 Feb 2025 15:18:19 -0800 Subject: [PATCH] Check only stable qual for import prefix --- .../tools/dotc/transform/CheckUnused.scala | 2 +- tests/warn/i22629.scala | 42 +++++++++++++++++++ 2 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 tests/warn/i22629.scala diff --git a/compiler/src/dotty/tools/dotc/transform/CheckUnused.scala b/compiler/src/dotty/tools/dotc/transform/CheckUnused.scala index 03accbdfeb5c..5e7858c51296 100644 --- a/compiler/src/dotty/tools/dotc/transform/CheckUnused.scala +++ b/compiler/src/dotty/tools/dotc/transform/CheckUnused.scala @@ -73,7 +73,7 @@ class CheckUnused private (phaseMode: PhaseMode, suffix: String) extends MiniPha val target = res.dealias.typeSymbol resolveUsage(target, target.name, res.importPrefix.skipPackageObject) // case _: T => case _ => - else if tree.qualifier.srcPos.isSynthetic || name.exists(_ != tree.symbol.name) then + else if tree.qualifier.srcPos.isSynthetic && tree.qualifier.tpe.isStable || name.exists(_ != tree.symbol.name) then if !ignoreTree(tree) then resolveUsage(tree.symbol, name, tree.qualifier.tpe) else diff --git a/tests/warn/i22629.scala b/tests/warn/i22629.scala new file mode 100644 index 000000000000..53d17ec4da3b --- /dev/null +++ b/tests/warn/i22629.scala @@ -0,0 +1,42 @@ +//> using options -Wunused:all -Yno-deep-subtypes "-Wconf:msg=set repeatedly:s" + +//import either.* + +trait ResultMapper[A] { + final def map[B](f: A => B): ResultMapper[B] = ??? + + infix final def and[B](other: ResultMapper[B]): ResultMapper[(A, B)] = ??? +} + +trait BoilerplateResultMappers { + + def and[B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W]( + b: ResultMapper[B], c: ResultMapper[C], d: ResultMapper[D], e: ResultMapper[E], f: ResultMapper[F], g: ResultMapper[G], h: ResultMapper[H], i: ResultMapper[I], j: ResultMapper[J], k: ResultMapper[K], l: ResultMapper[L], m: ResultMapper[M], n: ResultMapper[N], o: ResultMapper[O], p: ResultMapper[P], q: ResultMapper[Q], r: ResultMapper[R], s: ResultMapper[S], t: ResultMapper[T], u: ResultMapper[U], v: ResultMapper[V], w: ResultMapper[W] + ): ResultMapper[(B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W)] = + (b and c and d and e and f and g and h and i and j and k and l and m and n and o and p and q and r and s and t and u and v and w).map { + case ((((((((((((((((((((((b), c), d), e), f), g), h), i), j), k), l), m), n), o), p), q), r), s), t), u), v), w) => + (b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w) + } +} + +/* +object either { + type ResultMapperException = RuntimeException + implicit class EitherOps[A](private val ea: Either[ResultMapperException, A]) extends AnyVal { + def and[B](eb: Either[ResultMapperException, B]): Either[ResultMapperException, (A, B)] = + (ea, eb) match { + case (Right(a), Right(b)) => + Right((a, b)) + + case (Right(_), Left(ex)) => + Left(ex) + + case (Left(ex), Right(_)) => + Left(ex) + + case (Left(_), Left(_)) => + Left(RuntimeException()) + } + } +} +*/