@@ -2596,6 +2596,15 @@ repairViaOptionalUnwrap(ConstraintSystem &cs, Type fromType, Type toType,
2596
2596
if (!anchor)
2597
2597
return false ;
2598
2598
2599
+ bool possibleContextualMismatch = false ;
2600
+ // If this is a conversion to a non-optional contextual type e.g.
2601
+ // `let _: Bool = try? foo()` and `foo()` produces `Int`
2602
+ // we should diagnose it as type mismatch instead of missing unwrap.
2603
+ if (auto last = locator.last ()) {
2604
+ possibleContextualMismatch = last->is <LocatorPathElt::ContextualType>() &&
2605
+ !toType->getOptionalObjectType ();
2606
+ }
2607
+
2599
2608
// `OptionalEvaluationExpr` doesn't add a new level of
2600
2609
// optionality but it could be hiding concrete types
2601
2610
// behind itself which we can use to better understand
@@ -2612,7 +2621,12 @@ repairViaOptionalUnwrap(ConstraintSystem &cs, Type fromType, Type toType,
2612
2621
// other type e.g. contextual type or a parameter type,
2613
2622
// let's use `Bind` to match object types because
2614
2623
// object type of the optinal chain is a type variable.
2615
- if (matchKind >= ConstraintKind::Conversion)
2624
+ //
2625
+ // One exception is contextual conversion - in such cases
2626
+ // let's give optional chain a chance to infer its inner type
2627
+ // first, that makes it much easier to diagnose contextual
2628
+ // mismatch vs. missing optional unwrap.
2629
+ if (!possibleContextualMismatch && matchKind >= ConstraintKind::Conversion)
2616
2630
matchKind = ConstraintKind::Bind;
2617
2631
}
2618
2632
@@ -2644,13 +2658,12 @@ repairViaOptionalUnwrap(ConstraintSystem &cs, Type fromType, Type toType,
2644
2658
// language mode, so we can safely try to bind its
2645
2659
// object type to contextual type without risk of
2646
2660
// causing more optionality mismatches down the road.
2647
- auto last = locator. last ();
2661
+ //
2648
2662
// For contextual conversions let's give `try?` a chance to
2649
2663
// infer inner type which, if incorrect, should result in
2650
2664
// contextual conversion failure instead of optional unwrap.
2651
- matchKind = last && last->is <LocatorPathElt::ContextualType>()
2652
- ? ConstraintKind::Conversion
2653
- : ConstraintKind::Bind;
2665
+ matchKind = possibleContextualMismatch ? ConstraintKind::Conversion
2666
+ : ConstraintKind::Bind;
2654
2667
}
2655
2668
}
2656
2669
0 commit comments