Skip to content

Commit 76b8209

Browse files
Suyash SrijanSuyash Srijan
authored andcommitted
[cs] store base type and unwrapped type in the fix
1 parent f5264b9 commit 76b8209

File tree

5 files changed

+59
-41
lines changed

5 files changed

+59
-41
lines changed

lib/Sema/CSDiagnostics.cpp

Lines changed: 22 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -510,12 +510,18 @@ class VarDeclMultipleReferencesChecker : public ASTWalker {
510510
int referencesCount() { return count; }
511511
};
512512

513-
static bool diagnoseUnwrap(ConstraintSystem &CS, Expr *expr, Type type) {
514-
Type unwrappedType = type->getOptionalObjectType();
515-
if (!unwrappedType)
513+
static bool diagnoseUnwrap(ConstraintSystem &CS, Expr *expr, Type baseType,
514+
Type unwrappedType) {
515+
516+
assert(!baseType->hasTypeVariable() &&
517+
"Base type must not be a type variable");
518+
assert(!unwrappedType->hasTypeVariable() &&
519+
"Unwrapped type must not be a type variable");
520+
521+
if (baseType && !baseType->getOptionalObjectType())
516522
return false;
517523

518-
CS.TC.diagnose(expr->getLoc(), diag::optional_not_unwrapped, type,
524+
CS.TC.diagnose(expr->getLoc(), diag::optional_not_unwrapped, baseType,
519525
unwrappedType);
520526

521527
// If the expression we're unwrapping is the only reference to a
@@ -541,7 +547,8 @@ static bool diagnoseUnwrap(ConstraintSystem &CS, Expr *expr, Type type) {
541547
Expr *initializer = varDecl->getParentInitializer();
542548
if (auto declRefExpr = dyn_cast<DeclRefExpr>(initializer)) {
543549
if (declRefExpr->getDecl()->getAttrs().hasAttribute<ImplicitlyUnwrappedOptionalAttr>()) {
544-
CS.TC.diagnose(declRefExpr->getLoc(), diag::unwrap_iuo_initializer, type);
550+
CS.TC.diagnose(declRefExpr->getLoc(), diag::unwrap_iuo_initializer,
551+
baseType);
545552
}
546553
}
547554

@@ -580,25 +587,17 @@ bool MissingOptionalUnwrapFailure::diagnoseAsError() {
580587
anchor = assignExpr->getSrc();
581588

582589
auto *unwrapped = anchor->getValueProvidingExpr();
583-
Type type = [&] {
584-
// The anchor could be pointing to an OptionalEvaluationExpr, with the sub
585-
// expression being a CallExpr, UnresolvedDotExpr, etc which could produce
586-
// an >= 1 optional, so let's return the type of the sub expression.
587-
if (auto OEE = dyn_cast<OptionalEvaluationExpr>(anchor)) {
588-
if (auto subTy = getType(OEE->getSubExpr())) {
589-
if (!subTy->hasLValueType() && subTy->getOptionalObjectType()) {
590-
return subTy->getRValueType();
591-
}
592-
}
593-
}
594-
// Just return the type of the anchor
595-
return getType(anchor)->getRValueType();
596-
}();
597-
590+
Type type = getType(anchor)->getRValueType();
591+
598592
auto *tryExpr = dyn_cast<OptionalTryExpr>(unwrapped);
599-
if (!tryExpr)
600-
return diagnoseUnwrap(getConstraintSystem(), unwrapped, type);
601-
593+
if (!tryExpr) {
594+
auto resolvedBaseTy = BaseType ? resolveType(BaseType) : BaseType;
595+
auto resolvedUnwrappedTy =
596+
UnwrappedType ? resolveType(UnwrappedType) : UnwrappedType;
597+
return diagnoseUnwrap(getConstraintSystem(), unwrapped, resolvedBaseTy,
598+
resolvedUnwrappedTy);
599+
}
600+
602601
bool isSwift5OrGreater = getTypeChecker().getLangOpts().isSwiftVersionAtLeast(5);
603602
auto subExprType = getType(tryExpr->getSubExpr());
604603
bool subExpressionIsOptional = (bool)subExprType->getOptionalObjectType();

lib/Sema/CSDiagnostics.h

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -480,10 +480,14 @@ class MemberAccessOnOptionalBaseFailure final : public FailureDiagnostic {
480480
/// Diagnose failures related to use of the unwrapped optional types,
481481
/// which require some type of force-unwrap e.g. "!" or "try!".
482482
class MissingOptionalUnwrapFailure final : public FailureDiagnostic {
483+
Type BaseType;
484+
Type UnwrappedType;
485+
483486
public:
484-
MissingOptionalUnwrapFailure(Expr *expr, ConstraintSystem &cs,
485-
ConstraintLocator *locator)
486-
: FailureDiagnostic(expr, cs, locator) {}
487+
MissingOptionalUnwrapFailure(Expr *expr, ConstraintSystem &cs, Type baseType,
488+
Type unwrappedType, ConstraintLocator *locator)
489+
: FailureDiagnostic(expr, cs, locator), BaseType(baseType),
490+
UnwrappedType(unwrappedType) {}
487491

488492
bool diagnoseAsError() override;
489493
};

lib/Sema/CSFix.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,14 +65,16 @@ ForceDowncast *ForceDowncast::create(ConstraintSystem &cs, Type toType,
6565
}
6666

6767
bool ForceOptional::diagnose(Expr *root, bool asNote) const {
68-
MissingOptionalUnwrapFailure failure(root, getConstraintSystem(),
69-
getLocator());
68+
MissingOptionalUnwrapFailure failure(root, getConstraintSystem(), BaseType,
69+
UnwrappedType, getLocator());
7070
return failure.diagnose(asNote);
7171
}
7272

73-
ForceOptional *ForceOptional::create(ConstraintSystem &cs,
73+
ForceOptional *ForceOptional::create(ConstraintSystem &cs, Type baseType,
74+
Type unwrappedType,
7475
ConstraintLocator *locator) {
75-
return new (cs.getAllocator()) ForceOptional(cs, locator);
76+
return new (cs.getAllocator())
77+
ForceOptional(cs, baseType, unwrappedType, locator);
7678
}
7779

7880
bool UnwrapOptionalBase::diagnose(Expr *root, bool asNote) const {

lib/Sema/CSFix.h

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -166,16 +166,21 @@ class ForceDowncast final : public ConstraintFix {
166166

167167
/// Introduce a '!' to force an optional unwrap.
168168
class ForceOptional final : public ConstraintFix {
169-
ForceOptional(ConstraintSystem &cs, ConstraintLocator *locator)
170-
: ConstraintFix(cs, FixKind::ForceOptional, locator) {}
169+
Type BaseType;
170+
Type UnwrappedType;
171+
172+
ForceOptional(ConstraintSystem &cs, Type baseType, Type unwrappedType,
173+
ConstraintLocator *locator)
174+
: ConstraintFix(cs, FixKind::ForceOptional, locator), BaseType(baseType),
175+
UnwrappedType(unwrappedType) {}
171176

172177
public:
173178
std::string getName() const override { return "force optional"; }
174179

175180
bool diagnose(Expr *root, bool asNote = false) const override;
176181

177-
static ForceOptional *create(ConstraintSystem &cs,
178-
ConstraintLocator *locator);
182+
static ForceOptional *create(ConstraintSystem &cs, Type baseType,
183+
Type unwrappedType, ConstraintLocator *locator);
179184
};
180185

181186
/// Unwrap an optional base when we have a member access.

lib/Sema/CSSimplify.cpp

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2390,11 +2390,11 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
23902390
forceUnwrapPossible = false;
23912391
}
23922392
}
2393-
23942393

23952394
if (forceUnwrapPossible) {
2396-
conversionsOrFixes.push_back(
2397-
ForceOptional::create(*this, getConstraintLocator(locator)));
2395+
conversionsOrFixes.push_back(ForceOptional::create(
2396+
*this, objectType1, objectType1->getOptionalObjectType(),
2397+
getConstraintLocator(locator)));
23982398
}
23992399
}
24002400

@@ -2743,7 +2743,8 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyConformsToConstraint(
27432743
locator.withPathElement(LocatorPathElt::getGenericArgument(0)),
27442744
subflags);
27452745
if (result == SolutionKind::Solved) {
2746-
auto *fix = ForceOptional::create(*this, getConstraintLocator(locator));
2746+
auto *fix = ForceOptional::create(*this, type, optionalObjectType,
2747+
getConstraintLocator(locator));
27472748
if (recordFix(fix)) {
27482749
return SolutionKind::Error;
27492750
}
@@ -2996,6 +2997,7 @@ ConstraintSystem::simplifyFunctionComponentConstraint(
29962997
TypeMatchOptions flags,
29972998
ConstraintLocatorBuilder locator) {
29982999
auto simplified = simplifyType(first);
3000+
auto simplifiedCopy = simplified;
29993001

30003002
unsigned unwrapCount = 0;
30013003
if (shouldAttemptFixes()) {
@@ -3038,7 +3040,9 @@ ConstraintSystem::simplifyFunctionComponentConstraint(
30383040
}
30393041

30403042
if (unwrapCount > 0) {
3041-
auto *fix = ForceOptional::create(*this, getConstraintLocator(locator));
3043+
auto *fix = ForceOptional::create(*this, simplifiedCopy,
3044+
simplifiedCopy->getOptionalObjectType(),
3045+
getConstraintLocator(locator));
30423046
while (unwrapCount-- > 0) {
30433047
if (recordFix(fix))
30443048
return SolutionKind::Error;
@@ -4662,7 +4666,9 @@ ConstraintSystem::simplifyApplicableFnConstraint(
46624666
return SolutionKind::Error;
46634667

46644668
// Record any fixes we attempted to get to the correct solution.
4665-
auto *fix = ForceOptional::create(*this, getConstraintLocator(locator));
4669+
auto *fix = ForceOptional::create(*this, origType2,
4670+
origType2->getOptionalObjectType(),
4671+
getConstraintLocator(locator));
46664672
while (unwrapCount-- > 0) {
46674673
if (recordFix(fix))
46684674
return SolutionKind::Error;
@@ -4685,7 +4691,9 @@ ConstraintSystem::simplifyApplicableFnConstraint(
46854691

46864692
// Record any fixes we attempted to get to the correct solution.
46874693
if (simplified == SolutionKind::Solved) {
4688-
auto *fix = ForceOptional::create(*this, getConstraintLocator(locator));
4694+
auto *fix = ForceOptional::create(*this, origType2,
4695+
origType2->getOptionalObjectType(),
4696+
getConstraintLocator(locator));
46894697
while (unwrapCount-- > 0) {
46904698
if (recordFix(fix))
46914699
return SolutionKind::Error;

0 commit comments

Comments
 (0)