Skip to content

Commit 9340705

Browse files
committed
Address code review comments
1 parent 38b004d commit 9340705

File tree

1 file changed

+92
-73
lines changed

1 file changed

+92
-73
lines changed

lib/Sema/CSSimplify.cpp

Lines changed: 92 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)