diff --git a/lib/Sema/ConstraintSystem.cpp b/lib/Sema/ConstraintSystem.cpp index 536b682c38798..fa6e538308065 100644 --- a/lib/Sema/ConstraintSystem.cpp +++ b/lib/Sema/ConstraintSystem.cpp @@ -928,6 +928,72 @@ TypeVariableType *ConstraintSystem::isRepresentativeFor( return *member; } +static Optional> +getPropertyWrapperInformationFromOverload( + SelectedOverload resolvedOverload, DeclContext *DC, + llvm::function_ref>(VarDecl *)> + getInformation) { + if (auto *decl = + dyn_cast_or_null(resolvedOverload.choice.getDeclOrNull())) { + if (auto declInformation = getInformation(decl)) { + Type type; + VarDecl *memberDecl; + std::tie(memberDecl, type) = *declInformation; + if (Type baseType = resolvedOverload.choice.getBaseType()) { + type = + baseType->getTypeOfMember(DC->getParentModule(), memberDecl, type); + } + return std::make_pair(decl, type); + } + } + return None; +} + +Optional> +ConstraintSystem::getStorageWrapperInformation( + SelectedOverload resolvedOverload) { + return getPropertyWrapperInformationFromOverload( + resolvedOverload, DC, + [](VarDecl *decl) -> Optional> { + if (!decl->hasAttachedPropertyWrapper()) + return None; + + auto storageWrapper = decl->getPropertyWrapperStorageWrapper(); + if (!storageWrapper) + return None; + + return std::make_pair(storageWrapper, + storageWrapper->getInterfaceType()); + }); +} + +Optional> +ConstraintSystem::getPropertyWrapperInformation( + SelectedOverload resolvedOverload) { + return getPropertyWrapperInformationFromOverload( + resolvedOverload, DC, + [](VarDecl *decl) -> Optional> { + if (!decl->hasAttachedPropertyWrapper()) + return None; + + return std::make_pair(decl, + decl->getPropertyWrapperBackingPropertyType()); + }); +} + +Optional> +ConstraintSystem::getWrappedPropertyInformation( + SelectedOverload resolvedOverload) { + return getPropertyWrapperInformationFromOverload( + resolvedOverload, DC, + [](VarDecl *decl) -> Optional> { + if (auto wrapped = decl->getOriginalWrappedProperty()) + return std::make_pair(decl, wrapped->getInterfaceType()); + + return None; + }); +} + /// Does a var or subscript produce an l-value? /// /// \param baseType - the type of the base on which this object diff --git a/lib/Sema/ConstraintSystem.h b/lib/Sema/ConstraintSystem.h index 28b68e4779354..c74685f997e42 100644 --- a/lib/Sema/ConstraintSystem.h +++ b/lib/Sema/ConstraintSystem.h @@ -3080,62 +3080,18 @@ class ConstraintSystem { /// Gets the VarDecl associateed with resolvedOverload, and the type of the /// storage wrapper if the decl has an associated storage wrapper. Optional> - getStorageWrapperInformation(SelectedOverload resolvedOverload) { - if (resolvedOverload.choice.isDecl()) { - if (auto *decl = dyn_cast(resolvedOverload.choice.getDecl())) { - if (decl->hasAttachedPropertyWrapper()) { - if (auto storageWrapper = decl->getPropertyWrapperStorageWrapper()) { - Type type = storageWrapper->getInterfaceType(); - if (Type baseType = resolvedOverload.choice.getBaseType()) { - type = baseType->getTypeOfMember(DC->getParentModule(), - storageWrapper, type); - } - return std::make_pair(decl, type); - } - } - } - } - return None; - } + getStorageWrapperInformation(SelectedOverload resolvedOverload); /// Gets the VarDecl associateed with resolvedOverload, and the type of the /// backing storage if the decl has an associated property wrapper. Optional> - getPropertyWrapperInformation(SelectedOverload resolvedOverload) { - if (resolvedOverload.choice.isDecl()) { - if (auto *decl = dyn_cast(resolvedOverload.choice.getDecl())) { - if (decl->hasAttachedPropertyWrapper()) { - auto wrapperTy = decl->getPropertyWrapperBackingPropertyType(); - if (Type baseType = resolvedOverload.choice.getBaseType()) { - wrapperTy = baseType->getTypeOfMember(DC->getParentModule(), - decl, wrapperTy); - } - return std::make_pair(decl, wrapperTy); - } - } - } - return None; - } + getPropertyWrapperInformation(SelectedOverload resolvedOverload); /// Gets the VarDecl, and the type of the type property that it wraps if /// resolved overload has a decl which is the backing storage for a /// property wrapper. Optional> - getWrappedPropertyInformation(SelectedOverload resolvedOverload) { - if (resolvedOverload.choice.isDecl()) { - if (auto *decl = dyn_cast(resolvedOverload.choice.getDecl())) { - if (auto wrapped = decl->getOriginalWrappedProperty()) { - Type type = wrapped->getInterfaceType(); - if (Type baseType = resolvedOverload.choice.getBaseType()) { - type = baseType->getTypeOfMember(DC->getParentModule(), - wrapped, type); - } - return std::make_pair(decl, type); - } - } - } - return None; - } + getWrappedPropertyInformation(SelectedOverload resolvedOverload); /// Merge the equivalence sets of the two type variables. ///