Sema: Use dynamic dispatch for inout access of properties in classes

The problem is that the derived property's materializeForSet was
being synthesized after recordOverride() was called, so the new
accessor never got setOverridenDecl() called on it.

As a result, SIL didn't know that the derived materializeForSet
should replace the vtable entry for the base class materializeForSet.

The more fundamental problem here is that even after some recent
cleanups, accessors are still sometimes type checked before
the AbstractStorageDecla and sometimes after. So things like
inferring final, dynamic and overrides have to be duplicated in
multiple places.

Fixes <https://bugs.swift.org/browse/SR-3840> and
<rdar://problem/30336146>.
This commit is contained in:
Slava Pestov
2017-02-02 17:25:32 -08:00
parent ab581a2270
commit 06de5d70c1
3 changed files with 64 additions and 0 deletions

View File

@@ -814,6 +814,20 @@ static FuncDecl *addMaterializeForSet(AbstractStorageDecl *storage,
storage->getSetter());
storage->setMaterializeForSetFunc(materializeForSet);
// Make sure we record the override.
//
// FIXME: Instead, we should just not call checkOverrides() on
// storage until all accessors are in place.
if (auto *baseASD = storage->getOverriddenDecl()) {
// If the base storage has a private setter, we're not overriding
// materializeForSet either.
auto *baseMFS = baseASD->getMaterializeForSetFunc();
if (baseMFS != nullptr &&
baseASD->isSetterAccessibleFrom(storage->getDeclContext())) {
materializeForSet->setOverriddenDecl(baseMFS);
}
}
return materializeForSet;
}