mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[ConstraintSystem] Detect and diagnose missing generic arguments
Introduce a fix to detect and diagnose situations when omitted
generic arguments couldn't be deduced by the solver based on
the enclosing context.
Example:
```swift
struct S<T> {
}
_ = S() // There is not enough context to deduce `T`
```
Resolves: rdar://problem/51203824
This commit is contained in:
@@ -365,6 +365,10 @@ public:
|
||||
ArrayRef<TypeRepr*> GenericArgs,
|
||||
SourceRange AngleBrackets);
|
||||
|
||||
unsigned getNumGenericArgs() const {
|
||||
return Bits.GenericIdentTypeRepr.NumGenericArgs;
|
||||
}
|
||||
|
||||
ArrayRef<TypeRepr*> getGenericArgs() const {
|
||||
return {getTrailingObjects<TypeRepr*>(),
|
||||
Bits.GenericIdentTypeRepr.NumGenericArgs};
|
||||
|
||||
@@ -1244,14 +1244,11 @@ class MissingGenericArgumentsFailure final : public FailureDiagnostic {
|
||||
public:
|
||||
MissingGenericArgumentsFailure(Expr *root, ConstraintSystem &cs,
|
||||
TypeRepr *baseType,
|
||||
ArrayRef<TypeVariableType *> missingParams,
|
||||
ArrayRef<GenericTypeParamType *> missingParams,
|
||||
ConstraintLocator *locator)
|
||||
: FailureDiagnostic(root, cs, locator), BaseType(baseType) {
|
||||
assert(!missingParams.empty());
|
||||
llvm::transform(missingParams, std::back_inserter(Parameters),
|
||||
[](const TypeVariableType *GP) {
|
||||
return GP->getImpl().getGenericParameter();
|
||||
});
|
||||
Parameters.append(missingParams.begin(), missingParams.end());
|
||||
}
|
||||
|
||||
SourceLoc getLoc() const;
|
||||
|
||||
@@ -540,3 +540,110 @@ CollectionElementContextualMismatch::create(ConstraintSystem &cs, Type srcType,
|
||||
return new (cs.getAllocator())
|
||||
CollectionElementContextualMismatch(cs, srcType, dstType, locator);
|
||||
}
|
||||
|
||||
bool ExplicitlySpecifyGenericArguments::diagnose(Expr *root,
|
||||
bool asNote) const {
|
||||
auto &cs = getConstraintSystem();
|
||||
|
||||
bool diagnosed = false;
|
||||
for (const auto ¶msPerAnchor : Parameters) {
|
||||
auto anchor = paramsPerAnchor.first;
|
||||
ArrayRef<GenericTypeParamType *> missingParameters = paramsPerAnchor.second;
|
||||
MissingGenericArgumentsFailure failure(root, cs,
|
||||
anchor.dyn_cast<TypeRepr *>(),
|
||||
missingParameters, getLocator());
|
||||
diagnosed |= failure.diagnose(asNote);
|
||||
}
|
||||
|
||||
return diagnosed;
|
||||
}
|
||||
|
||||
ExplicitlySpecifyGenericArguments *ExplicitlySpecifyGenericArguments::create(
|
||||
ConstraintSystem &cs, ArrayRef<GenericTypeParamType *> params,
|
||||
ConstraintLocator *locator) {
|
||||
llvm::SmallDenseMap<TypeRepr *, llvm::SmallVector<GenericTypeParamType *, 4>>
|
||||
typeBasedParams;
|
||||
|
||||
if (findArgumentLocations(locator->getAnchor(), params,
|
||||
[&](TypeRepr *base, GenericTypeParamType *GP) {
|
||||
typeBasedParams[base].push_back(GP);
|
||||
}))
|
||||
return new (cs.getAllocator())
|
||||
ExplicitlySpecifyGenericArguments(cs, typeBasedParams, locator);
|
||||
|
||||
return new (cs.getAllocator())
|
||||
ExplicitlySpecifyGenericArguments(cs, params, locator);
|
||||
}
|
||||
|
||||
bool ExplicitlySpecifyGenericArguments::findArgumentLocations(
|
||||
Expr *anchor, ArrayRef<GenericTypeParamType *> genericParams,
|
||||
llvm::function_ref<void(TypeRepr *, GenericTypeParamType *)> callback) {
|
||||
using Callback = llvm::function_ref<void(TypeRepr *, GenericTypeParamType *)>;
|
||||
|
||||
if (!anchor)
|
||||
return false;
|
||||
|
||||
TypeLoc typeLoc;
|
||||
if (auto *TE = dyn_cast<TypeExpr>(anchor))
|
||||
typeLoc = TE->getTypeLoc();
|
||||
else if (auto *ECE = dyn_cast<ExplicitCastExpr>(anchor))
|
||||
typeLoc = ECE->getCastTypeLoc();
|
||||
|
||||
if (!typeLoc.hasLocation())
|
||||
return false;
|
||||
|
||||
llvm::SmallVector<GenericTypeParamType *, 4> params(genericParams.begin(),
|
||||
genericParams.end());
|
||||
|
||||
struct AssociateMissingParams : public ASTWalker {
|
||||
llvm::SmallVectorImpl<GenericTypeParamType *> &Params;
|
||||
Callback Fn;
|
||||
|
||||
AssociateMissingParams(SmallVectorImpl<GenericTypeParamType *> ¶ms,
|
||||
Callback callback)
|
||||
: Params(params), Fn(callback) {}
|
||||
|
||||
bool walkToTypeReprPre(TypeRepr *T) override {
|
||||
if (Params.empty())
|
||||
return false;
|
||||
|
||||
auto *ident = dyn_cast<ComponentIdentTypeRepr>(T);
|
||||
if (!ident)
|
||||
return true;
|
||||
|
||||
auto *decl = dyn_cast_or_null<GenericTypeDecl>(ident->getBoundDecl());
|
||||
if (!decl)
|
||||
return true;
|
||||
|
||||
auto *paramList = decl->getGenericParams();
|
||||
if (!paramList)
|
||||
return true;
|
||||
|
||||
// There could a situation like `S<S>()`, so we need to be
|
||||
// careful not to point at first `S` because it has all of
|
||||
// its generic parameters specified.
|
||||
if (auto *generic = dyn_cast<GenericIdentTypeRepr>(ident)) {
|
||||
if (paramList->size() == generic->getNumGenericArgs())
|
||||
return true;
|
||||
}
|
||||
|
||||
for (auto *candidate : paramList->getParams()) {
|
||||
auto result =
|
||||
llvm::find_if(Params, [&](const GenericTypeParamType *param) {
|
||||
return candidate == param->getDecl();
|
||||
});
|
||||
|
||||
if (result != Params.end()) {
|
||||
Fn(ident, *result);
|
||||
Params.erase(result);
|
||||
}
|
||||
}
|
||||
|
||||
// Keep walking.
|
||||
return true;
|
||||
}
|
||||
} paramAssociator(params, callback);
|
||||
|
||||
typeLoc.getTypeRepr()->walk(paramAssociator);
|
||||
return params.empty();
|
||||
}
|
||||
|
||||
@@ -153,6 +153,11 @@ enum class FixKind : uint8_t {
|
||||
/// Remove `return` or default last expression of single expression
|
||||
/// function to `Void` to conform to expected result type.
|
||||
RemoveReturn,
|
||||
|
||||
/// Generic parameters could not be inferred and have to be explicitly
|
||||
/// specified in the source. This fix groups all of the missing arguments
|
||||
/// associated with single declaration.
|
||||
ExplicitlySpecifyGenericArguments,
|
||||
};
|
||||
|
||||
class ConstraintFix {
|
||||
@@ -917,6 +922,53 @@ public:
|
||||
ConstraintLocator *locator);
|
||||
};
|
||||
|
||||
class ExplicitlySpecifyGenericArguments final : public ConstraintFix {
|
||||
using Anchor = llvm::PointerUnion<ConstraintLocator *, TypeRepr *>;
|
||||
|
||||
llvm::SmallDenseMap<Anchor, llvm::SmallVector<GenericTypeParamType *, 4>>
|
||||
Parameters;
|
||||
|
||||
ExplicitlySpecifyGenericArguments(ConstraintSystem &cs,
|
||||
ArrayRef<GenericTypeParamType *> params,
|
||||
ConstraintLocator *locator)
|
||||
: ConstraintFix(cs, FixKind::ExplicitlySpecifyGenericArguments, locator) {
|
||||
assert(!params.empty());
|
||||
Parameters[locator].append(params.begin(), params.end());
|
||||
}
|
||||
|
||||
ExplicitlySpecifyGenericArguments(
|
||||
ConstraintSystem &cs,
|
||||
llvm::SmallDenseMap<TypeRepr *,
|
||||
llvm::SmallVector<GenericTypeParamType *, 4>> ¶ms,
|
||||
ConstraintLocator *locator)
|
||||
: ConstraintFix(cs, FixKind::ExplicitlySpecifyGenericArguments, locator) {
|
||||
assert(!params.empty());
|
||||
for (const auto &elt : params) {
|
||||
Parameters.insert(elt);
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
std::string getName() const override {
|
||||
return "default missing generic argument to `Any`";
|
||||
}
|
||||
|
||||
bool diagnose(Expr *root, bool asNote = false) const override;
|
||||
|
||||
static ExplicitlySpecifyGenericArguments *
|
||||
create(ConstraintSystem &cs, ArrayRef<GenericTypeParamType *> params,
|
||||
ConstraintLocator *locator);
|
||||
|
||||
private:
|
||||
/// Retrieve representative locations for given generic prameters
|
||||
/// rooted at the given anchor.
|
||||
///
|
||||
/// \returns true if all of the parameters have been covered.
|
||||
static bool findArgumentLocations(
|
||||
Expr *anchor, ArrayRef<GenericTypeParamType *> genericParams,
|
||||
llvm::function_ref<void(TypeRepr *, GenericTypeParamType *)> callback);
|
||||
};
|
||||
|
||||
} // end namespace constraints
|
||||
} // end namespace swift
|
||||
|
||||
|
||||
@@ -6659,6 +6659,7 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyFixConstraint(
|
||||
case FixKind::AllowAnyObjectKeyPathRoot:
|
||||
case FixKind::TreatKeyPathSubscriptIndexAsHashable:
|
||||
case FixKind::AllowInvalidRefInKeyPath:
|
||||
case FixKind::ExplicitlySpecifyGenericArguments:
|
||||
llvm_unreachable("handled elsewhere");
|
||||
}
|
||||
|
||||
|
||||
@@ -275,8 +275,58 @@ StepResult ComponentStep::take(bool prevFailed) {
|
||||
// If there are no disjunctions or type variables to bind
|
||||
// we can't solve this system unless we have free type variables
|
||||
// allowed in the solution.
|
||||
if (!CS.solverState->allowsFreeTypeVariables() && CS.hasFreeTypeVariables())
|
||||
return done(/*isSuccess=*/false);
|
||||
if (!CS.solverState->allowsFreeTypeVariables() && CS.hasFreeTypeVariables()) {
|
||||
if (!CS.shouldAttemptFixes())
|
||||
return done(/*isSuccess=*/false);
|
||||
|
||||
// Let's see if all of the free type variables are associated with
|
||||
// generic parameters and if so, let's default them to `Any` and continue
|
||||
// solving so we can properly diagnose the problem later by suggesting
|
||||
// to explictly specify them.
|
||||
|
||||
llvm::SmallDenseMap<ConstraintLocator *,
|
||||
llvm::SmallVector<GenericTypeParamType *, 4>>
|
||||
defaultableGenericParams;
|
||||
|
||||
for (auto *typeVar : CS.getTypeVariables()) {
|
||||
if (typeVar->getImpl().hasRepresentativeOrFixed())
|
||||
continue;
|
||||
|
||||
// If this free type variable is not a generic parameter
|
||||
// we are done.
|
||||
auto *locator = typeVar->getImpl().getLocator();
|
||||
|
||||
auto *anchor = locator->getAnchor();
|
||||
if (!(anchor && locator->isForGenericParameter()))
|
||||
return done(/*isSuccess=*/false);
|
||||
|
||||
// Increment the score for every missing generic argument
|
||||
// to make ranking of the solutions with different number
|
||||
// of generic arguments easier.
|
||||
CS.increaseScore(ScoreKind::SK_Fix);
|
||||
// Default argument to `Any`.
|
||||
CS.assignFixedType(typeVar, CS.getASTContext().TheAnyType);
|
||||
// Note that this generic argument has been given a default value.
|
||||
CS.DefaultedConstraints.push_back(locator);
|
||||
|
||||
auto path = locator->getPath();
|
||||
// Let's drop `generic parameter '...'` part of the locator to
|
||||
// group all of the missing generic parameters related to the
|
||||
// same path together.
|
||||
defaultableGenericParams[CS.getConstraintLocator(anchor, path.drop_back(),
|
||||
/*summaryFlags=*/0)]
|
||||
.push_back(locator->getGenericParameter());
|
||||
}
|
||||
|
||||
for (const auto &missing : defaultableGenericParams) {
|
||||
auto *locator = missing.first;
|
||||
auto &missingParams = missing.second;
|
||||
auto *fix =
|
||||
ExplicitlySpecifyGenericArguments::create(CS, missingParams, locator);
|
||||
if (CS.recordFix(fix))
|
||||
return done(/*isSuccess=*/false);
|
||||
}
|
||||
}
|
||||
|
||||
// If this solution is worse than the best solution we've seen so far,
|
||||
// skip it.
|
||||
|
||||
@@ -100,13 +100,9 @@ void ConstraintSystem::incrementLeafScopes() {
|
||||
|
||||
bool ConstraintSystem::hasFreeTypeVariables() {
|
||||
// Look for any free type variables.
|
||||
for (auto tv : TypeVariables) {
|
||||
if (!tv->getImpl().hasRepresentativeOrFixed()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
return llvm::any_of(TypeVariables, [](const TypeVariableType *typeVar) {
|
||||
return !typeVar->getImpl().hasRepresentativeOrFixed();
|
||||
});
|
||||
}
|
||||
|
||||
void ConstraintSystem::addTypeVariable(TypeVariableType *typeVar) {
|
||||
|
||||
@@ -102,7 +102,7 @@ func longArray() {
|
||||
var _=["1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1"]
|
||||
}
|
||||
|
||||
[1,2].map // expected-error {{expression type '((Int) throws -> _) throws -> [_]' is ambiguous without more context}}
|
||||
[1,2].map // expected-error {{generic parameter 'T' could not be inferred}}
|
||||
|
||||
|
||||
// <rdar://problem/25563498> Type checker crash assigning array literal to type conforming to ArrayProtocol
|
||||
|
||||
@@ -223,7 +223,9 @@ func takesDictionary<K, V>(_ p: Dictionary<K, V>) {} // expected-note {{in call
|
||||
func takesArray<T>(_ t: Array<T>) {} // expected-note {{in call to function 'takesArray'}}
|
||||
func rdar19695671() {
|
||||
takesSet(NSSet() as! Set) // expected-error{{generic parameter 'T' could not be inferred}}
|
||||
takesDictionary(NSDictionary() as! Dictionary) // expected-error{{generic parameter 'K' could not be inferred}}
|
||||
takesDictionary(NSDictionary() as! Dictionary)
|
||||
// expected-error@-1 {{generic parameter 'K' could not be inferred}}
|
||||
// expected-error@-2 {{generic parameter 'V' could not be inferred}}
|
||||
takesArray(NSArray() as! Array) // expected-error{{generic parameter 'T' could not be inferred}}
|
||||
}
|
||||
|
||||
|
||||
@@ -716,7 +716,7 @@ func rdar37790062() {
|
||||
}
|
||||
|
||||
// <rdar://problem/39489003>
|
||||
typealias KeyedItem<K, T> = (key: K, value: T)
|
||||
typealias KeyedItem<K, T> = (key: K, value: T) // expected-note {{'T' declared as parameter to type 'KeyedItem'}}
|
||||
|
||||
protocol Node {
|
||||
associatedtype T
|
||||
@@ -730,8 +730,7 @@ extension Node {
|
||||
func getChild(for key:K)->(key: K, value: T) {
|
||||
return children.first(where: { (item:KeyedItem) -> Bool in
|
||||
return item.key == key
|
||||
// expected-error@-1 {{binary operator '==' cannot be applied to operands of type '_' and 'Self.K'}}
|
||||
// expected-note@-2 {{overloads for '==' exist with these partially matching parameter lists:}}
|
||||
// expected-error@-1 {{generic parameter 'T' could not be inferred}}
|
||||
})!
|
||||
}
|
||||
}
|
||||
@@ -814,13 +813,15 @@ func rdar_40537960() {
|
||||
init(_: P_40537960) {}
|
||||
}
|
||||
|
||||
struct A<T: Collection, P: P_40537960> {
|
||||
struct A<T: Collection, P: P_40537960> { // expected-note {{'P' declared as parameter to type 'A'}}
|
||||
typealias Data = T.Element
|
||||
init(_: T, fn: (Data) -> R<P>) {}
|
||||
}
|
||||
|
||||
var arr: [S] = []
|
||||
_ = A(arr, fn: { L($0.v) }) // expected-error {{cannot convert value of type 'L' to closure result type 'R<T>'}}
|
||||
_ = A(arr, fn: { L($0.v) }) // expected-error {{cannot convert value of type 'L' to closure result type 'R<Any>'}}
|
||||
// expected-error@-1 {{generic parameter 'P' could not be inferred}}
|
||||
// expected-note@-2 {{explicitly specify the generic arguments to fix this issue}} {{8-8=<[S], <#P: P_40537960#>>}}
|
||||
}
|
||||
|
||||
// rdar://problem/45659733
|
||||
|
||||
@@ -903,7 +903,7 @@ func test2208() {
|
||||
|
||||
// SR-2164: Erroneous diagnostic when unable to infer generic type
|
||||
|
||||
struct SR_2164<A, B> { // expected-note 3 {{'B' declared as parameter to type 'SR_2164'}} expected-note 2 {{'A' declared as parameter to type 'SR_2164'}} expected-note * {{generic type 'SR_2164' declared here}}
|
||||
struct SR_2164<A, B> { // expected-note 4 {{'B' declared as parameter to type 'SR_2164'}} expected-note 2 {{'A' declared as parameter to type 'SR_2164'}} expected-note * {{generic type 'SR_2164' declared here}}
|
||||
init(a: A) {}
|
||||
init(b: B) {}
|
||||
init(c: Int) {}
|
||||
@@ -921,7 +921,10 @@ struct SR_2164_Dict<A: Hashable, B> { // expected-note {{'B' declared as paramet
|
||||
|
||||
SR_2164(a: 0) // expected-error {{generic parameter 'B' could not be inferred}} expected-note {{explicitly specify the generic arguments to fix this issue}}
|
||||
SR_2164(b: 1) // expected-error {{generic parameter 'A' could not be inferred}} expected-note {{explicitly specify the generic arguments to fix this issue}}
|
||||
SR_2164(c: 2) // expected-error {{generic parameter 'A' could not be inferred}} expected-note {{explicitly specify the generic arguments to fix this issue}}
|
||||
SR_2164(c: 2)
|
||||
// expected-error@-1 {{generic parameter 'A' could not be inferred}}
|
||||
// expected-error@-2 {{generic parameter 'B' could not be inferred}}
|
||||
// expected-note@-3 {{explicitly specify the generic arguments to fix this issue}} {{8-8=<Any, Any>}}
|
||||
SR_2164(3) // expected-error {{generic parameter 'B' could not be inferred}} expected-note {{explicitly specify the generic arguments to fix this issue}}
|
||||
SR_2164_Array([4]) // expected-error {{generic parameter 'B' could not be inferred}} expected-note {{explicitly specify the generic arguments to fix this issue}}
|
||||
SR_2164(e: 5) // expected-error {{generic parameter 'B' could not be inferred}} expected-note {{explicitly specify the generic arguments to fix this issue}}
|
||||
|
||||
@@ -52,7 +52,7 @@ func generic_metatypes<T : SomeProtocol>(_ x: T)
|
||||
}
|
||||
|
||||
// Inferring a variable's type from a call to a generic.
|
||||
struct Pair<T, U> { } // expected-note 3 {{'T' declared as parameter to type 'Pair'}} expected-note 2 {{'U' declared as parameter to type 'Pair'}}
|
||||
struct Pair<T, U> { } // expected-note 3 {{'T' declared as parameter to type 'Pair'}} expected-note 3 {{'U' declared as parameter to type 'Pair'}}
|
||||
|
||||
func pair<T, U>(_ x: T, _ y: U) -> Pair<T, U> { }
|
||||
|
||||
@@ -219,8 +219,7 @@ protocol P19215114 {}
|
||||
func body9215114<T: P19215114, U: Q19215114>(_ t: T) -> (_ u: U) -> () {}
|
||||
|
||||
func test9215114<T: P19215114, U: Q19215114>(_ t: T) -> (U) -> () {
|
||||
//Should complain about not being able to infer type of U.
|
||||
let f = body9215114(t) // expected-error {{generic parameter 'T' could not be inferred}}
|
||||
let f = body9215114(t) // expected-error {{generic parameter 'U' could not be inferred}}
|
||||
return f
|
||||
}
|
||||
|
||||
@@ -231,7 +230,7 @@ class Whatever<A: Numeric, B: Numeric> { // expected-note 2 {{'A' declared as p
|
||||
static func bar() {}
|
||||
|
||||
}
|
||||
Whatever.foo(a: 23) // expected-error {{generic parameter 'A' could not be inferred}} expected-note {{explicitly specify the generic arguments to fix this issue}} {{9-9=<<#A: Numeric#>, <#B: Numeric#>>}}
|
||||
Whatever.foo(a: 23) // expected-error {{generic parameter 'A' could not be inferred}} expected-note {{explicitly specify the generic arguments to fix this issue}} {{9-9=<<#A: Numeric#>, Int>}}
|
||||
|
||||
// <rdar://problem/21718955> Swift useless error: cannot invoke 'foo' with no arguments
|
||||
Whatever.bar() // expected-error {{generic parameter 'A' could not be inferred}} expected-note {{explicitly specify the generic arguments to fix this issue}} {{9-9=<<#A: Numeric#>, <#B: Numeric#>>}}
|
||||
@@ -262,7 +261,7 @@ protocol SubProto: BaseProto {}
|
||||
func copy() -> Any
|
||||
}
|
||||
|
||||
struct FullyGeneric<Foo> {} // expected-note 11 {{'Foo' declared as parameter to type 'FullyGeneric'}} expected-note 1 {{generic type 'FullyGeneric' declared here}}
|
||||
struct FullyGeneric<Foo> {} // expected-note 13 {{'Foo' declared as parameter to type 'FullyGeneric'}} expected-note 1 {{generic type 'FullyGeneric' declared here}}
|
||||
|
||||
struct AnyClassBound<Foo: AnyObject> {} // expected-note {{'Foo' declared as parameter to type 'AnyClassBound'}} expected-note {{generic type 'AnyClassBound' declared here}}
|
||||
// expected-note@-1{{requirement specified as 'Foo' : 'AnyObject'}}
|
||||
@@ -340,7 +339,10 @@ func testFixIts() {
|
||||
// expected-error@-1 {{referencing initializer 'init()' on 'ClassAndProtosBound2' requires that 'X' conform to 'NSCopyish'}}
|
||||
// expected-error@-2 {{referencing initializer 'init()' on 'ClassAndProtosBound2' requires that 'X' conform to 'SubProto'}}
|
||||
|
||||
_ = Pair() // expected-error {{generic parameter 'T' could not be inferred}} expected-note {{explicitly specify the generic arguments to fix this issue}} {{11-11=<Any, Any>}}
|
||||
_ = Pair()
|
||||
// expected-error@-1 {{generic parameter 'T' could not be inferred}}
|
||||
// expected-error@-2 {{generic parameter 'U' could not be inferred}}
|
||||
// expected-note@-3 {{explicitly specify the generic arguments to fix this issue}} {{11-11=<Any, Any>}}
|
||||
_ = Pair(first: S()) // expected-error {{generic parameter 'U' could not be inferred}} expected-note {{explicitly specify the generic arguments to fix this issue}} {{11-11=<S, Any>}}
|
||||
_ = Pair(second: S()) // expected-error {{generic parameter 'T' could not be inferred}} expected-note {{explicitly specify the generic arguments to fix this issue}} {{11-11=<Any, S>}}
|
||||
}
|
||||
@@ -359,13 +361,13 @@ func testFixItClassBound() {
|
||||
}
|
||||
|
||||
func testFixItCasting(x: Any) {
|
||||
_ = x as! FullyGeneric // expected-error {{generic parameter 'Foo' could not be inferred in cast to 'FullyGeneric<_>'}} expected-note {{explicitly specify the generic arguments to fix this issue}} {{25-25=<Any>}}
|
||||
_ = x as! FullyGeneric // expected-error {{generic parameter 'Foo' could not be inferred}} expected-note {{explicitly specify the generic arguments to fix this issue}} {{25-25=<Any>}}
|
||||
}
|
||||
|
||||
func testFixItContextualKnowledge() {
|
||||
// FIXME: These could propagate backwards.
|
||||
let _: Int = Pair().first // expected-error {{generic parameter 'U' could not be inferred}} expected-note {{explicitly specify the generic arguments to fix this issue}} {{20-20=<Any, Any>}}
|
||||
let _: Int = Pair().second // expected-error {{generic parameter 'T' could not be inferred}} expected-note {{explicitly specify the generic arguments to fix this issue}} {{20-20=<Any, Any>}}
|
||||
let _: Int = Pair().first // expected-error {{generic parameter 'U' could not be inferred}} expected-note {{explicitly specify the generic arguments to fix this issue}} {{20-20=<Int, Any>}}
|
||||
let _: Int = Pair().second // expected-error {{generic parameter 'T' could not be inferred}} expected-note {{explicitly specify the generic arguments to fix this issue}} {{20-20=<Any, Int>}}
|
||||
}
|
||||
|
||||
func testFixItTypePosition() {
|
||||
@@ -382,32 +384,47 @@ func testFixItNested() {
|
||||
_ = [FullyGeneric]() // expected-error {{generic parameter 'Foo' could not be inferred}} expected-note {{explicitly specify the generic arguments to fix this issue}} {{20-20=<Any>}}
|
||||
|
||||
_ = FullyGeneric<FullyGeneric>() // expected-error {{generic parameter 'Foo' could not be inferred}}
|
||||
// expected-note@-1 {{explicitly specify the generic arguments to fix this issue}} {{32-32=<Any>}}
|
||||
|
||||
_ = Pair< // expected-error {{generic parameter 'Foo' could not be inferred}}
|
||||
_ = Pair<
|
||||
FullyGeneric,
|
||||
// expected-note@-1 {{explicitly specify the generic arguments to fix this issue}} {{17-17=<Any>}}
|
||||
FullyGeneric // FIXME: We could diagnose both of these, but we don't.
|
||||
// expected-error@-1 {{generic parameter 'Foo' could not be inferred}}
|
||||
// expected-note@-2 {{explicitly specify the generic arguments to fix this issue}} {{17-17=<Any>}}
|
||||
FullyGeneric
|
||||
// expected-error@-1 {{generic parameter 'Foo' could not be inferred}}
|
||||
// expected-note@-2 {{explicitly specify the generic arguments to fix this issue}} {{17-17=<Any>}}
|
||||
>()
|
||||
_ = Pair< // expected-error {{generic parameter 'Foo' could not be inferred}}
|
||||
_ = Pair<
|
||||
FullyGeneric<Any>,
|
||||
FullyGeneric
|
||||
// expected-error@-1 {{generic parameter 'Foo' could not be inferred}}
|
||||
// expected-note@-2 {{explicitly specify the generic arguments to fix this issue}} {{17-17=<Any>}}
|
||||
>()
|
||||
_ = Pair< // expected-error {{generic parameter 'Foo' could not be inferred}}
|
||||
_ = Pair<
|
||||
FullyGeneric,
|
||||
// expected-note@-1 {{explicitly specify the generic arguments to fix this issue}} {{17-17=<Any>}}
|
||||
// expected-error@-1 {{generic parameter 'Foo' could not be inferred}}
|
||||
// expected-note@-2 {{explicitly specify the generic arguments to fix this issue}} {{17-17=<Any>}}
|
||||
FullyGeneric<Any>
|
||||
>()
|
||||
|
||||
_ = pair( // expected-error {{generic parameter 'Foo' could not be inferred}} {{none}}
|
||||
FullyGeneric(), // expected-note {{explicitly specify the generic arguments to fix this issue}}
|
||||
_ = pair(
|
||||
FullyGeneric(),
|
||||
// expected-error@-1 {{generic parameter 'Foo' could not be inferred}}
|
||||
// expected-note@-2 {{explicitly specify the generic arguments to fix this issue}} {{17-17=<Any>}}
|
||||
FullyGeneric()
|
||||
// expected-error@-1 {{generic parameter 'Foo' could not be inferred}}
|
||||
// expected-note@-2 {{explicitly specify the generic arguments to fix this issue}} {{17-17=<Any>}}
|
||||
)
|
||||
_ = pair( // expected-error {{generic parameter 'Foo' could not be inferred}} {{none}}
|
||||
_ = pair(
|
||||
FullyGeneric<Any>(),
|
||||
FullyGeneric() // expected-note {{explicitly specify the generic arguments to fix this issue}}
|
||||
FullyGeneric()
|
||||
// expected-error@-1 {{generic parameter 'Foo' could not be inferred}}
|
||||
// expected-note@-2 {{explicitly specify the generic arguments to fix this issue}} {{17-17=<Any>}}
|
||||
)
|
||||
_ = pair( // expected-error {{generic parameter 'Foo' could not be inferred}} {{none}}
|
||||
FullyGeneric(), // expected-note {{explicitly specify the generic arguments to fix this issue}}
|
||||
_ = pair(
|
||||
FullyGeneric(),
|
||||
// expected-error@-1 {{generic parameter 'Foo' could not be inferred}}
|
||||
// expected-note@-2 {{explicitly specify the generic arguments to fix this issue}} {{17-17=<Any>}}
|
||||
FullyGeneric<Any>()
|
||||
)
|
||||
}
|
||||
@@ -435,7 +452,7 @@ class GenericClass<A> {}
|
||||
func genericFunc<T>(t: T) {
|
||||
_ = [T: GenericClass] // expected-error {{generic parameter 'A' could not be inferred}}
|
||||
// expected-note@-1 {{explicitly specify the generic arguments to fix this issue}}
|
||||
// expected-error@-2 3 {{type 'T' does not conform to protocol 'Hashable'}}
|
||||
// expected-error@-2 {{type 'T' does not conform to protocol 'Hashable'}}
|
||||
}
|
||||
|
||||
struct SR_3525<T> {}
|
||||
@@ -707,3 +724,26 @@ struct SR10694 {
|
||||
// expected-error@-1 {{initializing from a metatype value must reference 'init' explicitly}}
|
||||
}
|
||||
}
|
||||
|
||||
// SR-7003 (rdar://problem/51203824) - Poor diagnostics when attempting to access members on unfulfilled generic type
|
||||
func sr_7003() {
|
||||
struct E<T> { // expected-note 4 {{'T' declared as parameter to type 'E'}}
|
||||
static var foo: String { return "" }
|
||||
var bar: String { return "" }
|
||||
static func baz() -> String { return "" }
|
||||
func qux() -> String { return "" }
|
||||
}
|
||||
|
||||
let _: Any = E.foo
|
||||
// expected-error@-1 {{generic parameter 'T' could not be inferred}}
|
||||
// expected-note@-2 {{explicitly specify the generic arguments to fix this issue}} {{17-17=<Any>}}
|
||||
let _: Any = E().bar
|
||||
// expected-error@-1 {{generic parameter 'T' could not be inferred}}
|
||||
// expected-note@-2 {{explicitly specify the generic arguments to fix this issue}} {{17-17=<Any>}}
|
||||
let _: Any = E.baz()
|
||||
// expected-error@-1 {{generic parameter 'T' could not be inferred}}
|
||||
// expected-note@-2 {{explicitly specify the generic arguments to fix this issue}} {{17-17=<Any>}}
|
||||
let _: Any = E().qux()
|
||||
// expected-error@-1 {{generic parameter 'T' could not be inferred}}
|
||||
// expected-note@-2 {{explicitly specify the generic arguments to fix this issue}} {{17-17=<Any>}}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
// RUN: %target-typecheck-verify-swift
|
||||
|
||||
struct MyCollection<Element> { // expected-note {{'Element' declared as parameter to type 'MyCollection'}}
|
||||
func map<T>(_ transform: (Element) -> T) -> MyCollection<T> {
|
||||
func map<T>(_ transform: (Element) -> T) -> MyCollection<T> { // expected-note 2 {{in call to function 'map'}}
|
||||
fatalError("implement")
|
||||
}
|
||||
}
|
||||
|
||||
MyCollection.map // expected-error{{generic parameter 'Element' could not be inferred}} expected-note {{explicitly specify the generic arguments to fix this issue}} {{13-13=<Any>}}
|
||||
// expected-error@-1 {{generic parameter 'T' could not be inferred}}
|
||||
|
||||
let a = MyCollection<Int>()
|
||||
a.map // expected-error{{generic parameter 'T' could not be inferred}}
|
||||
|
||||
@@ -347,7 +347,9 @@ func trailingClosure5<T>(_ file: String = #file, line: UInt = #line, expression:
|
||||
func trailingClosure6<T>(value: Int, expression: () -> T?) { }
|
||||
|
||||
trailingClosure5(file: "hello", line: 17) { return Optional.Some(5) } // expected-error{{extraneous argument label 'file:' in call}}{{18-24=}}
|
||||
// expected-error@-1 {{enum type 'Optional<Any>' has no case 'Some'; did you mean 'some'}} {{61-65=some}}
|
||||
trailingClosure6(5) { return Optional.Some(5) } // expected-error{{missing argument label 'value:' in call}}{{18-18=value: }}
|
||||
// expected-error@-1 {{enum type 'Optional<Any>' has no case 'Some'; did you mean 'some'}} {{39-43=some}}
|
||||
|
||||
class MismatchOverloaded1 {
|
||||
func method1(_ x: Int!, arg: ((Int) -> Int)!) { }
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
struct D {}
|
||||
|
||||
class Future<T> {
|
||||
func then<U>(_ fn: @escaping (T) -> Future<U>) -> Future<U> { fatalError() }
|
||||
func then<U>(_ fn: @escaping (T) -> Future<U>) -> Future<U> { fatalError() } // expected-note {{in call to function 'then'}}
|
||||
func thenThrowing<U>(_ fn: @escaping (T) throws -> U) -> Future<U> { fatalError() }
|
||||
func whenFailure(_ fn: @escaping (Error) -> Void) {}
|
||||
|
||||
@@ -12,21 +12,18 @@ class Future<T> {
|
||||
|
||||
protocol P {
|
||||
func foo(arr: [D], data: ArraySlice<UInt8>) -> Future<D>
|
||||
// expected-note@-1 {{found this candidate}}
|
||||
func bar(root: D, from: P) -> Future<D>
|
||||
}
|
||||
|
||||
extension P {
|
||||
func foo(arr: [D] = [], data: [UInt8]) -> Future<D> { fatalError() }
|
||||
// expected-note@-1 {{found this candidate}}
|
||||
}
|
||||
|
||||
func crash(_ p: P, payload: [UInt8]) throws {
|
||||
p.foo(data: payload).then { _ in
|
||||
return Future<(D, [D])>()
|
||||
}.then { (id, arr) in
|
||||
}.then { (id, arr) in // expected-error {{generic parameter 'U' could not be inferred}}
|
||||
p.foo(arr: arr, data: []).and(result: (id, arr))
|
||||
// expected-error@-1 {{mbiguous reference to member 'foo(arr:data:)'}}
|
||||
}.then { args0 in
|
||||
let (parentID, args1) = args0
|
||||
p.bar(root: parentID, from: p).and(args1)
|
||||
|
||||
@@ -219,13 +219,13 @@ extension r25271859 {
|
||||
func map<U>(f: (T) -> U) -> r25271859<U> {
|
||||
}
|
||||
|
||||
func andThen<U>(f: (T) -> r25271859<U>) {
|
||||
func andThen<U>(f: (T) -> r25271859<U>) { // expected-note {{in call to function 'andThen(f:)'}}
|
||||
}
|
||||
}
|
||||
|
||||
func f(a : r25271859<(Float, Int)>) {
|
||||
a.map { $0.0 }
|
||||
.andThen { _ in // expected-error {{unable to infer complex closure return type; add explicit type to disambiguate}} {{18-18=-> r25271859<String> }}
|
||||
a.map { $0.0 } // expected-error {{generic parameter 'U' could not be inferred}} (This is related to how solver is setup with multiple statements)
|
||||
.andThen { _ in
|
||||
print("hello") // comment this out and it runs, leave any form of print in and it doesn't
|
||||
return r25271859<String>()
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ struct Lunch<T> {
|
||||
}
|
||||
}
|
||||
|
||||
class Deli<Spices> {
|
||||
class Deli<Spices> { // expected-note {{'Spices' declared as parameter to type 'Deli'}}
|
||||
|
||||
class Pepperoni {}
|
||||
struct Sausage {}
|
||||
@@ -79,7 +79,8 @@ func badDiagnostic2() {
|
||||
func takesAny(_ a: Any) {}
|
||||
|
||||
func badDiagnostic3() {
|
||||
takesAny(Deli.self) // expected-error {{argument type 'Deli<_>.Type' does not conform to expected type 'Any'}}
|
||||
takesAny(Deli.self) // expected-error {{generic parameter 'Spices' could not be inferred}}
|
||||
// expected-note@-1 {{explicitly specify the generic arguments to fix this issue}} {{16-16=<Any>}}
|
||||
}
|
||||
|
||||
// Crash with missing nested type inside concrete type
|
||||
|
||||
@@ -121,7 +121,7 @@ protocol P {} // expected-error {{invalid redeclaration of 'P'}}
|
||||
// expected-note@-1 {{did you mean 'P'?}}
|
||||
|
||||
func hasTypo() {
|
||||
_ = P.a.a // expected-error {{type 'Generic<_>' has no member 'a'}}
|
||||
_ = P.a.a // expected-error {{type 'Generic<Any>' has no member 'a'}}
|
||||
}
|
||||
|
||||
// Typo correction with AnyObject.
|
||||
|
||||
@@ -390,7 +390,8 @@ func testPostfixOperatorOnTuple<A, B>(a: A, b: B) {
|
||||
_ = (§)foo
|
||||
// expected-error@-1 {{consecutive statements on a line must be separated by ';'}}
|
||||
// expected-error@-2 {{generic parameter 'T' could not be inferred}}
|
||||
// expected-warning@-3 {{expression of type '(A, (B, B), A)' is unused}}
|
||||
// expected-error@-3 {{generic parameter 'U' could not be inferred}}
|
||||
// expected-warning@-4 {{expression of type '(A, (B, B), A)' is unused}}
|
||||
_ = (§)(foo)
|
||||
_ = (a, (b, b), a)§
|
||||
_ = (§)(a, (b, b), a) // expected-error {{operator function '§' expects a single parameter of type '(T, (U, U), T)'}}
|
||||
|
||||
@@ -377,7 +377,7 @@ protocol ExpressibleByDogLiteral {}
|
||||
struct Kitten : ExpressibleByCatLiteral {}
|
||||
struct Puppy : ExpressibleByDogLiteral {}
|
||||
|
||||
struct Claws<A: ExpressibleByCatLiteral> {
|
||||
struct Claws<A: ExpressibleByCatLiteral> { // expected-note 3 {{'A' declared as parameter to type 'Claws'}}
|
||||
struct Fangs<B: ExpressibleByDogLiteral> { } // expected-note {{where 'B' = 'NotADog'}}
|
||||
}
|
||||
|
||||
@@ -387,7 +387,7 @@ func pets<T>(fur: T) -> Claws<Kitten>.Fangs<T> {
|
||||
return Claws<Kitten>.Fangs<T>()
|
||||
}
|
||||
|
||||
func something<T>() -> T { // expected-note {{in call to function 'something()'}}
|
||||
func something<T>() -> T {
|
||||
while true {}
|
||||
}
|
||||
|
||||
@@ -398,11 +398,14 @@ func test() {
|
||||
let _: Claws.Fangs<Puppy> = pets(fur: Puppy())
|
||||
let _: Claws.Fangs<Puppy> = Claws<Kitten>.Fangs()
|
||||
let _: Claws.Fangs<Puppy> = Claws.Fangs()
|
||||
// expected-error@-1 {{cannot convert value of type 'Claws<_>.Fangs<_>' to specified type 'Claws.Fangs<Puppy>'}}
|
||||
// expected-error@-1 {{generic parameter 'A' could not be inferred}}
|
||||
// expected-note@-2 {{explicitly specify the generic arguments to fix this issue}} {{36-36=<<#A: ExpressibleByCatLiteral#>>}}
|
||||
let _: Claws.Fangs<NotADog> = something()
|
||||
// expected-error@-1 {{generic parameter 'T' could not be inferred}} // FIXME: bad diagnostic
|
||||
_ = Claws.Fangs<NotADog>() // TODO(diagnostics): There should be two errors here - "cannot infer A" and "NotADog conformance to ExpressibleByDogLiteral"
|
||||
// expected-error@-1 {{referencing initializer 'init()' on 'Claws.Fangs' requires that 'NotADog' conform to 'ExpressibleByDogLiteral'}}
|
||||
// expected-error@-1 {{generic parameter 'A' could not be inferred}}
|
||||
_ = Claws.Fangs<NotADog>()
|
||||
// expected-error@-1 {{generic parameter 'A' could not be inferred}}
|
||||
// expected-error@-2 {{referencing initializer 'init()' on 'Claws.Fangs' requires that 'NotADog' conform to 'ExpressibleByDogLiteral'}}
|
||||
// expected-note@-3 {{explicitly specify the generic arguments to fix this issue}} {{12-12=<<#A: ExpressibleByCatLiteral#>>}}
|
||||
}
|
||||
|
||||
// https://bugs.swift.org/browse/SR-4379
|
||||
|
||||
@@ -60,7 +60,7 @@ typealias B<T1> = MyType<T1, T1> // expected-note {{'T1' declared as parameter
|
||||
typealias C<T> = MyType<String, T>
|
||||
|
||||
// Type aliases with unused generic params.
|
||||
typealias D<T1, T2, T3> = MyType<T2, T1> // expected-note {{'T3' declared as parameter to type 'D'}}
|
||||
typealias D<T1, T2, T3> = MyType<T2, T1> // expected-note 3 {{'T3' declared as parameter to type 'D'}}
|
||||
|
||||
typealias E<T1, T2> = Int // expected-note {{generic type 'E' declared here}}
|
||||
|
||||
@@ -72,17 +72,18 @@ typealias G<S1, S2> = A<S1, S2>
|
||||
let _ : E<Int, Float> = 42
|
||||
let _ : E<Float> = 42 // expected-error {{generic type 'E' specialized with too few type parameters (got 1, but expected 2)}}
|
||||
let _ : E = 42 // expected-error {{cannot convert value of type 'Int' to specified type 'E'}}
|
||||
let _ : D = D(a: 1, b: 2) // expected-error {{cannot convert value of type 'MyType<Int, Int>' to specified type 'D'}}
|
||||
let _ : D = D(a: 1, b: 2)
|
||||
// expected-error@-1 {{generic parameter 'T3' could not be inferred}}
|
||||
// expected-note@-2 {{explicitly specify the generic arguments to fix this issue}} {{14-14=<Int, Int, Any>}}
|
||||
|
||||
let _ : D<Int, Int, Float> = D<Int, Int, Float>(a: 1, b: 2)
|
||||
|
||||
// FIXME: This is not a great error.
|
||||
// expected-error @+1 {{cannot convert value of type 'D<Int, Int, Float>' (aka 'MyType<Int, Int>') to specified type 'D'}}
|
||||
let _ : D = D<Int, Int, Float>(a: 1, b: 2)
|
||||
// expected-error@-1 {{generic parameter 'T3' could not be inferred}}
|
||||
|
||||
|
||||
// expected-error @+2 {{generic parameter 'T3' could not be inferred}}
|
||||
// expected-note @+1 {{explicitly specify the generic arguments to fix this issue}} {{31-31=<Any, Any, Any>}}
|
||||
// expected-note @+1 {{explicitly specify the generic arguments to fix this issue}} {{31-31=<Int, Int, Any>}}
|
||||
let _ : D<Int, Int, Float> = D(a: 1, b: 2)
|
||||
|
||||
let _ : F = { (a : Int) -> Int in a } // Infer the types of F
|
||||
|
||||
@@ -15,7 +15,7 @@ e1 = .Third(5, 3.14159)
|
||||
e1 = .default // SE-0071
|
||||
|
||||
// Generic enumeration type
|
||||
enum E2<T> {
|
||||
enum E2<T> { // expected-note {{'T' declared as parameter to type 'E2'}}
|
||||
case First
|
||||
case Second(T)
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ struct A: Hashable {
|
||||
func hash(into hasher: inout Hasher) { fatalError() }
|
||||
}
|
||||
struct B {}
|
||||
struct C<T> {
|
||||
struct C<T> { // expected-note 2 {{'T' declared as parameter to type 'C'}}
|
||||
var value: T
|
||||
subscript() -> T { get { return value } }
|
||||
subscript(sub: Sub) -> T { get { return value } set { } }
|
||||
@@ -190,7 +190,7 @@ func testKeyPath(sub: Sub, optSub: OptSub,
|
||||
let _: AnyKeyPath = \A.property
|
||||
let _: AnyKeyPath = \C<A>.value
|
||||
let _: AnyKeyPath = \.property // expected-error{{ambiguous}}
|
||||
let _: AnyKeyPath = \C.value // expected-error{{cannot convert}} (need to improve diagnostic)
|
||||
let _: AnyKeyPath = \C.value // expected-error{{generic parameter 'T' could not be inferred}}
|
||||
let _: AnyKeyPath = \.value // expected-error{{ambiguous}}
|
||||
|
||||
let _ = \Prop.[nonHashableSub] // expected-error{{subscript index of type 'NonHashableSub' in a key path must be Hashable}}
|
||||
@@ -282,9 +282,8 @@ func tupleGeneric<T, U>(_ v: (T, U)) {
|
||||
|
||||
_ = ("tuple", "too", "big")[keyPath: tuple_el_1()]
|
||||
// expected-note@-12 {{}}
|
||||
// expected-error@-2 {{cannot be applied}}
|
||||
// expected-error@-3 {{cannot be applied}}
|
||||
// expected-error@-4 {{could not be inferred}}
|
||||
// expected-error@-2 {{generic parameter 'T' could not be inferred}}
|
||||
// expected-error@-3 {{generic parameter 'U' could not be inferred}}
|
||||
}
|
||||
|
||||
struct Z { }
|
||||
|
||||
@@ -49,32 +49,32 @@ func mismatchedAppends<T, U, V>(readOnlyLeft: KeyPath<T, U>,
|
||||
readOnlyRight: KeyPath<U, V>,
|
||||
writableRight: WritableKeyPath<U, V>,
|
||||
referenceRight: ReferenceWritableKeyPath<U, V>){
|
||||
// expected-error@+1{{}}
|
||||
_ = readOnlyRight.appending(path: readOnlyLeft)
|
||||
// expected-error@-1 {{referencing instance method 'appending(path:)' on '_AppendKeyPath' requires the types 'KeyPath<U, V>' and 'AnyKeyPath' be equivalent}}
|
||||
|
||||
// expected-error@+1{{}}
|
||||
_ = readOnlyRight.appending(path: writableLeft)
|
||||
// expected-error@-1 {{referencing instance method 'appending(path:)' on '_AppendKeyPath' requires the types 'KeyPath<U, V>' and 'AnyKeyPath' be equivalent}}
|
||||
|
||||
// expected-error@+1{{}}
|
||||
_ = readOnlyRight.appending(path: referenceLeft)
|
||||
// expected-error@-1 {{referencing instance method 'appending(path:)' on '_AppendKeyPath' requires the types 'KeyPath<U, V>' and 'AnyKeyPath' be equivalent}}
|
||||
|
||||
// expected-error@+1{{}}
|
||||
_ = writableRight.appending(path: readOnlyLeft)
|
||||
// expected-error@-1 {{referencing instance method 'appending(path:)' on '_AppendKeyPath' requires the types 'WritableKeyPath<U, V>' and 'AnyKeyPath' be equivalent}}
|
||||
|
||||
// expected-error@+1{{}}
|
||||
_ = writableRight.appending(path: writableLeft)
|
||||
// expected-error@-1 {{referencing instance method 'appending(path:)' on '_AppendKeyPath' requires the types 'WritableKeyPath<U, V>' and 'AnyKeyPath' be equivalent}}
|
||||
|
||||
// expected-error@+1{{}}
|
||||
_ = writableRight.appending(path: referenceLeft)
|
||||
// expected-error@-1 {{referencing instance method 'appending(path:)' on '_AppendKeyPath' requires the types 'WritableKeyPath<U, V>' and 'AnyKeyPath' be equivalent}}
|
||||
|
||||
// expected-error@+1{{}}
|
||||
_ = referenceRight.appending(path: readOnlyLeft)
|
||||
// expected-error@-1 {{referencing instance method 'appending(path:)' on '_AppendKeyPath' requires the types 'ReferenceWritableKeyPath<U, V>' and 'AnyKeyPath' be equivalent}}
|
||||
|
||||
// expected-error@+1{{}}
|
||||
_ = referenceRight.appending(path: writableLeft)
|
||||
// expected-error@-1 {{referencing instance method 'appending(path:)' on '_AppendKeyPath' requires the types 'ReferenceWritableKeyPath<U, V>' and 'AnyKeyPath' be equivalent}}
|
||||
|
||||
// expected-error@+1{{}}
|
||||
_ = referenceRight.appending(path: referenceLeft)
|
||||
// expected-error@-1 {{referencing instance method 'appending(path:)' on '_AppendKeyPath' requires the types 'ReferenceWritableKeyPath<U, V>' and 'AnyKeyPath' be equivalent}}
|
||||
}
|
||||
|
||||
func partialAppends<T, U, V>(partial: PartialKeyPath<T>,
|
||||
|
||||
Reference in New Issue
Block a user