Skip to content

Commit b747462

Browse files
authored
Merge pull request swiftlang#22151 from xedin/small-cleanups-for-sr-9201
[CSFix] Couple of small cleanups related to ForceOptional
2 parents bcc7588 + 1c79380 commit b747462

File tree

8 files changed

+53
-32
lines changed

8 files changed

+53
-32
lines changed

lib/Sema/CSDiagnostics.cpp

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -518,7 +518,7 @@ static bool diagnoseUnwrap(ConstraintSystem &CS, Expr *expr, Type baseType,
518518
assert(!unwrappedType->hasTypeVariable() &&
519519
"Unwrapped type must not be a type variable");
520520

521-
if (baseType && !baseType->getOptionalObjectType())
521+
if (!baseType->getOptionalObjectType())
522522
return false;
523523

524524
CS.TC.diagnose(expr->getLoc(), diag::optional_not_unwrapped, baseType,
@@ -587,16 +587,12 @@ bool MissingOptionalUnwrapFailure::diagnoseAsError() {
587587
anchor = assignExpr->getSrc();
588588

589589
auto *unwrapped = anchor->getValueProvidingExpr();
590-
Type type = getType(anchor)->getRValueType();
590+
auto type = getType(anchor)->getRValueType();
591591

592592
auto *tryExpr = dyn_cast<OptionalTryExpr>(unwrapped);
593593
if (!tryExpr) {
594-
auto resolvedBaseTy =
595-
resolveType(BaseType)->reconstituteSugar(/*recursive=*/true);
596-
auto resolvedUnwrappedTy =
597-
resolveType(UnwrappedType)->reconstituteSugar(/*recursive=*/true);
598-
return diagnoseUnwrap(getConstraintSystem(), unwrapped, resolvedBaseTy,
599-
resolvedUnwrappedTy);
594+
return diagnoseUnwrap(getConstraintSystem(), unwrapped, getBaseType(),
595+
getUnwrappedType());
600596
}
601597

602598
bool isSwift5OrGreater = getTypeChecker().getLangOpts().isSwiftVersionAtLeast(5);
@@ -609,11 +605,10 @@ bool MissingOptionalUnwrapFailure::diagnoseAsError() {
609605
// under Swift 5+, so just report that a missing unwrap can't be handled here.
610606
return false;
611607
}
612-
else {
613-
emitDiagnostic(tryExpr->getTryLoc(), diag::missing_unwrap_optional_try, type)
614-
.fixItReplace({tryExpr->getTryLoc(), tryExpr->getQuestionLoc()}, "try!");
615-
return true;
616-
}
608+
609+
emitDiagnostic(tryExpr->getTryLoc(), diag::missing_unwrap_optional_try, type)
610+
.fixItReplace({tryExpr->getTryLoc(), tryExpr->getQuestionLoc()}, "try!");
611+
return true;
617612
}
618613

619614
bool RValueTreatedAsLValueFailure::diagnoseAsError() {

lib/Sema/CSDiagnostics.h

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,11 @@ class FailureDiagnostic {
9191
Type getType(Expr *expr) const;
9292

9393
/// Resolve type variables present in the raw type, if any.
94-
Type resolveType(Type rawType) const {
95-
return CS.simplifyType(rawType);
94+
Type resolveType(Type rawType, bool reconstituteSugar = false) const {
95+
auto resolvedType = CS.simplifyType(rawType);
96+
return reconstituteSugar
97+
? resolvedType->reconstituteSugar(/*recursive*/ true)
98+
: resolvedType;
9699
}
97100

98101
template <typename... ArgTypes>
@@ -490,6 +493,15 @@ class MissingOptionalUnwrapFailure final : public FailureDiagnostic {
490493
UnwrappedType(unwrappedType) {}
491494

492495
bool diagnoseAsError() override;
496+
497+
private:
498+
Type getBaseType() const {
499+
return resolveType(BaseType, /*reconstituteSugar=*/true);
500+
}
501+
502+
Type getUnwrappedType() const {
503+
return resolveType(UnwrappedType, /*reconstituteSugar=*/true);
504+
}
493505
};
494506

495507
/// Diagnose errors associated with rvalues in positions

lib/Sema/CSFix.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,10 @@ class ForceOptional final : public ConstraintFix {
172172
ForceOptional(ConstraintSystem &cs, Type baseType, Type unwrappedType,
173173
ConstraintLocator *locator)
174174
: ConstraintFix(cs, FixKind::ForceOptional, locator), BaseType(baseType),
175-
UnwrappedType(unwrappedType) {}
175+
UnwrappedType(unwrappedType) {
176+
assert(baseType && "Base type must not be null");
177+
assert(unwrappedType && "Unwrapped type must not be null");
178+
}
176179

177180
public:
178181
std::string getName() const override { return "force optional"; }

lib/Sema/CSSimplify.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4665,6 +4665,9 @@ ConstraintSystem::simplifyApplicableFnConstraint(
46654665
ConstraintLocator::FunctionResult)).isFailure())
46664666
return SolutionKind::Error;
46674667

4668+
if (unwrapCount == 0)
4669+
return SolutionKind::Solved;
4670+
46684671
// Record any fixes we attempted to get to the correct solution.
46694672
auto *fix = ForceOptional::create(*this, origType2,
46704673
origType2->getOptionalObjectType(),
@@ -4691,6 +4694,9 @@ ConstraintSystem::simplifyApplicableFnConstraint(
46914694

46924695
// Record any fixes we attempted to get to the correct solution.
46934696
if (simplified == SolutionKind::Solved) {
4697+
if (unwrapCount == 0)
4698+
return SolutionKind::Solved;
4699+
46944700
auto *fix = ForceOptional::create(*this, origType2,
46954701
origType2->getOptionalObjectType(),
46964702
getConstraintLocator(locator));

test/Constraints/fixes.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -286,4 +286,4 @@ let _: Int = thing?.e?.a() // expected-error {{value of optional type 'Int?' mus
286286
// expected-note@-2{{force-unwrap}}
287287
let _: Int? = thing?.e?.b // expected-error {{value of optional type 'Int??' must be unwrapped to a value of type 'Int?'}}
288288
// expected-note@-1{{coalesce}}
289-
// expected-note@-2{{force-unwrap}}
289+
// expected-note@-2{{force-unwrap}}

test/Constraints/patterns.swift

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -291,9 +291,10 @@ switch staticMembers {
291291
case .init(0): break
292292
case .init(_): break // expected-error{{'_' can only appear in a pattern}}
293293
case .init(let x): break // expected-error{{cannot appear in an expression}}
294-
case .init(opt: 0): break // expected-error{{value of optional type 'StaticMembers?' must be unwrapped to a value of type 'StaticMembers'}}
295-
// expected-note@-1{{coalesce}}
296-
// expected-note@-2{{force-unwrap}}
294+
case .init(opt: 0): break
295+
// expected-error@-1 {{value of optional type 'StaticMembers?' must be unwrapped to a value of type 'StaticMembers'}}
296+
// expected-note@-2 {{coalesce}}
297+
// expected-note@-3 {{force-unwrap}}
297298

298299
case .prop: break
299300
// TODO: repeated error message
@@ -310,9 +311,10 @@ switch staticMembers {
310311
case .method(withLabel: let x): break // expected-error{{cannot appear in an expression}}
311312

312313
case .optMethod: break // expected-error{{cannot match}}
313-
case .optMethod(0): break // expected-error{{value of optional type 'StaticMembers?' must be unwrapped to a value of type 'StaticMembers'}}
314-
// expected-note@-1{{coalesce}}
315-
// expected-note@-2{{force-unwrap}}
314+
case .optMethod(0): break
315+
// expected-error@-1 {{value of optional type 'StaticMembers?' must be unwrapped to a value of type 'StaticMembers'}}
316+
// expected-note@-2 {{coalesce}}
317+
// expected-note@-3 {{force-unwrap}}
316318
}
317319

318320
_ = 0

test/expr/delayed-ident/static_var.swift

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,8 @@ struct HasClosure {
4646
var _: HasClosure = .factoryNormal(0)
4747
var _: HasClosure = .factoryReturnOpt(1)!
4848
var _: HasClosure = .factoryIUO(2)
49-
var _: HasClosure = .factoryOpt(3) // expected-error {{value of optional type '((Int) -> HasClosure)?' must be unwrapped to a value of type '(Int) -> HasClosure'}}
50-
// expected-note@-1{{coalesce}}
51-
// expected-note@-2{{force-unwrap}}
49+
var _: HasClosure = .factoryOpt(3)
50+
// expected-error@-1 {{value of optional type '((Int) -> HasClosure)?' must be unwrapped to a value of type '(Int) -> HasClosure'}}
51+
// expected-note@-2 {{coalesce}}
52+
// expected-note@-3 {{force-unwrap}}
5253
var _: HasClosure = .factoryOpt!(4) // expected-error {{type of expression is ambiguous without more context}}

test/expr/postfix/dot/optional_context_member.swift

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,18 +13,20 @@ func nonOptContext() -> Foo {
1313
case ():
1414
return .someVar
1515
case (): // expected-warning {{case is already handled by previous patterns; consider removing it}}
16-
return .someOptVar // expected-error {{value of optional type 'Foo?' must be unwrapped to a value of type 'Foo'}}
17-
// expected-note@-1 {{coalesce}}
18-
// expected-note@-2 {{force-unwrap}}
16+
return .someOptVar
17+
// expected-error@-1 {{value of optional type 'Foo?' must be unwrapped to a value of type 'Foo'}}
18+
// expected-note@-2 {{coalesce}}
19+
// expected-note@-3 {{force-unwrap}}
1920
// TODO
2021
//case ():
2122
// return .someOptVar!
2223
case (): // expected-warning {{case is already handled by previous patterns; consider removing it}}
2324
return .someFunc()
2425
case (): // expected-warning {{case is already handled by previous patterns; consider removing it}}
25-
return .someOptFunc() // expected-error {{value of optional type 'Foo?' must be unwrapped to a value of type 'Foo'}}
26-
// expected-note@-1 {{coalesce}}
27-
// expected-note@-2 {{force-unwrap}}
26+
return .someOptFunc()
27+
// expected-error@-1 {{value of optional type 'Foo?' must be unwrapped to a value of type 'Foo'}}
28+
// expected-note@-2 {{coalesce}}
29+
// expected-note@-3 {{force-unwrap}}
2830
// TODO
2931
//case ():
3032
// return .someOptFunc()!

0 commit comments

Comments
 (0)