|
19 | 19 | #include "swift/AST/ASTVisitor.h" |
20 | 20 | #include "swift/AST/ASTWalker.h" |
21 | 21 | #include "swift/AST/Expr.h" |
| 22 | +#include "swift/AST/GenericSignature.h" |
22 | 23 | #include "swift/AST/ParameterList.h" |
23 | 24 | #include "swift/AST/PrettyStackTrace.h" |
24 | 25 | #include "swift/AST/SubstitutionMap.h" |
@@ -3607,41 +3608,70 @@ void ConstraintSystem::optimizeConstraints(Expr *e) { |
3607 | 3608 | e->walk(optimizer); |
3608 | 3609 | } |
3609 | 3610 |
|
3610 | | -bool swift::isExtensionApplied(DeclContext &DC, Type BaseTy, |
3611 | | - const ExtensionDecl *ED) { |
3612 | | - if (!ED->isConstrainedExtension() || |
3613 | | - // We'll crash if we leak type variables from one constraint |
3614 | | - // system into the new one created below. |
3615 | | - BaseTy->hasTypeVariable() || |
3616 | | - // We can't do anything if the base type has unbound generic |
3617 | | - // parameters either. |
3618 | | - BaseTy->hasUnboundGenericType()) |
3619 | | - return true; |
3620 | | - |
3621 | | - TypeChecker *TC = &createTypeChecker(DC.getASTContext()); |
3622 | | - TC->validateExtension(const_cast<ExtensionDecl *>(ED)); |
| 3611 | +static bool areGenericRequirementsSatisfied( |
| 3612 | + const DeclContext *DC, const GenericSignature *sig, |
| 3613 | + const SubstitutionMap &Substitutions, bool isExtension) { |
3623 | 3614 |
|
| 3615 | + TypeChecker &TC = createTypeChecker(DC->getASTContext()); |
3624 | 3616 | ConstraintSystemOptions Options; |
3625 | | - ConstraintSystem CS(*TC, &DC, Options); |
| 3617 | + ConstraintSystem CS(TC, const_cast<DeclContext *>(DC), Options); |
3626 | 3618 | auto Loc = CS.getConstraintLocator(nullptr); |
3627 | 3619 |
|
3628 | | - // Prepare type substitution map. |
3629 | | - SubstitutionMap Substitutions = BaseTy->getContextSubstitutionMap( |
3630 | | - DC.getParentModule(), ED); |
3631 | | - |
3632 | 3620 | // For every requirement, add a constraint. |
3633 | | - for (auto Req : ED->getGenericRequirements()) { |
| 3621 | + for (auto Req : sig->getRequirements()) { |
3634 | 3622 | if (auto resolved = Req.subst(Substitutions)) { |
3635 | 3623 | CS.addConstraint(*resolved, Loc); |
3636 | | - } else { |
| 3624 | + } else if (isExtension) { |
3637 | 3625 | return false; |
3638 | 3626 | } |
| 3627 | + // Unresolved requirements are requirements of the function itself. This |
| 3628 | + // does not prevent it from being applied. E.g. func foo<T: Sequence>(x: T). |
3639 | 3629 | } |
3640 | 3630 |
|
3641 | | - // Having a solution implies the extension's requirements have been fulfilled. |
| 3631 | + // Having a solution implies the requirements have been fulfilled. |
3642 | 3632 | return CS.solveSingle().hasValue(); |
3643 | 3633 | } |
3644 | 3634 |
|
| 3635 | +bool swift::isExtensionApplied(const DeclContext *DC, Type BaseTy, |
| 3636 | + const ExtensionDecl *ED) { |
| 3637 | + // We can't do anything if the base type has unbound generic parameters. |
| 3638 | + // We can't leak type variables into another constraint system. |
| 3639 | + if (BaseTy->hasTypeVariable() || BaseTy->hasUnboundGenericType()) |
| 3640 | + return true; |
| 3641 | + |
| 3642 | + if (!ED->isConstrainedExtension()) |
| 3643 | + return true; |
| 3644 | + |
| 3645 | + TypeChecker *TC = &createTypeChecker(DC->getASTContext()); |
| 3646 | + TC->validateExtension(const_cast<ExtensionDecl *>(ED)); |
| 3647 | + |
| 3648 | + GenericSignature *genericSig = ED->getGenericSignature(); |
| 3649 | + SubstitutionMap substMap = BaseTy->getContextSubstitutionMap( |
| 3650 | + DC->getParentModule(), ED->getExtendedNominal()); |
| 3651 | + return areGenericRequirementsSatisfied(DC, genericSig, substMap, |
| 3652 | + /*isExtension=*/true); |
| 3653 | +} |
| 3654 | + |
| 3655 | +bool swift::isMemberDeclApplied(const DeclContext *DC, Type BaseTy, |
| 3656 | + const ValueDecl *VD) { |
| 3657 | + // We can't leak type variables into another constraint system. |
| 3658 | + // We can't do anything if the base type has unbound generic parameters. |
| 3659 | + if (BaseTy->hasTypeVariable() || BaseTy->hasUnboundGenericType()) |
| 3660 | + return true; |
| 3661 | + |
| 3662 | + const GenericContext *genericDecl = VD->getAsGenericContext(); |
| 3663 | + if (!genericDecl) |
| 3664 | + return true; |
| 3665 | + const GenericSignature *genericSig = genericDecl->getGenericSignature(); |
| 3666 | + if (!genericSig) |
| 3667 | + return true; |
| 3668 | + |
| 3669 | + SubstitutionMap substMap = BaseTy->getContextSubstitutionMap( |
| 3670 | + DC->getParentModule(), VD->getDeclContext()); |
| 3671 | + return areGenericRequirementsSatisfied(DC, genericSig, substMap, |
| 3672 | + /*isExtension=*/false); |
| 3673 | +} |
| 3674 | + |
3645 | 3675 | static bool canSatisfy(Type type1, Type type2, bool openArchetypes, |
3646 | 3676 | ConstraintKind kind, DeclContext *dc) { |
3647 | 3677 | std::unique_ptr<TypeChecker> CreatedTC; |
|
0 commit comments