Skip to content

[ConstraintSystem] Tally implicit optional wraps into impact of point… #32029

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 27, 2020
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 21 additions & 11 deletions lib/Sema/CSSimplify.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8817,14 +8817,15 @@ ConstraintSystem::simplifyRestrictedConstraintImpl(

TypeMatchOptions subflags = getDefaultDecompositionOptions(flags);

auto matchPointerBaseTypes = [&](Type baseType1,
Type baseType2) -> SolutionKind {
auto matchPointerBaseTypes =
[&](llvm::PointerIntPair<Type, 3, unsigned> baseType1,
llvm::PointerIntPair<Type, 3, unsigned> baseType2) -> SolutionKind {
if (restriction != ConversionRestrictionKind::PointerToPointer)
increaseScore(ScoreKind::SK_ValueToPointerConversion);

auto result =
matchTypes(baseType1, baseType2, ConstraintKind::BindToPointerType,
subflags, locator);
matchTypes(baseType1.getPointer(), baseType2.getPointer(),
ConstraintKind::BindToPointerType, subflags, locator);

if (!(result.isFailure() && shouldAttemptFixes()))
return result;
Expand All @@ -8837,13 +8838,14 @@ ConstraintSystem::simplifyRestrictedConstraintImpl(
case ConversionRestrictionKind::InoutToPointer: {
ptr2 = type2->lookThroughAllOptionalTypes()->castTo<BoundGenericType>();
ptr1 = BoundGenericType::get(ptr2->getDecl(), ptr2->getParent(),
{baseType1});
{baseType1.getPointer()});
break;
}

case ConversionRestrictionKind::PointerToPointer:
ptr1 = type1->castTo<BoundGenericType>();
ptr2 = type2->castTo<BoundGenericType>();
// Original types could be wrapped into a different number of optional.
ptr1 = type1->lookThroughAllOptionalTypes()->castTo<BoundGenericType>();
ptr2 = type2->lookThroughAllOptionalTypes()->castTo<BoundGenericType>();
break;

default:
Expand All @@ -8852,7 +8854,15 @@ ConstraintSystem::simplifyRestrictedConstraintImpl(

auto *fix = GenericArgumentsMismatch::create(*this, ptr1, ptr2, {0},
getConstraintLocator(locator));
return recordFix(fix) ? SolutionKind::Error : SolutionKind::Solved;

// It's possible to implicitly promote pointer into an optional
// before matching base types if other side is an optional, so
// score needs to account for number of such promotions.
int optionalWraps = baseType2.getInt() - baseType1.getInt();
return recordFix(fix,
/*impact=*/1 + abs(optionalWraps))
? SolutionKind::Error
: SolutionKind::Solved;
};

auto fixContextualFailure = [&](Type fromType, Type toType,
Expand Down Expand Up @@ -9040,7 +9050,7 @@ ConstraintSystem::simplifyRestrictedConstraintImpl(

increaseScore(SK_ValueToOptional, ptr2.getInt());

return matchPointerBaseTypes(baseType1, ptr2.getPointer());
return matchPointerBaseTypes({baseType1, 0}, ptr2);
}

// String ===> UnsafePointer<[U]Int8>
Expand Down Expand Up @@ -9101,7 +9111,7 @@ ConstraintSystem::simplifyRestrictedConstraintImpl(

increaseScore(SK_ValueToOptional, ptr2.getInt());

return matchPointerBaseTypes(baseType1, ptr2.getPointer());
return matchPointerBaseTypes({baseType1, 0}, ptr2);
}

// T <p U ===> UnsafeMutablePointer<T> <a UnsafeMutablePointer<U>
Expand All @@ -9112,7 +9122,7 @@ ConstraintSystem::simplifyRestrictedConstraintImpl(
auto ptr1 = getBaseTypeForPointer(t1);
auto ptr2 = getBaseTypeForPointer(t2);

return matchPointerBaseTypes(ptr1.getPointer(), ptr2.getPointer());
return matchPointerBaseTypes(ptr1, ptr2);
}

// T < U or T is bridged to V where V < U ===> Array<T> <c Array<U>
Expand Down