@@ -2967,101 +2967,118 @@ namespace {
29672967 }
29682968}
29692969
2970- ConstraintSystem::TypeMatchResult
2971- ConstraintSystem::matchFunctionTypes(FunctionType *func1, FunctionType *func2,
2972- ConstraintKind kind, TypeMatchOptions flags,
2973- ConstraintLocatorBuilder locator) {
2970+ /// Match the throwing specifier of the two function types.
2971+ static ConstraintSystem::TypeMatchResult
2972+ matchFunctionThrowing(ConstraintSystem &cs,
2973+ FunctionType *func1, FunctionType *func2,
2974+ ConstraintKind kind,
2975+ ConstraintSystem::TypeMatchOptions flags,
2976+ ConstraintLocatorBuilder locator) {
29742977 // A function type that throws the error type E1 is a subtype of a function
29752978 // that throws error type E2 when E1 is a subtype of E2. For the purpose
29762979 // of this comparison, a non-throwing function has thrown error type 'Never',
29772980 // and an untyped throwing function has thrown error type 'any Error'.
2978- Type neverType = getASTContext().getNeverType();
2981+ Type neverType = cs. getASTContext().getNeverType();
29792982 Type thrownError1 = func1->getEffectiveThrownInterfaceType().value_or(neverType);
29802983 Type thrownError2 = func2->getEffectiveThrownInterfaceType().value_or(neverType);
2981- if (thrownError1 && thrownError2 && !thrownError1->isEqual(thrownError2)) {
2982- auto thrownErrorKind1 = getThrownErrorKind(thrownError1);
2983- auto thrownErrorKind2 = getThrownErrorKind(thrownError2);
2984-
2985- bool mustUnify = false;
2986- bool dropThrows = false;
2984+ if (!thrownError1 || !thrownError2 || thrownError1->isEqual(thrownError2))
2985+ return cs.getTypeMatchSuccess();
2986+
2987+ auto thrownErrorKind1 = getThrownErrorKind(thrownError1);
2988+ auto thrownErrorKind2 = getThrownErrorKind(thrownError2);
2989+
2990+ bool mustUnify = false;
2991+ bool dropThrows = false;
2992+
2993+ switch (thrownErrorKind1) {
2994+ case ThrownErrorKind::Specific:
2995+ // If the specific thrown error contains no type variables and we're
2996+ // going to try to convert it to \c Never, treat this as dropping throws.
2997+ if (thrownErrorKind2 == ThrownErrorKind::Never &&
2998+ !thrownError1->hasTypeVariable()) {
2999+ dropThrows = true;
3000+ } else {
3001+ // We need to unify the thrown error types.
3002+ mustUnify = true;
3003+ }
3004+ break;
29873005
2988- switch (thrownErrorKind1) {
3006+ case ThrownErrorKind::Never:
3007+ switch (thrownErrorKind2) {
29893008 case ThrownErrorKind::Specific:
2990- // If the specific thrown error contains no type variables and we're
2991- // going to try to convert it to \c Never, treat this as dropping throws.
2992- if (thrownErrorKind2 == ThrownErrorKind::Never &&
2993- !thrownError1->hasTypeVariable()) {
2994- dropThrows = true;
2995- } else {
2996- // We need to unify the thrown error types.
2997- mustUnify = true;
2998- }
3009+ // We need to unify the thrown error types.
3010+ mustUnify = true;
29993011 break;
30003012
30013013 case ThrownErrorKind::Never:
3002- switch (thrownErrorKind2) {
3003- case ThrownErrorKind::Specific:
3004- // We need to unify the thrown error types.
3005- mustUnify = true;
3006- break;
3007-
3008- case ThrownErrorKind::Never:
3009- llvm_unreachable("The thrown error types should have been equal");
3010- break;
3011-
3012- case ThrownErrorKind::AnyError:
3013- // We have a subtype. If we're not allowed to do the subtype,
3014- // then we need to drop "throws".
3015- if (kind < ConstraintKind::Subtype)
3016- dropThrows = true;
3017- break;
3018- }
3014+ llvm_unreachable("The thrown error types should have been equal");
30193015 break;
30203016
30213017 case ThrownErrorKind::AnyError:
3022- switch (thrownErrorKind2) {
3023- case ThrownErrorKind::Specific:
3024- // We need to unify the thrown error types.
3025- mustUnify = true;
3026- break;
3027-
3028- case ThrownErrorKind::Never:
3029- // We're going to have to drop the "throws" entirely.
3018+ // We have a subtype. If we're not allowed to do the subtype,
3019+ // then we need to drop "throws".
3020+ if (kind < ConstraintKind::Subtype)
30303021 dropThrows = true;
3031- break;
3032-
3033- case ThrownErrorKind::AnyError:
3034- llvm_unreachable("The thrown error types should have been equal");
3035- }
30363022 break;
30373023 }
3024+ break;
30383025
3039- // If we know we need to drop 'throws', try it now.
3040- if (dropThrows) {
3041- if (!shouldAttemptFixes())
3042- return getTypeMatchFailure(locator);
3026+ case ThrownErrorKind::AnyError:
3027+ switch (thrownErrorKind2) {
3028+ case ThrownErrorKind::Specific:
3029+ // We need to unify the thrown error types.
3030+ mustUnify = true;
3031+ break;
30433032
3044- auto *fix = DropThrowsAttribute::create(*this, func1, func2,
3045- getConstraintLocator(locator));
3046- if (recordFix(fix))
3047- return getTypeMatchFailure(locator);
3048- }
3033+ case ThrownErrorKind::Never:
3034+ // We're going to have to drop the "throws" entirely.
3035+ dropThrows = true;
3036+ break;
30493037
3050- // If we need to unify the thrown error types, do so now.
3051- if (mustUnify) {
3052- ConstraintKind subKind = (kind < ConstraintKind::Subtype)
3053- ? ConstraintKind::Equal
3054- : ConstraintKind::Subtype;
3055- const auto subflags = getDefaultDecompositionOptions(flags);
3056- auto result = matchTypes(
3057- thrownError1, thrownError2,
3058- subKind, subflags,
3059- locator.withPathElement(LocatorPathElt::ThrownErrorType()));
3060- if (result == SolutionKind::Error)
3061- return getTypeMatchFailure(locator);
3038+ case ThrownErrorKind::AnyError:
3039+ llvm_unreachable("The thrown error types should have been equal");
30623040 }
3041+ break;
30633042 }
30643043
3044+ // If we know we need to drop 'throws', try it now.
3045+ if (dropThrows) {
3046+ if (!cs.shouldAttemptFixes())
3047+ return cs.getTypeMatchFailure(locator);
3048+
3049+ auto *fix = DropThrowsAttribute::create(cs, func1, func2,
3050+ cs.getConstraintLocator(locator));
3051+ if (cs.recordFix(fix))
3052+ return cs.getTypeMatchFailure(locator);
3053+ }
3054+
3055+ // If we need to unify the thrown error types, do so now.
3056+ if (mustUnify) {
3057+ ConstraintKind subKind = (kind < ConstraintKind::Subtype)
3058+ ? ConstraintKind::Equal
3059+ : ConstraintKind::Subtype;
3060+ const auto subflags = getDefaultDecompositionOptions(flags);
3061+ auto result = cs.matchTypes(
3062+ thrownError1, thrownError2,
3063+ subKind, subflags,
3064+ locator.withPathElement(LocatorPathElt::ThrownErrorType()));
3065+ if (result == ConstraintSystem::SolutionKind::Error)
3066+ return cs.getTypeMatchFailure(locator);
3067+ }
3068+
3069+ return cs.getTypeMatchSuccess();
3070+ }
3071+
3072+ ConstraintSystem::TypeMatchResult
3073+ ConstraintSystem::matchFunctionTypes(FunctionType *func1, FunctionType *func2,
3074+ ConstraintKind kind, TypeMatchOptions flags,
3075+ ConstraintLocatorBuilder locator) {
3076+ // Match the 'throws' effect.
3077+ TypeMatchResult throwsResult =
3078+ matchFunctionThrowing(*this, func1, func2, kind, flags, locator);
3079+ if (throwsResult.isFailure())
3080+ return throwsResult;
3081+
30653082 // A synchronous function can be a subtype of an 'async' function.
30663083 if (func1->isAsync() != func2->isAsync()) {
30673084 // Cannot drop 'async'.
@@ -15105,10 +15122,12 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyFixConstraint(
1510515122 case FixKind::AllowAssociatedValueMismatch:
1510615123 case FixKind::GenericArgumentsMismatch:
1510715124 case FixKind::AllowConcreteTypeSpecialization:
15108- case FixKind::IgnoreThrownErrorMismatch:
1510915125 case FixKind::IgnoreGenericSpecializationArityMismatch: {
1511015126 return recordFix(fix) ? SolutionKind::Error : SolutionKind::Solved;
1511115127 }
15128+ case FixKind::IgnoreThrownErrorMismatch: {
15129+ return recordFix(fix, 2) ? SolutionKind::Error : SolutionKind::Solved;
15130+ }
1511215131 case FixKind::IgnoreInvalidASTNode: {
1511315132 return recordFix(fix, 10) ? SolutionKind::Error : SolutionKind::Solved;
1511415133 }
0 commit comments