Skip to content

Commit 8b1adce

Browse files
authored
Merge pull request #26543 from xedin/diag-arr-to-ptr-elt-conv-failures
[Diagnostics] Extend generic argument mismatch to cover [T] to Unsafe…
2 parents 8a9af49 + 8ac2ef8 commit 8b1adce

File tree

3 files changed

+34
-9
lines changed

3 files changed

+34
-9
lines changed

lib/Sema/CSDiagnostics.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -611,7 +611,15 @@ Optional<Diag<Type, Type>> GenericArgumentsMismatchFailure::getDiagnosticFor(
611611
}
612612

613613
void GenericArgumentsMismatchFailure::emitNoteForMismatch(int position) {
614-
auto genericTypeDecl = getActual()->getCanonicalType()->getAnyGeneric();
614+
auto *locator = getLocator();
615+
// Since there could be implicit conversions assoicated with argument
616+
// to parameter conversions, let's use parameter type as a source of
617+
// generic parameter information.
618+
auto paramSourceTy =
619+
locator->isLastElement(ConstraintLocator::ApplyArgToParam) ? getRequired()
620+
: getActual();
621+
622+
auto genericTypeDecl = paramSourceTy->getAnyGeneric();
615623
auto param = genericTypeDecl->getGenericParams()->getParams()[position];
616624

617625
auto lhs = resolveType(getActual()->getGenericArgs()[position])

lib/Sema/CSSimplify.cpp

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6624,11 +6624,24 @@ ConstraintSystem::simplifyRestrictedConstraintImpl(
66246624
auto baseType2 = getBaseTypeForPointer(*this, t2);
66256625

66266626
increaseScore(ScoreKind::SK_ValueToPointerConversion);
6627-
return matchTypes(baseType1, baseType2,
6628-
ConstraintKind::BindToPointerType,
6629-
subflags, locator);
6627+
auto result = matchTypes(baseType1, baseType2,
6628+
ConstraintKind::BindToPointerType,
6629+
subflags, locator);
6630+
6631+
if (!(result.isFailure() && shouldAttemptFixes()))
6632+
return result;
6633+
6634+
auto *arrTy = obj1->getAs<BoundGenericType>();
6635+
// Let's dig out underlying pointer type since it could
6636+
// be wrapped into N (implicit) optionals.
6637+
auto *ptrTy =
6638+
type2->lookThroughAllOptionalTypes()->getAs<BoundGenericType>();
6639+
6640+
auto *fix = GenericArgumentsMismatch::create(*this, arrTy, ptrTy, {0},
6641+
getConstraintLocator(locator));
6642+
return recordFix(fix) ? SolutionKind::Error : SolutionKind::Solved;
66306643
}
6631-
6644+
66326645
// String ===> UnsafePointer<[U]Int8>
66336646
case ConversionRestrictionKind::StringToPointer: {
66346647
addContextualScore();

test/Parse/pointer_conversion.swift.gyb

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,8 @@ func mutablePointerArguments(_ p: UnsafeMutablePointer<Int>,
5454
var ii: [Int] = [0, 1, 2]
5555
var ff: [Float] = [0, 1, 2]
5656
takesMutablePointer(&ii)
57-
takesMutablePointer(&ff) // expected-error{{cannot convert value of type '[Float]' to expected argument type 'Int'}}
57+
takesMutablePointer(&ff) // expected-error{{cannot convert value of type '[Float]' to expected argument type 'UnsafeMutablePointer<Int>'}}
58+
// expected-note@-1 {{arguments to generic parameter 'Pointee' ('Float' and 'Int') are expected to be equal}}
5859
takesMutablePointer(ii) // expected-error{{cannot convert value of type '[Int]' to expected argument type 'UnsafeMutablePointer<Int>${diag_suffix}'}}
5960
takesMutablePointer(ff) // expected-error{{cannot convert value of type '[Float]' to expected argument type 'UnsafeMutablePointer<Int>${diag_suffix}'}}
6061

@@ -152,9 +153,11 @@ func constPointerArguments(_ p: UnsafeMutablePointer<Int>,
152153
var ii: [Int] = [0, 1, 2]
153154
var ff: [Float] = [0, 1, 2]
154155
takesConstPointer(&ii)
155-
takesConstPointer(&ff) // expected-error{{cannot convert value of type '[Float]' to expected argument type 'Int'}}
156+
takesConstPointer(&ff) // expected-error{{cannot convert value of type '[Float]' to expected argument type 'UnsafePointer<Int>'}}
157+
// expected-note@-1 {{arguments to generic parameter 'Pointee' ('Float' and 'Int') are expected to be equal}}
156158
takesConstPointer(ii)
157-
takesConstPointer(ff) // expected-error{{cannot convert value of type '[Float]' to expected argument type 'UnsafePointer<Int>${diag_suffix}'}}
159+
takesConstPointer(ff) // expected-error{{cannot convert value of type '[Float]' to expected argument type 'UnsafePointer<Int>'}}
160+
// expected-note@-1 {{arguments to generic parameter 'Pointee' ('Float' and 'Int') are expected to be equal}}
158161
takesConstPointer([0, 1, 2])
159162
// <rdar://problem/22308330> QoI: CSDiags doesn't handle array -> pointer impl conversions well
160163
takesConstPointer([0.0, 1.0, 2.0])
@@ -338,7 +341,8 @@ func f23202128() {
338341
UMP(&pipe) // expected-error {{cannot pass immutable value as inout argument: 'pipe' is a 'let' constant}}
339342

340343
var pipe2: [Int] = [0, 0]
341-
UMP(&pipe2) // expected-error {{cannot convert value of type '[Int]' to expected argument type 'Int32'}}
344+
UMP(&pipe2) // expected-error {{cannot convert value of type '[Int]' to expected argument type 'UnsafeMutablePointer<Int32>'}}
345+
// expected-note@-1 {{arguments to generic parameter 'Pointee' ('Int' and 'Int32') are expected to be equal}}
342346

343347

344348
UP(pipe) // ok

0 commit comments

Comments
 (0)