Skip to content

Commit 1f78009

Browse files
committed
[CSDiagnostics] Add ephemeralness ambiguity notes
1 parent 3df40aa commit 1f78009

File tree

4 files changed

+24
-0
lines changed

4 files changed

+24
-0
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -426,6 +426,10 @@ NOTE(ephemeral_use_array_with_unsafe_buffer,none,
426426
"use the 'withUnsafe%select{Bytes|MutableBytes|BufferPointer|"
427427
"MutableBufferPointer}0' method on Array in order to explicitly convert "
428428
"argument to buffer pointer valid for a defined scope", (unsigned))
429+
NOTE(candidate_performs_illegal_ephemeral_conv,none,
430+
"candidate expects pointer that outlives the call for parameter #%0",
431+
(unsigned))
432+
429433
ERROR(cannot_convert_argument_value_protocol,none,
430434
"argument type %0 does not conform to expected type %1", (Type, Type))
431435
ERROR(cannot_convert_partial_argument_value_protocol,none,

lib/Sema/CSDiagnostics.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5535,6 +5535,16 @@ void NonEphemeralConversionFailure::emitSuggestionNotes() const {
55355535
}
55365536
}
55375537

5538+
bool NonEphemeralConversionFailure::diagnoseAsNote() {
5539+
// We can only emit a useful note if we have a callee.
5540+
if (auto *callee = getCallee()) {
5541+
emitDiagnostic(callee, diag::candidate_performs_illegal_ephemeral_conv,
5542+
getParamPosition());
5543+
return true;
5544+
}
5545+
return false;
5546+
}
5547+
55385548
bool NonEphemeralConversionFailure::diagnoseAsError() {
55395549
auto *argExpr = getArgExpr();
55405550
if (isa<InOutExpr>(argExpr)) {

lib/Sema/CSDiagnostics.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1933,6 +1933,7 @@ class NonEphemeralConversionFailure final : public ArgumentMismatchFailure {
19331933
}
19341934

19351935
bool diagnoseAsError() override;
1936+
bool diagnoseAsNote() override;
19361937

19371938
private:
19381939
/// Emits a note explaining to the user that an ephemeral conversion is only

test/Sema/diag_non_ephemeral.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -446,3 +446,12 @@ let f8: (UnsafeMutablePointer<Int8>) -> Void = takesMutable
446446
func higherOrder(_ fn: (UnsafeMutableRawPointer, Int) -> Void) {}
447447
higherOrder(takesMutableRaw)
448448

449+
450+
// @_nonEphemeral ambiguities
451+
func takesPointerOverload(x: Int = 0, @_nonEphemeral _ ptr: UnsafePointer<Int>) {} // expected-note {{candidate expects pointer that outlives the call for parameter #2}}
452+
func takesPointerOverload(x: Int = 0, @_nonEphemeral _ ptr: UnsafeMutablePointer<Int>) {} // expected-note {{candidate expects pointer that outlives the call for parameter #2}}
453+
454+
func testAmbiguity() {
455+
var arr = [1, 2, 3]
456+
takesPointerOverload(&arr) // expected-error {{no exact matches in call to global function 'takesPointerOverload(x:_:)'}}
457+
}

0 commit comments

Comments
 (0)