[Diagnostic] In no exact match cases diagnose labeling mismatch as a note

Each candidate with incorrect labels (but everything else lined up)
gets a note on its declarationm which says what is expected and what
has been given.
This commit is contained in:
Pavel Yaskevich
2019-07-25 13:45:18 -07:00
parent be470f5dd7
commit 1b4f9c33eb
8 changed files with 87 additions and 42 deletions

View File

@@ -1051,6 +1051,9 @@ ERROR(argument_out_of_order_unnamed_named,none,
ERROR(argument_out_of_order_unnamed_unnamed,none,
"unnamed argument #%0 must precede unnamed argument #%1",
(unsigned, unsigned))
NOTE(candidate_expected_different_labels,none,
"incorrect labels for candidate (have: '%0', expected: '%1')",
(StringRef, StringRef))
ERROR(member_shadows_global_function,none,
"use of %0 refers to %1 %2 rather than %3 %4 in %5 %6",

View File

@@ -33,6 +33,7 @@
#include "swift/Parse/Lexer.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallString.h"
#include <string>
using namespace swift;
using namespace constraints;
@@ -691,6 +692,46 @@ bool LabelingFailure::diagnoseAsError() {
isa<SubscriptExpr>(anchor));
}
bool LabelingFailure::diagnoseAsNote() {
auto *anchor = getRawAnchor();
auto *argExpr = getArgumentExprFor(anchor);
if (!argExpr)
return false;
SmallVector<Identifier, 4> argLabels;
if (auto *paren = dyn_cast<ParenExpr>(argExpr)) {
argLabels.push_back(Identifier());
} else if (auto *tuple = dyn_cast<TupleExpr>(argExpr)) {
argLabels.append(tuple->getElementNames().begin(),
tuple->getElementNames().end());
} else {
return false;
}
auto stringifyLabels = [](ArrayRef<Identifier> labels) -> std::string {
std::string str;
for (auto label : labels) {
str += label.empty() ? "_" : label.str();
str += ':';
}
return "(" + str + ")";
};
auto selectedOverload = getChoiceFor(anchor);
if (!selectedOverload)
return false;
const auto &choice = selectedOverload->choice;
if (auto *decl = choice.getDeclOrNull()) {
emitDiagnostic(decl, diag::candidate_expected_different_labels,
stringifyLabels(argLabels), stringifyLabels(CorrectLabels));
return true;
}
return false;
}
bool NoEscapeFuncToTypeConversionFailure::diagnoseAsError() {
auto *anchor = getAnchor();

View File

@@ -529,6 +529,7 @@ public:
: FailureDiagnostic(root, cs, locator), CorrectLabels(labels) {}
bool diagnoseAsError() override;
bool diagnoseAsNote() override;
};
/// Diagnose errors related to converting function type which

View File

@@ -3,6 +3,6 @@
import ObjectiveC
func instanceMethod(_ b: B) {
b.method(1, 2.5) // expected-error {{argument labels '(_:, _:)' do not match any available overloads}}
// expected-note @-1 {{overloads for 'method' exist with these partially matching parameter lists: (Int32, onCat1: Double), (Int32, onExtA: Double), (Int32, onExtB: Double), (Int32, with: Double), (Int32, with: Float), (Int32, withDouble: Double), (Int32, withFloat: Float)}}
// Notes for labeling mismatch candidates are now attached to each individual declaration
b.method(1, 2.5) // expected-error {{no exact matches in call to instance method 'method'}}
}

View File

@@ -3,57 +3,57 @@
import UnimportableMembers
import UnimportableMembersUser
class IncompleteInitSubclassImplicit : IncompleteDesignatedInitializers {
class IncompleteInitSubclassImplicit : IncompleteDesignatedInitializers { // expected-note 6 {{incorrect labels for candidate}}
var myOneNewMember = 1
}
class IncompleteInitSubclass : IncompleteDesignatedInitializers {
override init(first: Int) {}
override init(second: Int) {}
override init(first: Int) {} // expected-note 3 {{incorrect labels for candidate}}
override init(second: Int) {} // expected-note 3 {{incorrect labels for candidate}}
}
class IncompleteConvenienceInitSubclass : IncompleteConvenienceInitializers {}
class IncompleteConvenienceInitSubclass : IncompleteConvenienceInitializers {} // expected-note 2 {{incorrect labels for candidate}}
class IncompleteUnknownInitSubclass : IncompleteUnknownInitializers {}
class IncompleteUnknownInitSubclass : IncompleteUnknownInitializers {} // expected-note 4 {{incorrect labels for candidate}}
class IncompleteInitCategorySubclassImplicit : IncompleteDesignatedInitializersWithCategory {}
class IncompleteInitCategorySubclassImplicit : IncompleteDesignatedInitializersWithCategory {} // expected-note 6 {{incorrect labels for candidate}}
class IncompleteInitCategorySubclass : IncompleteDesignatedInitializersWithCategory {
override init(first: Int) {}
override init(second: Int) {}
override init(first: Int) {} // expected-note 3 {{incorrect labels for candidate}}
override init(second: Int) {} // expected-note 3 {{incorrect labels for candidate}}
}
class DesignatedInitializerInAnotherModuleSubclass : DesignatedInitializerInAnotherModule {}
class DesignatedInitializerInAnotherModuleSubclass : DesignatedInitializerInAnotherModule {} // expected-note 9 {{incorrect labels for candidate}}
func testBaseClassesBehaveAsExpected() {
_ = IncompleteDesignatedInitializers(first: 0) // okay
_ = IncompleteDesignatedInitializers(second: 0) // okay
_ = IncompleteDesignatedInitializers(missing: 0) // expected-error {{argument labels '(missing:)' do not match any available overloads}} expected-note {{overloads}}
_ = IncompleteDesignatedInitializers(missing: 0) // expected-error {{no exact matches in call to initializer}}
_ = IncompleteDesignatedInitializers(conveniently: 0) // okay
_ = IncompleteDesignatedInitializers(category: 0) // okay
_ = IncompleteConvenienceInitializers(first: 0) // okay
_ = IncompleteConvenienceInitializers(second: 0) // okay
_ = IncompleteConvenienceInitializers(missing: 0) // expected-error {{argument labels '(missing:)' do not match any available overloads}} expected-note {{overloads}}
_ = IncompleteConvenienceInitializers(missing: 0) // expected-error {{no exact matches in call to initializer}}
_ = IncompleteConvenienceInitializers(conveniently: 0) // okay
_ = IncompleteConvenienceInitializers(category: 0) // okay
_ = IncompleteUnknownInitializers(first: 0) // okay
_ = IncompleteUnknownInitializers(second: 0) // okay
_ = IncompleteUnknownInitializers(missing: 0) // expected-error {{argument labels '(missing:)' do not match any available overloads}} expected-note {{overloads}}
_ = IncompleteUnknownInitializers(missing: 0) // expected-error {{no exact matches in call to initializer}}
_ = IncompleteUnknownInitializers(conveniently: 0) // okay
_ = IncompleteUnknownInitializers(category: 0) // okay
_ = IncompleteDesignatedInitializersWithCategory(first: 0) // okay
_ = IncompleteDesignatedInitializersWithCategory(second: 0) // okay
_ = IncompleteDesignatedInitializersWithCategory(missing: 0) // expected-error {{argument labels '(missing:)' do not match any available overloads}} expected-note {{overloads}}
_ = IncompleteDesignatedInitializersWithCategory(missing: 0) // expected-error {{no exact matches in call to initializer}}
_ = IncompleteDesignatedInitializersWithCategory(conveniently: 0) // okay
_ = IncompleteDesignatedInitializersWithCategory(category: 0) // okay
_ = DesignatedInitializerInAnotherModule(first: 0) // okay
_ = DesignatedInitializerInAnotherModule(second: 0) // okay
_ = DesignatedInitializerInAnotherModule(missing: 0) // expected-error {{argument labels '(missing:)' do not match any available overloads}} expected-note {{overloads}}
_ = DesignatedInitializerInAnotherModule(missing: 0) // expected-error {{no exact matches in call to initializer}}
_ = DesignatedInitializerInAnotherModule(conveniently: 0) // okay
_ = DesignatedInitializerInAnotherModule(category: 0) // okay
_ = DesignatedInitializerInAnotherModule(fromOtherModule: 0) // okay
@@ -62,44 +62,44 @@ func testBaseClassesBehaveAsExpected() {
func testSubclasses() {
_ = IncompleteInitSubclass(first: 0) // okay
_ = IncompleteInitSubclass(second: 0) // okay
_ = IncompleteInitSubclass(missing: 0) // expected-error {{argument labels '(missing:)' do not match any available overloads}} expected-note {{overloads}}
_ = IncompleteInitSubclass(conveniently: 0) // expected-error {{argument labels '(conveniently:)' do not match any available overloads}} expected-note {{overloads}}
_ = IncompleteInitSubclass(category: 0) // expected-error {{argument labels '(category:)' do not match any available overloads}} expected-note {{overloads}}
_ = IncompleteInitSubclass(missing: 0) // expected-error {{no exact matches in call to initializer}}
_ = IncompleteInitSubclass(conveniently: 0) // expected-error {{no exact matches in call to initializer}}
_ = IncompleteInitSubclass(category: 0) // expected-error {{no exact matches in call to initializer}}
_ = IncompleteInitSubclassImplicit(first: 0) // okay
_ = IncompleteInitSubclassImplicit(second: 0) // okay
_ = IncompleteInitSubclassImplicit(missing: 0) // expected-error {{argument labels '(missing:)' do not match any available overloads}} expected-note {{overloads}}
_ = IncompleteInitSubclassImplicit(conveniently: 0) // expected-error {{argument labels '(conveniently:)' do not match any available overloads}} expected-note {{overloads}}
_ = IncompleteInitSubclassImplicit(category: 0) // expected-error {{argument labels '(category:)' do not match any available overloads}} expected-note {{overloads}}
_ = IncompleteInitSubclassImplicit(missing: 0) // expected-error {{no exact matches in call to initializer}}
_ = IncompleteInitSubclassImplicit(conveniently: 0) // expected-error {{no exact matches in call to initializer}}
_ = IncompleteInitSubclassImplicit(category: 0) // expected-error {{no exact matches in call to initializer}}
_ = IncompleteConvenienceInitSubclass(first: 0) // okay
_ = IncompleteConvenienceInitSubclass(second: 0) // okay
_ = IncompleteConvenienceInitSubclass(missing: 0) // expected-error {{argument labels '(missing:)' do not match any available overloads}} expected-note {{overloads}}
_ = IncompleteConvenienceInitSubclass(missing: 0) // expected-error {{no exact matches in call to initializer}}
_ = IncompleteConvenienceInitSubclass(conveniently: 0) // okay
_ = IncompleteConvenienceInitSubclass(category: 0) // okay
_ = IncompleteUnknownInitSubclass(first: 0) // okay
_ = IncompleteUnknownInitSubclass(second: 0) // okay
_ = IncompleteUnknownInitSubclass(missing: 0) // expected-error {{argument labels '(missing:)' do not match any available overloads}} expected-note {{overloads}}
_ = IncompleteUnknownInitSubclass(missing: 0) // expected-error {{no exact matches in call to initializer}}
_ = IncompleteUnknownInitSubclass(conveniently: 0) // okay
_ = IncompleteUnknownInitSubclass(category: 0) // okay
_ = IncompleteInitCategorySubclass(first: 0) // okay
_ = IncompleteInitCategorySubclass(second: 0) // okay
_ = IncompleteInitCategorySubclass(missing: 0) // expected-error {{argument labels '(missing:)' do not match any available overloads}} expected-note {{overloads}}
_ = IncompleteInitCategorySubclass(conveniently: 0) // expected-error {{argument labels '(conveniently:)' do not match any available overloads}} expected-note {{overloads}}
_ = IncompleteInitCategorySubclass(category: 0) // expected-error {{argument labels '(category:)' do not match any available overloads}} expected-note {{overloads}}
_ = IncompleteInitCategorySubclass(missing: 0) // expected-error {{no exact matches in call to initializer}}
_ = IncompleteInitCategorySubclass(conveniently: 0) // expected-error {{no exact matches in call to initializer}}
_ = IncompleteInitCategorySubclass(category: 0) // expected-error {{no exact matches in call to initializer}}
_ = IncompleteInitCategorySubclassImplicit(first: 0) // okay
_ = IncompleteInitCategorySubclassImplicit(second: 0) // okay
_ = IncompleteInitCategorySubclassImplicit(missing: 0) // expected-error {{argument labels '(missing:)' do not match any available overloads}} expected-note {{overloads}}
_ = IncompleteInitCategorySubclassImplicit(conveniently: 0) // expected-error {{argument labels '(conveniently:)' do not match any available overloads}} expected-note {{overloads}}
_ = IncompleteInitCategorySubclassImplicit(category: 0) // expected-error {{argument labels '(category:)' do not match any available overloads}} expected-note {{overloads}}
_ = IncompleteInitCategorySubclassImplicit(missing: 0) // expected-error {{no exact matches in call to initializer}}
_ = IncompleteInitCategorySubclassImplicit(conveniently: 0) // expected-error {{no exact matches in call to initializer}}
_ = IncompleteInitCategorySubclassImplicit(category: 0) // expected-error {{no exact matches in call to initializer}}
_ = DesignatedInitializerInAnotherModuleSubclass(first: 0) // okay
_ = DesignatedInitializerInAnotherModuleSubclass(second: 0) // okay
_ = DesignatedInitializerInAnotherModuleSubclass(missing: 0) // expected-error {{argument labels '(missing:)' do not match any available overloads}} expected-note {{overloads}}
_ = DesignatedInitializerInAnotherModuleSubclass(conveniently: 0) // expected-error {{argument labels '(conveniently:)' do not match any available overloads}} expected-note {{overloads}}
_ = DesignatedInitializerInAnotherModuleSubclass(category: 0) // expected-error {{argument labels '(category:)' do not match any available overloads}} expected-note {{overloads}}
_ = DesignatedInitializerInAnotherModuleSubclass(missing: 0) // expected-error {{no exact matches in call to initializer}}
_ = DesignatedInitializerInAnotherModuleSubclass(conveniently: 0) // expected-error {{no exact matches in call to initializer}}
_ = DesignatedInitializerInAnotherModuleSubclass(category: 0) // expected-error {{no exact matches in call to initializer}}
_ = DesignatedInitializerInAnotherModuleSubclass(fromOtherModule: 0) // okay
}

View File

@@ -417,8 +417,8 @@ enum Color {
static func rainbow() -> Color {}
static func overload(a : Int) -> Color {}
static func overload(b : Int) -> Color {}
static func overload(a : Int) -> Color {} // expected-note {{incorrect labels for candidate (have: '(_:)', expected: '(a:)')}}
static func overload(b : Int) -> Color {} // expected-note {{incorrect labels for candidate (have: '(_:)', expected: '(b:)')}}
static func frob(_ a : Int, b : inout Int) -> Color {}
static var svar: Color { return .Red }
@@ -444,8 +444,7 @@ let _ : Color = .rainbow // expected-error {{member 'rainbow' is a function; di
let _: Color = .overload(a : 1.0) // expected-error {{cannot convert value of type 'Double' to expected argument type 'Int'}}
let _: Color = .overload(1.0) // expected-error {{ambiguous reference to member 'overload'}}
// expected-note @-1 {{overloads for 'overload' exist with these partially matching parameter lists: (a: Int), (b: Int)}}
let _: Color = .overload(1) // expected-error {{ambiguous reference to member 'overload'}}
// expected-note @-1 {{overloads for 'overload' exist with these partially matching parameter lists: (a: Int), (b: Int)}}
let _: Color = .overload(1) // expected-error {{no exact matches in call to static method 'overload'}}
let _: Color = .frob(1.0, &i) // expected-error {{missing argument label 'b:' in call}}
let _: Color = .frob(1.0, b: &i) // expected-error {{cannot convert value of type 'Double' to expected argument type 'Int'}}
let _: Color = .frob(1, i) // expected-error {{missing argument label 'b:' in call}}

View File

@@ -6,8 +6,8 @@ class A {
func do_b(_ x: Int) {}
func do_b(_ x: Float) {}
func do_c(x: Int) {}
func do_c(y: Int) {}
func do_c(x: Int) {} // expected-note 2 {{incorrect labels for candidate (have: '(_:)', expected: '(x:)')}}
func do_c(y: Int) {} // expected-note 2 {{incorrect labels for candidate (have: '(_:)', expected: '(y:)')}}
}
func test0(_ a : A!) {
@@ -16,7 +16,7 @@ func test0(_ a : A!) {
a.do_b(1)
a.do_b(5.0)
a.do_c(1) // expected-error {{cannot invoke 'do_c' with an argument list of type '(Int)'}}
a.do_c(1) // expected-error {{no exact matches in call to instance method 'do_c'}}
a.do_c(x: 1)
}
@@ -26,7 +26,7 @@ func test1(_ a : A!) {
a?.do_b(1)
a?.do_b(5.0)
a?.do_c(1) // expected-error {{cannot invoke 'do_c' with an argument list of type '(Int)'}}
a?.do_c(1) // expected-error {{no exact matches in call to instance method 'do_c'}}
a?.do_c(x: 1)
}

View File

@@ -4,7 +4,8 @@ extension BinaryInteger {
init(bytes: [UInt8]) { fatalError() }
init<S: Sequence>(bytes: S) where S.Iterator.Element == UInt8 {
self.init(bytes // expected-error {{missing argument label 'integerLiteral:' in call}}
// expected-note@-1 {{incorrect labels for candidate (have: '(_:)', expected: '(bytes:)')}}
self.init(bytes // expected-error {{no exact matches in call to initializer}}
// expected-note@-1 {{}}
extension