Skip to content

Commit 26a00d4

Browse files
authored
Merge pull request #10910 from slavapestov/generic-subscript-materialize-for-set-infer-requirements-4.0
Sema: Explicitly infer requirements from subscript element type for materializeForSet [4.0]
2 parents 437b053 + 8aaa553 commit 26a00d4

File tree

2 files changed

+42
-0
lines changed

2 files changed

+42
-0
lines changed

lib/Sema/TypeCheckGeneric.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -555,6 +555,26 @@ static bool checkGenericFuncSignature(TypeChecker &tc,
555555
source);
556556
}
557557
}
558+
559+
// If this is a materializeForSet, infer requirements from the
560+
// storage type instead, since it's not part of the accessor's
561+
// type signature.
562+
if (fn->getAccessorKind() == AccessorKind::IsMaterializeForSet) {
563+
if (builder) {
564+
auto *storage = fn->getAccessorStorageDecl();
565+
if (auto *subscriptDecl = dyn_cast<SubscriptDecl>(storage)) {
566+
auto source =
567+
GenericSignatureBuilder::FloatingRequirementSource::forInferred(
568+
subscriptDecl->getElementTypeLoc().getTypeRepr(),
569+
/*quietly=*/true);
570+
571+
TypeLoc type(nullptr, subscriptDecl->getElementInterfaceType());
572+
assert(type.getType());
573+
builder->inferRequirements(*func->getParentModule(),
574+
type, source);
575+
}
576+
}
577+
}
558578
}
559579

560580
return badType;

test/SILGen/materializeForSet.swift

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -466,6 +466,28 @@ extension GenericSubscriptProtocol {
466466

467467
struct GenericSubscriptDefaultWitness : GenericSubscriptProtocol { }
468468

469+
// Make sure we correctly infer the 'T : Magic' requirement on all the accessors
470+
// of the subscript.
471+
472+
struct GenericTypeWithRequirement<T : Magic> {}
473+
474+
protocol InferredRequirementOnSubscriptProtocol {
475+
subscript<T>(i: Int) -> GenericTypeWithRequirement<T> { get set }
476+
}
477+
478+
struct InferredRequirementOnSubscript : InferredRequirementOnSubscriptProtocol {
479+
subscript<T>(i: Int) -> GenericTypeWithRequirement<T> {
480+
get { }
481+
set { }
482+
}
483+
}
484+
485+
// CHECK-LABEL: sil hidden @_T017materializeForSet30InferredRequirementOnSubscriptV9subscriptAA015GenericTypeWithE0VyxGSicAA5MagicRzlufg : $@convention(method) <T where T : Magic> (Int, InferredRequirementOnSubscript) -> GenericTypeWithRequirement<T>
486+
487+
// CHECK-LABEL: sil hidden @_T017materializeForSet30InferredRequirementOnSubscriptV9subscriptAA015GenericTypeWithE0VyxGSicAA5MagicRzlufs : $@convention(method) <T where T : Magic> (GenericTypeWithRequirement<T>, Int, @inout InferredRequirementOnSubscript) -> ()
488+
489+
// CHECK-LABEL: sil hidden [transparent] @_T017materializeForSet30InferredRequirementOnSubscriptV9subscriptAA015GenericTypeWithE0VyxGSicAA5MagicRzlufm : $@convention(method) <T where T : Magic> (Builtin.RawPointer, @inout Builtin.UnsafeValueBuffer, Int, @inout InferredRequirementOnSubscript) -> (Builtin.RawPointer, Optional<Builtin.RawPointer>)
490+
469491
// Test for materializeForSet vs static properties of structs.
470492

471493
protocol Beverage {

0 commit comments

Comments
 (0)