diff --git a/compiler/src/dotty/tools/dotc/core/Types.scala b/compiler/src/dotty/tools/dotc/core/Types.scala index 04dfbbb26ef7..5413113fb8f6 100644 --- a/compiler/src/dotty/tools/dotc/core/Types.scala +++ b/compiler/src/dotty/tools/dotc/core/Types.scala @@ -4943,7 +4943,7 @@ object Types { record("MatchType.reduce computed") if (myReduced != null) record("MatchType.reduce cache miss") myReduced = - trace(i"reduce match type $this $hashCode", matchTypes, show = true) { + trace(i"reduce match type $this $hashCode", matchTypes, show = true)(inMode(Mode.Type) { def matchCases(cmp: TrackingTypeComparer): Type = val saved = ctx.typerState.snapshot() try cmp.matchCases(scrutinee.normalized, cases) @@ -4956,7 +4956,7 @@ object Types { // instantiations during matchtype reduction TypeComparer.tracked(matchCases) - } + }) myReduced.nn } diff --git a/tests/pos/i16408.min1.scala b/tests/pos/i16408.min1.scala new file mode 100644 index 000000000000..8c45fbaa9783 --- /dev/null +++ b/tests/pos/i16408.min1.scala @@ -0,0 +1,26 @@ +object Helpers: + type NodeFun[R] = Matchable // compiles without [R] parameter + + type URIFun[R] = R match + case GetURI[u] => u & NodeFun[R] + + private type GetURI[U] = RDF { type URI = U } +end Helpers + +trait RDF: + type URI + +trait ROps[R <: RDF]: + def auth(uri: Helpers.URIFun[R]): String + +object TraitRDF extends RDF: + override type URI = TraitTypes.UriImpl + + val rops = new ROps[TraitRDF.type] { + override def auth(uri: Helpers.URIFun[TraitRDF.type]): String = ??? + } +end TraitRDF + +object TraitTypes: + trait UriImpl // doesn't compile + // class UriImpl // compiles diff --git a/tests/pos/i16408.min2.scala b/tests/pos/i16408.min2.scala new file mode 100644 index 000000000000..3eb9d395ac4b --- /dev/null +++ b/tests/pos/i16408.min2.scala @@ -0,0 +1,22 @@ +object Helpers: + type NodeFun[R] = Matchable // compiles without [R] parameter + + type URIFun[R] = R match + case RDF[u] => u & NodeFun[R] +end Helpers + +trait RDF[URIParam] + +trait ROps[R <: RDF[?]]: + def auth(uri: Helpers.URIFun[R]): String + +object TraitRDF extends RDF[TraitTypes.UriImpl]: + + val rops = new ROps[TraitRDF.type] { + override def auth(uri: Helpers.URIFun[TraitRDF.type]): String = ??? + } +end TraitRDF + +object TraitTypes: + trait UriImpl // doesn't compile + // class UriImpl // compiles diff --git a/tests/pos/i16408.scala b/tests/pos/i16408.scala new file mode 100644 index 000000000000..10e8b16bab72 --- /dev/null +++ b/tests/pos/i16408.scala @@ -0,0 +1,57 @@ +import scala.util.Try + +trait RDF: + rdf => + + type R = rdf.type + type Node <: Matchable + type URI <: Node + + given rops: ROps[R] +end RDF + +object RDF: + type Node[R <: RDF] = R match + case GetNode[n] => Matchable //n & rNode[R] + + type URI[R <: RDF] <: Node[R] = R match + case GetURI[u] => u & Node[R] + + private type GetNode[N] = RDF { type Node = N } + private type GetURI[U] = RDF { type URI = U } +end RDF + +trait ROps[R <: RDF]: + def mkUri(str: String): Try[RDF.URI[R]] + def auth(uri: RDF.URI[R]): Try[String] + +object TraitTypes: + trait Node: + def value: String + + trait Uri extends Node + + def mkUri(u: String): Uri = + new Uri { def value = u } + +object TraitRDF extends RDF: + import TraitTypes as tz + + override opaque type Node <: Matchable = tz.Node + override opaque type URI <: Node = tz.Uri + + given rops: ROps[R] with + override def mkUri(str: String): Try[RDF.URI[R]] = Try(tz.mkUri(str)) + override def auth(uri: RDF.URI[R]): Try[String] = + Try(java.net.URI.create(uri.value).getAuthority()) + +end TraitRDF + +class Test[R <: RDF](using rops: ROps[R]): + import rops.given + lazy val uriT: Try[RDF.URI[R]] = rops.mkUri("https://bblfish.net/#i") + lazy val x: String = "uri authority=" + uriT.map(u => rops.auth(u)) + +@main def run = + val test = Test[TraitRDF.type] + println(test.x)