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,
|
ArrayRef<TypeRepr*> GenericArgs,
|
||||||
SourceRange AngleBrackets);
|
SourceRange AngleBrackets);
|
||||||
|
|
||||||
|
unsigned getNumGenericArgs() const {
|
||||||
|
return Bits.GenericIdentTypeRepr.NumGenericArgs;
|
||||||
|
}
|
||||||
|
|
||||||
ArrayRef<TypeRepr*> getGenericArgs() const {
|
ArrayRef<TypeRepr*> getGenericArgs() const {
|
||||||
return {getTrailingObjects<TypeRepr*>(),
|
return {getTrailingObjects<TypeRepr*>(),
|
||||||
Bits.GenericIdentTypeRepr.NumGenericArgs};
|
Bits.GenericIdentTypeRepr.NumGenericArgs};
|
||||||
|
|||||||
@@ -1244,14 +1244,11 @@ class MissingGenericArgumentsFailure final : public FailureDiagnostic {
|
|||||||
public:
|
public:
|
||||||
MissingGenericArgumentsFailure(Expr *root, ConstraintSystem &cs,
|
MissingGenericArgumentsFailure(Expr *root, ConstraintSystem &cs,
|
||||||
TypeRepr *baseType,
|
TypeRepr *baseType,
|
||||||
ArrayRef<TypeVariableType *> missingParams,
|
ArrayRef<GenericTypeParamType *> missingParams,
|
||||||
ConstraintLocator *locator)
|
ConstraintLocator *locator)
|
||||||
: FailureDiagnostic(root, cs, locator), BaseType(baseType) {
|
: FailureDiagnostic(root, cs, locator), BaseType(baseType) {
|
||||||
assert(!missingParams.empty());
|
assert(!missingParams.empty());
|
||||||
llvm::transform(missingParams, std::back_inserter(Parameters),
|
Parameters.append(missingParams.begin(), missingParams.end());
|
||||||
[](const TypeVariableType *GP) {
|
|
||||||
return GP->getImpl().getGenericParameter();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SourceLoc getLoc() const;
|
SourceLoc getLoc() const;
|
||||||
|
|||||||
@@ -540,3 +540,110 @@ CollectionElementContextualMismatch::create(ConstraintSystem &cs, Type srcType,
|
|||||||
return new (cs.getAllocator())
|
return new (cs.getAllocator())
|
||||||
CollectionElementContextualMismatch(cs, srcType, dstType, locator);
|
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
|
/// Remove `return` or default last expression of single expression
|
||||||
/// function to `Void` to conform to expected result type.
|
/// function to `Void` to conform to expected result type.
|
||||||
RemoveReturn,
|
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 {
|
class ConstraintFix {
|
||||||
@@ -917,6 +922,53 @@ public:
|
|||||||
ConstraintLocator *locator);
|
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 constraints
|
||||||
} // end namespace swift
|
} // end namespace swift
|
||||||
|
|
||||||
|
|||||||
@@ -6659,6 +6659,7 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyFixConstraint(
|
|||||||
case FixKind::AllowAnyObjectKeyPathRoot:
|
case FixKind::AllowAnyObjectKeyPathRoot:
|
||||||
case FixKind::TreatKeyPathSubscriptIndexAsHashable:
|
case FixKind::TreatKeyPathSubscriptIndexAsHashable:
|
||||||
case FixKind::AllowInvalidRefInKeyPath:
|
case FixKind::AllowInvalidRefInKeyPath:
|
||||||
|
case FixKind::ExplicitlySpecifyGenericArguments:
|
||||||
llvm_unreachable("handled elsewhere");
|
llvm_unreachable("handled elsewhere");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -275,8 +275,58 @@ StepResult ComponentStep::take(bool prevFailed) {
|
|||||||
// If there are no disjunctions or type variables to bind
|
// If there are no disjunctions or type variables to bind
|
||||||
// we can't solve this system unless we have free type variables
|
// we can't solve this system unless we have free type variables
|
||||||
// allowed in the solution.
|
// allowed in the solution.
|
||||||
if (!CS.solverState->allowsFreeTypeVariables() && CS.hasFreeTypeVariables())
|
if (!CS.solverState->allowsFreeTypeVariables() && CS.hasFreeTypeVariables()) {
|
||||||
return done(/*isSuccess=*/false);
|
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,
|
// If this solution is worse than the best solution we've seen so far,
|
||||||
// skip it.
|
// skip it.
|
||||||
|
|||||||
@@ -100,13 +100,9 @@ void ConstraintSystem::incrementLeafScopes() {
|
|||||||
|
|
||||||
bool ConstraintSystem::hasFreeTypeVariables() {
|
bool ConstraintSystem::hasFreeTypeVariables() {
|
||||||
// Look for any free type variables.
|
// Look for any free type variables.
|
||||||
for (auto tv : TypeVariables) {
|
return llvm::any_of(TypeVariables, [](const TypeVariableType *typeVar) {
|
||||||
if (!tv->getImpl().hasRepresentativeOrFixed()) {
|
return !typeVar->getImpl().hasRepresentativeOrFixed();
|
||||||
return true;
|
});
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConstraintSystem::addTypeVariable(TypeVariableType *typeVar) {
|
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"]
|
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
|
// <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 takesArray<T>(_ t: Array<T>) {} // expected-note {{in call to function 'takesArray'}}
|
||||||
func rdar19695671() {
|
func rdar19695671() {
|
||||||
takesSet(NSSet() as! Set) // expected-error{{generic parameter 'T' could not be inferred}}
|
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}}
|
takesArray(NSArray() as! Array) // expected-error{{generic parameter 'T' could not be inferred}}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -716,7 +716,7 @@ func rdar37790062() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// <rdar://problem/39489003>
|
// <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 {
|
protocol Node {
|
||||||
associatedtype T
|
associatedtype T
|
||||||
@@ -730,8 +730,7 @@ extension Node {
|
|||||||
func getChild(for key:K)->(key: K, value: T) {
|
func getChild(for key:K)->(key: K, value: T) {
|
||||||
return children.first(where: { (item:KeyedItem) -> Bool in
|
return children.first(where: { (item:KeyedItem) -> Bool in
|
||||||
return item.key == key
|
return item.key == key
|
||||||
// expected-error@-1 {{binary operator '==' cannot be applied to operands of type '_' and 'Self.K'}}
|
// expected-error@-1 {{generic parameter 'T' could not be inferred}}
|
||||||
// expected-note@-2 {{overloads for '==' exist with these partially matching parameter lists:}}
|
|
||||||
})!
|
})!
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -814,13 +813,15 @@ func rdar_40537960() {
|
|||||||
init(_: P_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
|
typealias Data = T.Element
|
||||||
init(_: T, fn: (Data) -> R<P>) {}
|
init(_: T, fn: (Data) -> R<P>) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
var arr: [S] = []
|
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
|
// rdar://problem/45659733
|
||||||
|
|||||||
@@ -903,7 +903,7 @@ func test2208() {
|
|||||||
|
|
||||||
// SR-2164: Erroneous diagnostic when unable to infer generic type
|
// 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(a: A) {}
|
||||||
init(b: B) {}
|
init(b: B) {}
|
||||||
init(c: Int) {}
|
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(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(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(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_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}}
|
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.
|
// 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> { }
|
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 body9215114<T: P19215114, U: Q19215114>(_ t: T) -> (_ u: U) -> () {}
|
||||||
|
|
||||||
func test9215114<T: P19215114, U: Q19215114>(_ t: T) -> (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 'U' could not be inferred}}
|
||||||
let f = body9215114(t) // expected-error {{generic parameter 'T' could not be inferred}}
|
|
||||||
return f
|
return f
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -231,7 +230,7 @@ class Whatever<A: Numeric, B: Numeric> { // expected-note 2 {{'A' declared as p
|
|||||||
static func bar() {}
|
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
|
// <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#>>}}
|
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
|
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}}
|
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'}}
|
// 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@-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'}}
|
// 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(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>}}
|
_ = 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) {
|
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() {
|
func testFixItContextualKnowledge() {
|
||||||
// FIXME: These could propagate backwards.
|
// 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().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, 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() {
|
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]() // 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}}
|
_ = 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,
|
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}}
|
||||||
FullyGeneric // FIXME: We could diagnose both of these, but we don't.
|
// 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<Any>,
|
||||||
FullyGeneric
|
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,
|
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>
|
FullyGeneric<Any>
|
||||||
>()
|
>()
|
||||||
|
|
||||||
_ = pair( // expected-error {{generic parameter 'Foo' could not be inferred}} {{none}}
|
_ = pair(
|
||||||
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>}}
|
||||||
FullyGeneric()
|
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<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}}
|
_ = pair(
|
||||||
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>}}
|
||||||
FullyGeneric<Any>()
|
FullyGeneric<Any>()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -435,7 +452,7 @@ class GenericClass<A> {}
|
|||||||
func genericFunc<T>(t: T) {
|
func genericFunc<T>(t: T) {
|
||||||
_ = [T: GenericClass] // expected-error {{generic parameter 'A' could not be inferred}}
|
_ = [T: GenericClass] // expected-error {{generic parameter 'A' could not be inferred}}
|
||||||
// expected-note@-1 {{explicitly specify the generic arguments to fix this issue}}
|
// 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> {}
|
struct SR_3525<T> {}
|
||||||
@@ -707,3 +724,26 @@ struct SR10694 {
|
|||||||
// expected-error@-1 {{initializing from a metatype value must reference 'init' explicitly}}
|
// 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
|
// RUN: %target-typecheck-verify-swift
|
||||||
|
|
||||||
struct MyCollection<Element> { // expected-note {{'Element' declared as parameter to type 'MyCollection'}}
|
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")
|
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>}}
|
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>()
|
let a = MyCollection<Int>()
|
||||||
a.map // expected-error{{generic parameter 'T' could not be inferred}}
|
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?) { }
|
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=}}
|
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: }}
|
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 {
|
class MismatchOverloaded1 {
|
||||||
func method1(_ x: Int!, arg: ((Int) -> Int)!) { }
|
func method1(_ x: Int!, arg: ((Int) -> Int)!) { }
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
struct D {}
|
struct D {}
|
||||||
|
|
||||||
class Future<T> {
|
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 thenThrowing<U>(_ fn: @escaping (T) throws -> U) -> Future<U> { fatalError() }
|
||||||
func whenFailure(_ fn: @escaping (Error) -> Void) {}
|
func whenFailure(_ fn: @escaping (Error) -> Void) {}
|
||||||
|
|
||||||
@@ -12,21 +12,18 @@ class Future<T> {
|
|||||||
|
|
||||||
protocol P {
|
protocol P {
|
||||||
func foo(arr: [D], data: ArraySlice<UInt8>) -> Future<D>
|
func foo(arr: [D], data: ArraySlice<UInt8>) -> Future<D>
|
||||||
// expected-note@-1 {{found this candidate}}
|
|
||||||
func bar(root: D, from: P) -> Future<D>
|
func bar(root: D, from: P) -> Future<D>
|
||||||
}
|
}
|
||||||
|
|
||||||
extension P {
|
extension P {
|
||||||
func foo(arr: [D] = [], data: [UInt8]) -> Future<D> { fatalError() }
|
func foo(arr: [D] = [], data: [UInt8]) -> Future<D> { fatalError() }
|
||||||
// expected-note@-1 {{found this candidate}}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func crash(_ p: P, payload: [UInt8]) throws {
|
func crash(_ p: P, payload: [UInt8]) throws {
|
||||||
p.foo(data: payload).then { _ in
|
p.foo(data: payload).then { _ in
|
||||||
return Future<(D, [D])>()
|
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))
|
p.foo(arr: arr, data: []).and(result: (id, arr))
|
||||||
// expected-error@-1 {{mbiguous reference to member 'foo(arr:data:)'}}
|
|
||||||
}.then { args0 in
|
}.then { args0 in
|
||||||
let (parentID, args1) = args0
|
let (parentID, args1) = args0
|
||||||
p.bar(root: parentID, from: p).and(args1)
|
p.bar(root: parentID, from: p).and(args1)
|
||||||
|
|||||||
@@ -219,13 +219,13 @@ extension r25271859 {
|
|||||||
func map<U>(f: (T) -> U) -> r25271859<U> {
|
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)>) {
|
func f(a : r25271859<(Float, Int)>) {
|
||||||
a.map { $0.0 }
|
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 // expected-error {{unable to infer complex closure return type; add explicit type to disambiguate}} {{18-18=-> r25271859<String> }}
|
.andThen { _ in
|
||||||
print("hello") // comment this out and it runs, leave any form of print in and it doesn't
|
print("hello") // comment this out and it runs, leave any form of print in and it doesn't
|
||||||
return r25271859<String>()
|
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 {}
|
class Pepperoni {}
|
||||||
struct Sausage {}
|
struct Sausage {}
|
||||||
@@ -79,7 +79,8 @@ func badDiagnostic2() {
|
|||||||
func takesAny(_ a: Any) {}
|
func takesAny(_ a: Any) {}
|
||||||
|
|
||||||
func badDiagnostic3() {
|
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
|
// 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'?}}
|
// expected-note@-1 {{did you mean 'P'?}}
|
||||||
|
|
||||||
func hasTypo() {
|
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.
|
// Typo correction with AnyObject.
|
||||||
|
|||||||
@@ -390,7 +390,8 @@ func testPostfixOperatorOnTuple<A, B>(a: A, b: B) {
|
|||||||
_ = (§)foo
|
_ = (§)foo
|
||||||
// expected-error@-1 {{consecutive statements on a line must be separated by ';'}}
|
// expected-error@-1 {{consecutive statements on a line must be separated by ';'}}
|
||||||
// expected-error@-2 {{generic parameter 'T' could not be inferred}}
|
// 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)
|
_ = (§)(foo)
|
||||||
_ = (a, (b, b), a)§
|
_ = (a, (b, b), a)§
|
||||||
_ = (§)(a, (b, b), a) // expected-error {{operator function '§' expects a single parameter of type '(T, (U, U), T)'}}
|
_ = (§)(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 Kitten : ExpressibleByCatLiteral {}
|
||||||
struct Puppy : ExpressibleByDogLiteral {}
|
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'}}
|
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>()
|
return Claws<Kitten>.Fangs<T>()
|
||||||
}
|
}
|
||||||
|
|
||||||
func something<T>() -> T { // expected-note {{in call to function 'something()'}}
|
func something<T>() -> T {
|
||||||
while true {}
|
while true {}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -398,11 +398,14 @@ func test() {
|
|||||||
let _: Claws.Fangs<Puppy> = pets(fur: Puppy())
|
let _: Claws.Fangs<Puppy> = pets(fur: Puppy())
|
||||||
let _: Claws.Fangs<Puppy> = Claws<Kitten>.Fangs()
|
let _: Claws.Fangs<Puppy> = Claws<Kitten>.Fangs()
|
||||||
let _: Claws.Fangs<Puppy> = Claws.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()
|
let _: Claws.Fangs<NotADog> = something()
|
||||||
// expected-error@-1 {{generic parameter 'T' could not be inferred}} // FIXME: bad diagnostic
|
// expected-error@-1 {{generic parameter 'A' could not be inferred}}
|
||||||
_ = Claws.Fangs<NotADog>() // TODO(diagnostics): There should be two errors here - "cannot infer A" and "NotADog conformance to ExpressibleByDogLiteral"
|
_ = Claws.Fangs<NotADog>()
|
||||||
// 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}}
|
||||||
|
// 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
|
// 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>
|
typealias C<T> = MyType<String, T>
|
||||||
|
|
||||||
// Type aliases with unused generic params.
|
// 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}}
|
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<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<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 _ : 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)
|
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)
|
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-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 _ : D<Int, Int, Float> = D(a: 1, b: 2)
|
||||||
|
|
||||||
let _ : F = { (a : Int) -> Int in a } // Infer the types of F
|
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
|
e1 = .default // SE-0071
|
||||||
|
|
||||||
// Generic enumeration type
|
// Generic enumeration type
|
||||||
enum E2<T> {
|
enum E2<T> { // expected-note {{'T' declared as parameter to type 'E2'}}
|
||||||
case First
|
case First
|
||||||
case Second(T)
|
case Second(T)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ struct A: Hashable {
|
|||||||
func hash(into hasher: inout Hasher) { fatalError() }
|
func hash(into hasher: inout Hasher) { fatalError() }
|
||||||
}
|
}
|
||||||
struct B {}
|
struct B {}
|
||||||
struct C<T> {
|
struct C<T> { // expected-note 2 {{'T' declared as parameter to type 'C'}}
|
||||||
var value: T
|
var value: T
|
||||||
subscript() -> T { get { return value } }
|
subscript() -> T { get { return value } }
|
||||||
subscript(sub: Sub) -> T { get { return value } set { } }
|
subscript(sub: Sub) -> T { get { return value } set { } }
|
||||||
@@ -190,7 +190,7 @@ func testKeyPath(sub: Sub, optSub: OptSub,
|
|||||||
let _: AnyKeyPath = \A.property
|
let _: AnyKeyPath = \A.property
|
||||||
let _: AnyKeyPath = \C<A>.value
|
let _: AnyKeyPath = \C<A>.value
|
||||||
let _: AnyKeyPath = \.property // expected-error{{ambiguous}}
|
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 _: AnyKeyPath = \.value // expected-error{{ambiguous}}
|
||||||
|
|
||||||
let _ = \Prop.[nonHashableSub] // expected-error{{subscript index of type 'NonHashableSub' in a key path must be Hashable}}
|
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()]
|
_ = ("tuple", "too", "big")[keyPath: tuple_el_1()]
|
||||||
// expected-note@-12 {{}}
|
// expected-note@-12 {{}}
|
||||||
// expected-error@-2 {{cannot be applied}}
|
// expected-error@-2 {{generic parameter 'T' could not be inferred}}
|
||||||
// expected-error@-3 {{cannot be applied}}
|
// expected-error@-3 {{generic parameter 'U' could not be inferred}}
|
||||||
// expected-error@-4 {{could not be inferred}}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Z { }
|
struct Z { }
|
||||||
|
|||||||
@@ -49,32 +49,32 @@ func mismatchedAppends<T, U, V>(readOnlyLeft: KeyPath<T, U>,
|
|||||||
readOnlyRight: KeyPath<U, V>,
|
readOnlyRight: KeyPath<U, V>,
|
||||||
writableRight: WritableKeyPath<U, V>,
|
writableRight: WritableKeyPath<U, V>,
|
||||||
referenceRight: ReferenceWritableKeyPath<U, V>){
|
referenceRight: ReferenceWritableKeyPath<U, V>){
|
||||||
// expected-error@+1{{}}
|
|
||||||
_ = readOnlyRight.appending(path: readOnlyLeft)
|
_ = 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)
|
_ = 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)
|
_ = 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)
|
_ = 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)
|
_ = 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)
|
_ = 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)
|
_ = 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)
|
_ = 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)
|
_ = 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>,
|
func partialAppends<T, U, V>(partial: PartialKeyPath<T>,
|
||||||
|
|||||||
Reference in New Issue
Block a user