[ConstraintSystem] Bind holes to UnresolvedType instead of Any.

This commit is contained in:
Holly Borla
2019-10-10 12:05:58 -07:00
parent 3cdee649f5
commit e63f259f4f
17 changed files with 36 additions and 31 deletions

View File

@@ -530,6 +530,8 @@ public:
/// Is this the 'Any' type?
bool isAny();
bool isHole();
/// Does the type have outer parenthesis?
bool hasParenSugar() const { return getKind() == TypeKind::Paren; }

View File

@@ -157,6 +157,10 @@ bool TypeBase::isAny() {
return isEqual(getASTContext().TheAnyType);
}
bool TypeBase::isHole() {
return isEqual(getASTContext().TheUnresolvedType);
}
bool TypeBase::isAnyClassReferenceType() {
return getCanonicalType().isAnyClassReferenceType();
}

View File

@@ -740,7 +740,7 @@ ConstraintSystem::getPotentialBindings(TypeVariableType *typeVar) const {
if (shouldAttemptFixes() && result.Bindings.empty() &&
(isHole(typeVar) || result.isGenericParameter())) {
result.IsHole = true;
result.addPotentialBinding({getASTContext().TheAnyType,
result.addPotentialBinding({getASTContext().TheUnresolvedType,
AllowedBindingKind::Exact, ConstraintKind::Defaultable, nullptr,
typeVar->getImpl().getLocator()});
}

View File

@@ -98,7 +98,7 @@ public:
/// Resolve type variables present in the raw type, if any.
Type resolveType(Type rawType, bool reconstituteSugar = false,
bool wantRValue = true) const {
auto resolvedType = CS.simplifyType(rawType);
auto resolvedType = CS.simplifyType(rawType, /*forDiagnostics*/true);
if (reconstituteSugar)
resolvedType = resolvedType->reconstituteSugar(/*recursive*/ true);
@@ -782,12 +782,7 @@ protected:
private:
Type resolve(Type rawType) {
auto type = resolveType(rawType)->getWithoutSpecifierType();
if (auto *BGT = type->getAs<BoundGenericType>()) {
if (BGT->hasUnresolvedType())
return BGT->getDecl()->getDeclaredInterfaceType();
}
return type;
return resolveType(rawType)->getWithoutSpecifierType();
}
/// Try to add a fix-it to convert a stored property into a computed

View File

@@ -2313,7 +2313,7 @@ Type simplifyTypeImpl(const ConstraintSystem &cs, Type type,
});
}
Type ConstraintSystem::simplifyType(Type type) const {
Type ConstraintSystem::simplifyType(Type type, bool forDiagnostics) const {
if (!type->hasTypeVariable())
return type;
@@ -2321,8 +2321,13 @@ Type ConstraintSystem::simplifyType(Type type) const {
return simplifyTypeImpl(
*this, type,
[&](TypeVariableType *tvt) -> Type {
if (auto fixed = getFixedType(tvt))
if (auto fixed = getFixedType(tvt)) {
if (forDiagnostics && fixed->isHole() &&
tvt->getImpl().getLocator()->isForGenericParameter())
return tvt->getImpl().getLocator()->getGenericParameter();
return simplifyType(fixed);
}
return getRepresentative(tvt);
});

View File

@@ -3033,7 +3033,7 @@ public:
///
/// The resulting types can be compared canonically, so long as additional
/// type equivalence requirements aren't introduced between comparisons.
Type simplifyType(Type type) const;
Type simplifyType(Type type, bool forDiagnostics = false) const;
/// Simplify a type, by replacing type variables with either their
/// fixed types (if available) or their representatives.

View File

@@ -372,7 +372,7 @@ func rdar21078316() {
var foo : [String : String]?
var bar : [(String, String)]?
bar = foo.map { ($0, $1) } // expected-error {{contextual closure type '([String : String]) throws -> [(String, String)]' expects 1 argument, but 2 were used in closure body}}
// expected-error@-1:19 {{cannot convert value of type '([String : String], Any)' to closure result type '[(String, String)]'}}
// expected-error@-1:19 {{cannot convert value of type '(Dictionary<String, String>, _)' to closure result type '[(String, String)]'}}
}
@@ -821,7 +821,7 @@ func rdar_40537960() {
}
var arr: [S] = []
_ = A(arr, fn: { L($0.v) }) // expected-error {{cannot convert value of type 'L' to closure result type 'R<Any>'}}
_ = A(arr, fn: { L($0.v) }) // expected-error {{cannot convert value of type 'L' to closure result type 'R<P>'}}
// 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#>>}}
}

View File

@@ -19,11 +19,11 @@ func attributedInOutFunc(x: inout @convention(c) () -> Int32) {} // expected-not
attributedInOutFunc() // expected-error {{missing argument for parameter 'x' in call}} {{21-21=x: &<#@convention(c) () -> Int32#>}}
func genericFunc1<T>(x: T) {} // expected-note * {{here}}
genericFunc1() // expected-error {{missing argument for parameter 'x' in call}} {{14-14=x: <#Any#>}}
genericFunc1() // expected-error {{missing argument for parameter 'x' in call}} {{14-14=x: <#_#>}}
protocol P {}
func genericFunc2<T : P>(x: T) {} // expected-note * {{here}}
genericFunc2() // expected-error {{missing argument for parameter 'x' in call}} {{14-14=x: <#Any#>}}
genericFunc2() // expected-error {{missing argument for parameter 'x' in call}} {{14-14=x: <#_#>}}
typealias MyInt = Int
func aliasedFunc(x: MyInt) {} // expected-note * {{here}}

View File

@@ -1296,7 +1296,7 @@ func rdar43525641(_ a: Int, _ b: Int = 0, c: Int = 0, _ d: Int) {}
rdar43525641(1, c: 2, 3) // Ok
struct Array {}
let foo: Swift.Array = Array() // expected-error {{cannot convert value of type 'Array' to specified type 'Array<Any>'}}
let foo: Swift.Array = Array() // expected-error {{cannot convert value of type 'Array' to specified type 'Array<Element>'}}
struct Error {}
let bar: Swift.Error = Error() //expected-error {{value of type 'diagnostics.Error' does not conform to specified type 'Swift.Error'}}
@@ -1317,16 +1317,16 @@ takesArrayOfSetOfGenericArrays(1) // expected-error {{cannot convert value of ty
func takesArrayOfGenericOptionals<T>(_ x: [T?]) {}
takesArrayOfGenericOptionals(1) // expected-error {{cannot convert value of type 'Int' to expected argument type '[Int?]'}}
func takesGenericDictionary<T, U>(_ x: [T : U]) {} // expected-note {{in call to function 'takesGenericDictionary'}}
takesGenericDictionary(true) // expected-error {{cannot convert value of type 'Bool' to expected argument type '[Any : Any]'}}
takesGenericDictionary(true) // expected-error {{cannot convert value of type 'Bool' to expected argument type '[T : U]'}}
// expected-error@-1 {{generic parameter 'T' could not be inferred}}
// expected-error@-2 {{generic parameter 'U' could not be inferred}}
typealias Z = Int
func takesGenericDictionaryWithTypealias<T>(_ x: [T : Z]) {} // expected-note {{in call to function 'takesGenericDictionaryWithTypealias'}}
takesGenericDictionaryWithTypealias(true) // expected-error {{cannot convert value of type 'Bool' to expected argument type '[Any : Z]' (aka 'Dictionary<Any, Int>'}}
takesGenericDictionaryWithTypealias(true) // expected-error {{cannot convert value of type 'Bool' to expected argument type '[T : Z]'}}
// expected-error@-1 {{generic parameter 'T' could not be inferred}}
func takesGenericFunction<T>(_ x: ([T]) -> Void) {} // expected-note {{in call to function 'takesGenericFunction'}}
takesGenericFunction(true) // expected-error {{cannot convert value of type 'Bool' to expected argument type '([Any]) -> Void'}}
takesGenericFunction(true) // expected-error {{cannot convert value of type 'Bool' to expected argument type '([T]) -> Void'}}
// expected-error@-1 {{generic parameter 'T' could not be inferred}}
func takesTuple<T>(_ x: ([T], [T])) {} // expected-note {{in call to function 'takesTuple'}}
takesTuple(true) // expected-error {{cannot convert value of type 'Bool' to expected argument type '([Any], [Any])'}}
takesTuple(true) // expected-error {{cannot convert value of type 'Bool' to expected argument type '([T], [T])'}}
// expected-error@-1 {{generic parameter 'T' could not be inferred}}

View File

@@ -31,8 +31,8 @@ class Demo {
}
let some = Some(keyPath: \Demo.here)
// expected-error@-1 {{cannot convert value of type 'KeyPath<Demo, (() -> Void)?>' to expected argument type 'KeyPath<Demo, ((Any) -> Void)?>'}}
// expected-note@-2 {{arguments to generic parameter 'Value' ('(() -> Void)?' and '((Any) -> Void)?') are expected to be equal}}
// expected-error@-1 {{cannot convert value of type 'KeyPath<Demo, (() -> Void)?>' to expected argument type 'KeyPath<Demo, ((V) -> Void)?>'}}
// expected-note@-2 {{arguments to generic parameter 'Value' ('(() -> Void)?' and '((V) -> Void)?') are expected to be equal}}
// expected-error@-3 {{generic parameter 'V' could not be inferred}}
// expected-note@-4 {{explicitly specify the generic arguments to fix this issue}}

View File

@@ -349,14 +349,14 @@ func trailingClosure6<T>(value: Int, expression: () -> T?) { }
trailingClosure5(file: "hello", line: 17) { // expected-error{{extraneous argument label 'file:' in call}}{{18-24=}}
// expected-error@-1 {{generic parameter 'T' could not be inferred}}
return Optional.Some(5)
// expected-error@-1 {{enum type 'Optional<Any>' has no case 'Some'; did you mean 'some'}} {{19-23=some}}
// expected-error@-1 {{enum type 'Optional<Wrapped>' has no case 'Some'; did you mean 'some'}} {{19-23=some}}
// expected-error@-2 {{generic parameter 'Wrapped' could not be inferred}}
// expected-note@-3 {{explicitly specify the generic arguments to fix this issue}}
}
trailingClosure6(5) { // expected-error{{missing argument label 'value:' in call}}{{18-18=value: }}
// expected-error@-1 {{generic parameter 'T' could not be inferred}}
return Optional.Some(5)
// expected-error@-1 {{enum type 'Optional<Any>' has no case 'Some'; did you mean 'some'}} {{19-23=some}}
// expected-error@-1 {{enum type 'Optional<Wrapped>' has no case 'Some'; did you mean 'some'}} {{19-23=some}}
// expected-error@-2 {{generic parameter 'Wrapped' could not be inferred}}
// expected-note@-3 {{explicitly specify the generic arguments to fix this issue}}
}

View File

@@ -266,7 +266,7 @@ func testGetVectorSize(_ vi: MyVector<Int>, vf: MyVector<Float>) {
i = getVectorSize(vi)
i = getVectorSize(vf)
getVectorSize(i) // expected-error{{cannot convert value of type 'Int' to expected argument type 'MyVector<Any>'}}
getVectorSize(i) // expected-error{{cannot convert value of type 'Int' to expected argument type 'MyVector<T>'}}
// expected-error@-1 {{generic parameter 'T' could not be inferred}}
var x : X, y : Y

View File

@@ -55,7 +55,7 @@ func test_varname_binding() {
var ((), (g1, g2), h) = ((), (e, d), e)
var (j, k, l) = callee1()
var (m, n) = callee1() // expected-error{{'(Int, Int, Int)' is not convertible to '(Int, Int)', tuples have a different number of elements}}
var (o, p, q, r) = callee1() // expected-error{{'(Int, Int, Int)' is not convertible to '(Int, Int, Int, Any)', tuples have a different number of elements}}
var (o, p, q, r) = callee1() // expected-error{{'(Int, Int, Int)' is not convertible to '(Int, Int, Int, _)', tuples have a different number of elements}}
}
//===----------------------------------------------------------------------===//

View File

@@ -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<Any>' has no member 'a'}}
_ = P.a.a // expected-error {{type 'Generic<T>' has no member 'a'}}
// expected-error@-1 {{generic parameter 'T' could not be inferred}}
}

View File

@@ -156,7 +156,7 @@ func errorRecovery() {
var f: (Int,Int) = (1, 2, f : 3) // expected-error {{'(Int, Int, f: Int)' is not convertible to '(Int, Int)', tuples have a different number of elements}}
// <rdar://problem/22426860> CrashTracer: [USER] swift at mous_namespace::ConstraintGenerator::getTypeForPattern + 698
var (g1, g2, g3) = (1, 2) // expected-error {{'(Int, Int)' is not convertible to '(Int, Int, Any)', tuples have a different number of elements}}
var (g1, g2, g3) = (1, 2) // expected-error {{'(Int, Int)' is not convertible to '(Int, Int, _)', tuples have a different number of elements}}
var (h1, h2) = (1, 2, 3) // expected-error {{'(Int, Int, Int)' is not convertible to '(Int, Int)', tuples have a different number of elements}}
var i: (Bool, Bool) = makeTuple() // expected-error {{tuple type '(String, Int)' is not convertible to tuple '(Bool, Bool)'}}
}

View File

@@ -232,7 +232,7 @@ func testNoComponents() {
let _: KeyPath<A, A> = \A // expected-error{{must have at least one component}}
// FIXME(diagnostics): This should be diagnosed as `missing generic parameter 'T'` instead of a contextual failure.
let _: KeyPath<C, A> = \C // expected-error{{must have at least one component}} expected-error{{}}
// expected-error@-1 {{cannot convert value of type 'KeyPath<Root, Value>' to specified type 'KeyPath<C<Any>, A>'}}
// expected-error@-1 {{cannot convert value of type 'KeyPath<Root, Value>' to specified type 'KeyPath<C<T>, A>'}}
}
struct TupleStruct {

View File

@@ -44,5 +44,4 @@ struct X { var y: Int = 0 }
var x = X()
x ~> \X.y > { a in a += 1; return 3 }
// expected-error@-1 {{generic parameter 'R' could not be inferred}}
// expected-error@-2 {{cannot convert value of type 'M<WritableKeyPath<X, Int>, Any>' to expected argument type 'WritableKeyPath<Root, Value>'}}
// FIXME: in 'M<WritableKeyPath<X, Int>, Any>', Any comes from a hole
// expected-error@-2 {{cannot convert value of type 'M<WritableKeyPath<X, Int>, R>' to expected argument type 'WritableKeyPath<_, _>'}}