Skip to content

Commit 427d313

Browse files
authored
Merge pull request #13361 from dotty-staging/proto-implicit
wildApprox: also approximate FunProto arguments
2 parents bf7009e + bee299e commit 427d313

File tree

3 files changed

+22
-8
lines changed

3 files changed

+22
-8
lines changed

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

+4-7
Original file line numberDiff line numberDiff line change
@@ -562,7 +562,6 @@ trait ImplicitRunInfo:
562562

563563
object collectParts extends TypeTraverser:
564564

565-
private var provisional: Boolean = _
566565
private var parts: mutable.LinkedHashSet[Type] = _
567566
private val partSeen = util.HashSet[Type]()
568567

@@ -587,19 +586,18 @@ trait ImplicitRunInfo:
587586
case t: ConstantType =>
588587
traverse(t.underlying)
589588
case t: TypeParamRef =>
589+
assert(!ctx.typerState.constraint.contains(t), i"`wildApprox` failed to remove uninstantiated $t")
590590
traverse(t.underlying)
591-
if ctx.typerState.constraint.contains(t) then provisional = true
592591
case t: TermParamRef =>
593592
traverse(t.underlying)
594593
case t =>
595594
traverseChildren(t)
596595

597-
def apply(tp: Type): (collection.Set[Type], Boolean) =
598-
provisional = false
596+
def apply(tp: Type): collection.Set[Type] =
599597
parts = mutable.LinkedHashSet()
600598
partSeen.clear()
601599
traverse(tp)
602-
(parts, provisional)
600+
parts
603601
end collectParts
604602

605603
val seen = util.HashSet[Type]()
@@ -674,12 +672,11 @@ trait ImplicitRunInfo:
674672
end collectCompanions
675673

676674
def recur(tp: Type): OfTypeImplicits =
677-
val (parts, provisional) = collectParts(tp)
675+
val parts = collectParts(tp)
678676
val companions = collectCompanions(tp, parts)
679677
val result = OfTypeImplicits(tp, companions)(runContext)
680678
if Config.cacheImplicitScopes
681679
&& tp.hash != NotCached
682-
&& !provisional
683680
&& (tp eq rootTp) // first type traversed is always cached
684681
|| !incomplete.contains(tp) // other types are cached if they are not incomplete
685682
then implicitScopeCache(tp) = result

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

+15-1
Original file line numberDiff line numberDiff line change
@@ -394,7 +394,10 @@ object ProtoTypes {
394394
// `protoTyperState` committable we must ensure that it does not
395395
// contain any type variable which don't already exist in the passed
396396
// TyperState. This is achieved by instantiating any such type
397-
// variable.
397+
// variable. NOTE: this does not suffice to discard type variables
398+
// in ancestors of `protoTyperState`, if this situation ever
399+
// comes up, an assertion in TyperState will trigger and this code
400+
// will need to be generalized.
398401
if protoTyperState.isCommittable then
399402
val passedConstraint = passedTyperState.constraint
400403
val newLambdas = newConstraint.domainLambdas.filter(tl =>
@@ -822,6 +825,17 @@ object ProtoTypes {
822825
tp.derivedViewProto(
823826
wildApprox(tp.argType, theMap, seen, internal),
824827
wildApprox(tp.resultType, theMap, seen, internal))
828+
case tp: FunProto =>
829+
val args = tp.args.mapconserve(arg =>
830+
val argTp = tp.typeOfArg(arg) match
831+
case NoType => WildcardType
832+
case tp => wildApprox(tp, theMap, seen, internal)
833+
arg.withType(argTp))
834+
val resTp = wildApprox(tp.resultType, theMap, seen, internal)
835+
if (args eq tp.args) && (resTp eq tp.resultType) then
836+
tp
837+
else
838+
FunProtoTyped(args, resTp)(ctx.typer, tp.applyKind)
825839
case tp: IgnoredProto =>
826840
WildcardType
827841
case _: ThisType | _: BoundType => // default case, inlined for speed

tests/neg/i13340.scala

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
case class Field(name: String, subQuery: Option[Query] = None)
2+
case class Query(fields: Seq[Field])
3+
val x = Query(Seq(Field("a", subQuery=Some(Query(Seq(Field("b")), Nil)))), Nil) // error

0 commit comments

Comments
 (0)