Skip to content

[CSBindings] Open collection before binding parameter only if origina… #30113

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 28, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 19 additions & 14 deletions lib/Sema/CSBindings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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())
Expand All @@ -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);
Expand Down
8 changes: 5 additions & 3 deletions lib/Sema/CSSimplify.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3799,9 +3799,11 @@ bool ConstraintSystem::repairFailures(
if (tupleLocator->isLastElement<LocatorPathElt::SequenceElementType>())
break;

// Generic argument failures have a more general fix which is attached to a
// parent type and aggregates all argument failures into a single fix.
if (tupleLocator->isLastElement<LocatorPathElt::GenericArgument>())
// Generic argument/requirement failures have a more general fix which
// is attached to a parent type and aggregates all argument failures
// into a single fix.
if (tupleLocator->isLastElement<LocatorPathElt::AnyRequirement>() ||
tupleLocator->isLastElement<LocatorPathElt::GenericArgument>())
break;

ConstraintFix *fix;
Expand Down
1 change: 0 additions & 1 deletion test/Constraints/construction.swift
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,6 @@ func rdar_50668864() {
struct Foo {
init(anchors: [Int]) { // expected-note {{'init(anchors:)' declared here}}
self = .init { _ in [] } // expected-error {{trailing closure passed to parameter of type '[Int]' that does not accept a closure}}
// expected-error@-1 {{generic parameter 'Element' could not be inferred}}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
// FIXME: This should be linear instead of exponential.
// RUN: %scale-test --begin 1 --end 10 --step 1 --select NumLeafScopes --invert-result %s -Xfrontend=-solver-expression-time-threshold=1
// RUN: %scale-test --begin 1 --end 20 --step 1 --select NumLeafScopes %s -Xfrontend=-solver-expression-time-threshold=1
// REQUIRES: asserts,no_asan
// REQUIRES: rdar57138194,SR11770

enum Val {
case d([String: Val])
Expand Down