Skip to content

Commit 2e03264

Browse files
authored
Merge pull request #33842 from xedin/rdar-68254165-followup
[ConstraintSystem] Record `unable to infer base` only if hole origina…
2 parents ed30712 + 79a2ab0 commit 2e03264

File tree

3 files changed

+69
-29
lines changed

3 files changed

+69
-29
lines changed

lib/Sema/CSSimplify.cpp

Lines changed: 68 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -6966,6 +6966,24 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyMemberConstraint(
69666966

69676967
auto locator = getConstraintLocator(locatorB);
69686968

6969+
auto formUnsolved = [&](bool activate = false) {
6970+
// If requested, generate a constraint.
6971+
if (flags.contains(TMF_GenerateConstraints)) {
6972+
auto *memberRef = Constraint::createMemberOrOuterDisjunction(
6973+
*this, kind, baseTy, memberTy, member, useDC, functionRefKind,
6974+
outerAlternatives, locator);
6975+
6976+
addUnsolvedConstraint(memberRef);
6977+
6978+
if (activate)
6979+
activateConstraint(memberRef);
6980+
6981+
return SolutionKind::Solved;
6982+
}
6983+
6984+
return SolutionKind::Unsolved;
6985+
};
6986+
69696987
// If the base type of this member lookup is a "hole" there is no
69706988
// reason to perform a lookup because it wouldn't return any results.
69716989
if (shouldAttemptFixes()) {
@@ -6977,15 +6995,57 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyMemberConstraint(
69776995
// If this is an unresolved member ref e.g. `.foo` and its contextual base
69786996
// type has been determined to be a "hole", let's mark the resulting member
69796997
// type as a potential hole and continue solving.
6980-
if (kind == ConstraintKind::UnresolvedValueMember &&
6981-
baseObjTy->getMetatypeInstanceType()->isHole()) {
6982-
auto *fix =
6983-
SpecifyBaseTypeForContextualMember::create(*this, member, locator);
6984-
if (recordFix(fix))
6985-
return SolutionKind::Error;
6998+
if (kind == ConstraintKind::UnresolvedValueMember) {
6999+
// Let's look through all metatypes to find "underlying" type
7000+
// of this lookup.
7001+
Type underlyingType = baseObjTy;
7002+
while (auto *MT = underlyingType->getAs<AnyMetatypeType>()) {
7003+
underlyingType = MT->getInstanceType();
7004+
}
7005+
7006+
// Let's delay solving this constraint in diagnostic
7007+
// mode until it's certain that there is no way to
7008+
// find out what the base type is.
7009+
if (underlyingType->isTypeVariableOrMember())
7010+
return formUnsolved();
69867011

6987-
markMemberTypeAsPotentialHole(memberTy);
6988-
return SolutionKind::Solved;
7012+
// Let's record a fix only if the hole originates either
7013+
// at the result of the chain (that could happen since solving
7014+
// of this constraint is delayed until base could be resolved),
7015+
// or it is certain that base type can't be bound to any other
7016+
// type but a hole.
7017+
auto shouldRecordFixForHole = [&](HoleType *baseType) {
7018+
auto *originator =
7019+
baseType->getOriginatorType().dyn_cast<TypeVariableType *>();
7020+
7021+
if (!originator)
7022+
return false;
7023+
7024+
auto *originatorLoc = originator->getImpl().getLocator();
7025+
7026+
// It could either be a hole associated directly with the base
7027+
// or a hole which came from result type of the chain.
7028+
if (originatorLoc->isLastElement<
7029+
LocatorPathElt::UnresolvedMemberChainResult>()) {
7030+
auto *UMCR = castToExpr<UnresolvedMemberChainResultExpr>(
7031+
originatorLoc->getAnchor());
7032+
return UMCR->getChainBase() == getAsExpr(locator->getAnchor());
7033+
}
7034+
7035+
return originatorLoc == locator;
7036+
};
7037+
7038+
if (auto *hole = underlyingType->getAs<HoleType>()) {
7039+
if (shouldRecordFixForHole(hole)) {
7040+
auto *fix = SpecifyBaseTypeForContextualMember::create(*this, member,
7041+
locator);
7042+
if (recordFix(fix))
7043+
return SolutionKind::Error;
7044+
}
7045+
7046+
markMemberTypeAsPotentialHole(memberTy);
7047+
return SolutionKind::Solved;
7048+
}
69897049
} else if ((kind == ConstraintKind::ValueMember ||
69907050
kind == ConstraintKind::ValueWitness) &&
69917051
baseObjTy->getMetatypeInstanceType()->isHole()) {
@@ -7000,24 +7060,6 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyMemberConstraint(
70007060
performMemberLookup(kind, member, baseTy, functionRefKind, locator,
70017061
/*includeInaccessibleMembers*/ shouldAttemptFixes());
70027062

7003-
auto formUnsolved = [&](bool activate = false) {
7004-
// If requested, generate a constraint.
7005-
if (flags.contains(TMF_GenerateConstraints)) {
7006-
auto *memberRef = Constraint::createMemberOrOuterDisjunction(
7007-
*this, kind, baseTy, memberTy, member, useDC, functionRefKind,
7008-
outerAlternatives, locator);
7009-
7010-
addUnsolvedConstraint(memberRef);
7011-
7012-
if (activate)
7013-
activateConstraint(memberRef);
7014-
7015-
return SolutionKind::Solved;
7016-
}
7017-
7018-
return SolutionKind::Unsolved;
7019-
};
7020-
70217063
switch (result.OverallResult) {
70227064
case MemberLookupResult::Unsolved:
70237065
return formUnsolved();

test/Constraints/valid_pointer_conversions.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,5 +45,4 @@ SR12382(&i) // expected-error {{cannot convert value of type 'UnsafeMutablePoint
4545
//problem/68254165 - Bad diagnostic when using String init(decodingCString:) with an incorrect pointer type
4646
func rdar68254165(ptr: UnsafeMutablePointer<Int8>) {
4747
_ = String(decodingCString: ptr, as: .utf8) // expected-error {{generic parameter 'Encoding' could not be inferred}}
48-
// expected-error@-1 {{type '_.Type' has no member 'utf8'}}
4948
}

test/decl/enum/enumtest.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,8 +100,7 @@ func test3a(_ a: ZeroOneTwoThree) {
100100
var h = ZeroOneTwoThree(1)
101101

102102
var i = 0 > 3 ? .none : .some(3) // expected-error {{cannot infer contextual base in reference to member 'none'}}
103-
// expected-error@-1 {{cannot infer contextual base in reference to member 'some'}}
104-
103+
105104
test3a; // expected-error {{unused function}}
106105
.Zero // expected-error {{reference to member 'Zero' cannot be resolved without a contextual type}}
107106
test3a // expected-error {{unused function}}

0 commit comments

Comments
 (0)