Skip to content

Commit 1846a59

Browse files
authored
Merge pull request #27608 from xedin/autoclosure-ctx-mismatch
[Diagnostics] Extend use of argument mismatch fix to `autoclosure` pa…
2 parents db902a1 + f09b07b commit 1846a59

File tree

5 files changed

+44
-10
lines changed

5 files changed

+44
-10
lines changed

lib/Sema/CSSimplify.cpp

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3007,13 +3007,38 @@ bool ConstraintSystem::repairFailures(
30073007
if (repairByInsertingExplicitCall(lhs, rhs))
30083008
return true;
30093009

3010-
auto result = matchTypes(lhs, rhs, ConstraintKind::ArgumentConversion,
3011-
TypeMatchFlags::TMF_ApplyingFix,
3012-
locator.withPathElement(ConstraintLocator::FunctionArgument));
3010+
auto isPointerType = [](Type type) -> bool {
3011+
return bool(
3012+
type->lookThroughAllOptionalTypes()->getAnyPointerElementType());
3013+
};
30133014

3014-
if (result.isSuccess())
3015-
conversionsOrFixes.push_back(AllowAutoClosurePointerConversion::create(
3016-
*this, lhs, rhs, getConstraintLocator(locator)));
3015+
// Let's see whether this is an implicit conversion to a pointer type
3016+
// which is invalid in @autoclosure context e.g. from `inout`, Array
3017+
// or String.
3018+
if (!isPointerType(lhs) && isPointerType(rhs)) {
3019+
auto result = matchTypes(
3020+
lhs, rhs, ConstraintKind::ArgumentConversion,
3021+
TypeMatchFlags::TMF_ApplyingFix,
3022+
locator.withPathElement(ConstraintLocator::FunctionArgument));
3023+
3024+
if (result.isSuccess())
3025+
conversionsOrFixes.push_back(AllowAutoClosurePointerConversion::create(
3026+
*this, lhs, rhs, getConstraintLocator(locator)));
3027+
}
3028+
3029+
// In situations like this:
3030+
//
3031+
// struct S<T> {}
3032+
// func foo(_: @autoclosure () -> S<Int>) {}
3033+
// foo(S<String>())
3034+
//
3035+
// Generic type conversion mismatch is a better fix which is going to
3036+
// point to the generic arguments that did not align properly.
3037+
if (hasConversionOrRestriction(ConversionRestrictionKind::DeepEquality))
3038+
break;
3039+
3040+
conversionsOrFixes.push_back(AllowArgumentMismatch::create(
3041+
*this, lhs, rhs, getConstraintLocator(locator)));
30173042
break;
30183043
}
30193044

test/Constraints/bridging.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,8 @@ func rdar19836341(_ ns: NSString?, vns: NSString?) {
285285

286286
// <rdar://problem/20029786> Swift compiler sometimes suggests changing "as!" to "as?!"
287287
func rdar20029786(_ ns: NSString?) {
288-
var s: String = ns ?? "str" as String as String // expected-error{{cannot convert value of type 'NSString?' to expected argument type 'String?'}}{{21-21= as String?}}
288+
var s: String = ns ?? "str" as String as String // expected-error{{'NSString' is not implicitly convertible to 'String'; did you mean to use 'as' to explicitly convert?}} {{19-19=(}} {{50-50=) as String}}
289+
// expected-error@-1 {{cannot convert value of type 'String' to expected argument type 'NSString'}} {{50-50= as NSString}}
289290
var s2 = ns ?? "str" as String as String // expected-error {{cannot convert value of type 'String' to expected argument type 'NSString'}}{{43-43= as NSString}}
290291

291292
let s3: NSString? = "str" as String? // expected-error {{cannot convert value of type 'String?' to specified type 'NSString?'}}{{39-39= as NSString?}}

test/attr/attr_autoclosure.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,3 +274,10 @@ func autoclosure_param_returning_func_type() {
274274
func biz_5(_ fn: @escaping () -> (() -> Int)) { fiz(fn) } // Can't forward in Swift >= 5 mode
275275
// expected-error@-1 {{add () to forward @autoclosure parameter}} {{57-57=()}}
276276
}
277+
278+
func test_autoclosure_with_generic_argument_mismatch() {
279+
struct S<T> {} // expected-note {{arguments to generic parameter 'T' ('String' and 'Int') are expected to be equal}}
280+
func foo(_: @autoclosure () -> S<Int>) {}
281+
282+
foo(S<String>()) // expected-error {{cannot convert value of type 'S<String>' to expected argument type 'S<Int>'}}
283+
}

test/decl/func/dynamic_self.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -386,8 +386,7 @@ class Factory : FactoryPattern {
386386

387387
convenience init(string: String) {
388388
self.init(factory: Factory(_string: string))
389-
// expected-error@-1 {{incorrect argument label in call (have 'factory:', expected '_string:')}}
390-
// FIXME: Bogus diagnostic
389+
// expected-error@-1 {{cannot convert value of type 'Factory' to expected argument type 'Self'}}
391390
}
392391
}
393392

test/expr/expressions.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -774,14 +774,16 @@ func testNilCoalescePrecedence(cond: Bool, a: Int?, r: ClosedRange<Int>?) {
774774
// ?? should have higher precedence than logical operators like || and comparisons.
775775
if cond || (a ?? 42 > 0) {} // Ok.
776776
if (cond || a) ?? 42 > 0 {} // expected-error {{cannot be used as a boolean}} {{15-15=(}} {{16-16= != nil)}}
777+
// expected-error@-1:12 {{cannot convert value of type 'Bool' to expected argument type 'Int?'}}
777778
if (cond || a) ?? (42 > 0) {} // expected-error {{cannot be used as a boolean}} {{15-15=(}} {{16-16= != nil)}}
778779

779780
if cond || a ?? 42 > 0 {} // Parses as the first one, not the others.
780781

781782

782783
// ?? should have lower precedence than range and arithmetic operators.
783784
let r1 = r ?? (0...42) // ok
784-
let r2 = (r ?? 0)...42 // not ok: expected-error {{cannot convert value of type 'Int' to expected argument type 'ClosedRange<Int>'}}
785+
let r2 = (r ?? 0)...42 // not ok: expected-error 2 {{cannot convert value of type 'Int' to expected argument type 'ClosedRange<Int>'}}
786+
// expected-error@-1 {{argument type 'ClosedRange<Int>' does not conform to expected type 'Comparable'}}
785787
let r3 = r ?? 0...42 // parses as the first one, not the second.
786788

787789

0 commit comments

Comments
 (0)