@@ -407,71 +407,52 @@ combineSubstitutionMaps(SubstitutionMap firstSubMap,
407407 GenericSignature genericSig) {
408408 auto &ctx = genericSig->getASTContext ();
409409
410- auto replaceGenericParameter = [&](Type type) -> std::optional<Type> {
411- if (auto gp = type->getAs <GenericTypeParamType>()) {
412- if (gp->getDepth () < firstDepth)
413- return Type ();
414- return Type (GenericTypeParamType::get (gp->isParameterPack (),
415- gp->getDepth () + secondDepth -
416- firstDepth,
417- gp->getIndex (), ctx));
418- }
419-
420- return std::nullopt ;
421- };
422-
423410 return SubstitutionMap::get (
424411 genericSig,
425412 [&](SubstitutableType *type) {
426- if (auto replacement = replaceGenericParameter (type))
427- if (*replacement)
428- return replacement->subst (secondSubMap);
429- return Type (type).subst (firstSubMap);
413+ auto *gp = cast<GenericTypeParamType>(type);
414+ if (gp->getDepth () < firstDepth)
415+ return QuerySubstitutionMap{firstSubMap}(gp);
416+
417+ auto *replacement = GenericTypeParamType::get (
418+ gp->isParameterPack (),
419+ gp->getDepth () + secondDepth - firstDepth,
420+ gp->getIndex (), ctx);
421+ return QuerySubstitutionMap{secondSubMap}(replacement);
430422 },
431- [&](CanType type, Type substType, ProtocolDecl *proto) {
432- if (auto replacement = type.transformRec (replaceGenericParameter))
433- return secondSubMap.lookupConformance (replacement->getCanonicalType (),
434- proto);
435- if (auto conformance = firstSubMap.lookupConformance (type, proto))
436- return conformance;
437-
438- // We might not have enough information in the substitution maps alone.
439- //
440- // Eg,
441- //
442- // class Base<T1> {
443- // func foo<U1>(_: U1) where T1 : P {}
444- // }
445- //
446- // class Derived<T2> : Base<Foo<T2>> {
447- // override func foo<U2>(_: U2) where T2 : Q {}
448- // }
449- //
450- // Suppose we're devirtualizing a call to Base.foo() on a value whose
451- // type is known to be Derived<Bar>. We start with substitutions written
452- // in terms of Base.foo()'s generic signature:
453- //
454- // <T1, U1 where T1 : P>
455- // T1 := Foo<Bar>
456- // T1 : P := Foo<Bar> : P
457- //
458- // We want to build substitutions in terms of Derived.foo()'s
459- // generic signature:
460- //
461- // <T2, U2 where T2 : Q>
462- // T2 := Bar
463- // T2 : Q := Bar : Q
464- //
465- // The conformance Bar : Q is difficult to recover in the general case.
466- //
467- // Some combination of storing substitution maps in BoundGenericTypes
468- // as well as for method overrides would solve this, but for now, just
469- // punt to module lookup.
470- if (substType->isTypeParameter ())
471- return ProtocolConformanceRef (proto);
472-
473- return swift::lookupConformance (substType, proto);
474- });
423+ // We might not have enough information in the substitution maps alone.
424+ //
425+ // Eg,
426+ //
427+ // class Base<T1> {
428+ // func foo<U1>(_: U1) where T1 : P {}
429+ // }
430+ //
431+ // class Derived<T2> : Base<Foo<T2>> {
432+ // override func foo<U2>(_: U2) where T2 : Q {}
433+ // }
434+ //
435+ // Suppose we're devirtualizing a call to Base.foo() on a value whose
436+ // type is known to be Derived<Bar>. We start with substitutions written
437+ // in terms of Base.foo()'s generic signature:
438+ //
439+ // <T1, U1 where T1 : P>
440+ // T1 := Foo<Bar>
441+ // T1 : P := Foo<Bar> : P
442+ //
443+ // We want to build substitutions in terms of Derived.foo()'s
444+ // generic signature:
445+ //
446+ // <T2, U2 where T2 : Q>
447+ // T2 := Bar
448+ // T2 : Q := Bar : Q
449+ //
450+ // The conformance Bar : Q is difficult to recover in the general case.
451+ //
452+ // Some combination of storing substitution maps in BoundGenericTypes
453+ // as well as for method overrides would solve this, but for now, just
454+ // punt to global lookup.
455+ LookUpConformanceInModule ());
475456}
476457
477458// Start with the substitutions from the apply.
0 commit comments