[SE-0258] Ensure that we fully check the property type vs. wrapper's value type

Various optimizations / shortcuts in type checking property wrappers meant
that we weren't consistently verifying that a wrapped property type is
identical to the type of the 'value' property of the wrapper. Do so.

Fixes SR-10899 / rdar://problem/51588022.
This commit is contained in:
Doug Gregor
2019-06-11 10:01:53 -07:00
parent f5ab62aa81
commit 5e00f01ce4
2 changed files with 33 additions and 2 deletions

View File

@@ -1756,13 +1756,34 @@ PropertyWrapperBackingPropertyInfoRequest::evaluate(Evaluator &evaluator,
auto dc = var->getDeclContext();
Type storageInterfaceType = wrapperType;
Type storageType =
var->getDeclContext()->mapTypeIntoContext(storageInterfaceType);
Type storageType = dc->mapTypeIntoContext(storageInterfaceType);
if (!storageType) {
storageType = ErrorType::get(ctx);
isInvalid = true;
}
// Make sure that the property type matches the value of the
// wrapper type.
if (!storageType->hasError()) {
Type expectedPropertyType =
storageType->getTypeOfMember(
dc->getParentModule(),
wrapperInfo.valueVar,
wrapperInfo.valueVar->getValueInterfaceType());
Type propertyType =
dc->mapTypeIntoContext(var->getValueInterfaceType());
if (!expectedPropertyType->hasError() &&
!propertyType->hasError() &&
!propertyType->isEqual(expectedPropertyType)) {
var->diagnose(diag::property_wrapper_incompatible_property,
propertyType, wrapperType);
if (auto nominalWrapper = wrapperType->getAnyNominal()) {
nominalWrapper->diagnose(diag::property_wrapper_declared_here,
nominalWrapper->getFullName());
}
}
}
// Create the backing storage property and note it in the cache.
VarDecl *backingVar = new (ctx) VarDecl(/*IsStatic=*/var->isStatic(),
VarDecl::Specifier::Var,