Skip to content

Commit 425c11e

Browse files
oderskytgodzik
authored andcommitted
Refine isMatched of IgnoredProtos
Fixes the Open CB counter example. [Cherry-picked 0436529]
1 parent 7a06235 commit 425c11e

File tree

2 files changed

+40
-4
lines changed

2 files changed

+40
-4
lines changed

compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -126,13 +126,15 @@ object ProtoTypes {
126126
override def viewExists(tp: Type, pt: Type)(using Context): Boolean = false
127127
}
128128

129-
/** A trait for prototypes that match all types */
130-
trait MatchAlways extends ProtoType {
131-
def isMatchedBy(tp1: Type, keepConstraint: Boolean)(using Context): Boolean = true
129+
/** A trait for prototypes that map to themselves */
130+
trait FixedProto extends ProtoType:
132131
def map(tm: TypeMap)(using Context): ProtoType = this
133132
def fold[T](x: T, ta: TypeAccumulator[T])(using Context): T = x
134133
override def toString: String = getClass.toString
135-
}
134+
135+
/** A trait for prototypes that match all types */
136+
trait MatchAlways extends FixedProto:
137+
def isMatchedBy(tp1: Type, keepConstraint: Boolean)(using Context): Boolean = true
136138

137139
/** A class marking ignored prototypes that can be revealed by `deepenProto` */
138140
abstract case class IgnoredProto(ignored: Type) extends CachedGroundType with MatchAlways:
@@ -143,6 +145,21 @@ object ProtoTypes {
143145
ignored
144146
override def deepenProtoTrans(using Context): Type = ignored.deepenProtoTrans
145147

148+
override def isMatchedBy(tp1: Type, keepConstraint: Boolean)(using Context): Boolean =
149+
def takesParams(tp: Type): Boolean = tp match
150+
case tp: PolyType => takesParams(tp.resType)
151+
case MethodType(pnames) => pnames.nonEmpty && !tp.isImplicitMethod
152+
case _ => false
153+
ignored match
154+
case ignored: SelectionProto if ignored.name != nme.apply =>
155+
// Non-implicit methods that take at least one parameter don't match ignored
156+
// selection protos unless the selection is via `apply`. This is because a
157+
// match of a different selection would require an eta expansion _and_ an
158+
// implicit conversion, which is not allowed. So the prototype would not
159+
// match even if implicit conversions were present. Test case: i23773a.scala.
160+
!takesParams(tp1.widen)
161+
case _ => true
162+
146163
/** Did someone look inside via deepenProto? Used for error deagniostics
147164
* to give a more extensive expected type.
148165
*/

tests/pos/i23773a.scala

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
trait NumericDate
2+
trait JWSDecoded[H]
3+
4+
trait StandardHeaderWrite[H]:
5+
def setAlgorithm(header: H, algorithm: Algorithm): H
6+
7+
object StandardHeaderWrite:
8+
def apply[H](using sh: StandardHeaderWrite[H]): StandardHeaderWrite[H] = ???
9+
// unused - required to reproduce
10+
def apply[H](setAlg: (H, Algorithm) => H): StandardHeaderWrite[H] = ???
11+
12+
final case class JWK(algorithm: Option[Algorithm])
13+
sealed trait Algorithm
14+
15+
def Test[F[_], H](key: JWK, header: H)(using StandardHeaderWrite[H]) = {
16+
key.algorithm
17+
.map(StandardHeaderWrite[H].setAlgorithm(header, _))
18+
.getOrElse(header)
19+
}

0 commit comments

Comments
 (0)