mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
[CSBindings] Open collection before binding parameter only if original argument type failed
Instead of always opening argument type represented by a collection without type variables (to support subtyping when element is a labeled tuple), let's try original type first and if that fails use a slower path with indirection which attempts `array upcast`. Doing it this way helps to propagate contextual information faster which fixes a performance regression. Resolves: rdar://problem/54580247
This commit is contained in:
@@ -1043,6 +1043,25 @@ bool TypeVarBindingProducer::computeNext() {
|
||||
if (auto simplifiedSuper = CS.checkTypeOfBinding(TypeVar, supertype))
|
||||
addNewBinding(binding.withType(*simplifiedSuper));
|
||||
}
|
||||
|
||||
auto srcLocator = binding.getLocator();
|
||||
if (srcLocator &&
|
||||
srcLocator->isLastElement<LocatorPathElt::ApplyArgToParam>() &&
|
||||
!type->hasTypeVariable() && CS.isCollectionType(type)) {
|
||||
// If the type binding comes from the argument conversion, let's
|
||||
// instead of binding collection types directly, try to bind
|
||||
// using temporary type variables substituted for element
|
||||
// types, that's going to ensure that subtype relationship is
|
||||
// always preserved.
|
||||
auto *BGT = type->castTo<BoundGenericType>();
|
||||
auto UGT = UnboundGenericType::get(BGT->getDecl(), BGT->getParent(),
|
||||
BGT->getASTContext());
|
||||
|
||||
auto dstLocator = TypeVar->getImpl().getLocator();
|
||||
auto newType = CS.openUnboundGenericType(UGT, dstLocator)
|
||||
->reconstituteSugar(/*recursive=*/false);
|
||||
addNewBinding(binding.withType(newType));
|
||||
}
|
||||
}
|
||||
|
||||
if (newBindings.empty())
|
||||
@@ -1062,20 +1081,6 @@ bool TypeVariableBinding::attempt(ConstraintSystem &cs) const {
|
||||
if (Binding.hasDefaultedLiteralProtocol()) {
|
||||
type = cs.openUnboundGenericType(type, dstLocator);
|
||||
type = type->reconstituteSugar(/*recursive=*/false);
|
||||
} else if (srcLocator &&
|
||||
srcLocator->isLastElement<LocatorPathElt::ApplyArgToParam>() &&
|
||||
!type->hasTypeVariable() && cs.isCollectionType(type)) {
|
||||
// If the type binding comes from the argument conversion, let's
|
||||
// instead of binding collection types directly, try to bind
|
||||
// using temporary type variables substituted for element
|
||||
// types, that's going to ensure that subtype relationship is
|
||||
// always preserved.
|
||||
auto *BGT = type->castTo<BoundGenericType>();
|
||||
auto UGT = UnboundGenericType::get(BGT->getDecl(), BGT->getParent(),
|
||||
BGT->getASTContext());
|
||||
|
||||
type = cs.openUnboundGenericType(UGT, dstLocator);
|
||||
type = type->reconstituteSugar(/*recursive=*/false);
|
||||
}
|
||||
|
||||
cs.addConstraint(ConstraintKind::Bind, TypeVar, type, srcLocator);
|
||||
|
||||
Reference in New Issue
Block a user