Skip to content

Commit 89eaa1e

Browse files
committed
[Diagnostics] Desugar syntax sugared types if they have unresolved types
If a syntax sugared type like Array had an unresolved type, it used to print as `[_]` in diagnostics, which could be confusing. Instead, desugar these unresolved types before printing, so Array, for example, prints as `Array<_>`. Currently this only applies to Array, Dictionary, and Optional.
1 parent 89382f7 commit 89eaa1e

File tree

5 files changed

+43
-2
lines changed

5 files changed

+43
-2
lines changed

include/swift/AST/Types.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -457,6 +457,10 @@ class alignas(1 << TypeAlignInBits) TypeBase {
457457
/// types, optionals, etc.
458458
TypeBase *reconstituteSugar(bool Recursive);
459459

460+
// If this type is a syntax sugar type, desugar it. Also desugar any nested
461+
// syntax sugar types.
462+
TypeBase *getWithoutSyntaxSugar();
463+
460464
/// getASTContext - Return the ASTContext that this type belongs to.
461465
ASTContext &getASTContext() {
462466
// If this type is canonical, it has the ASTContext in it.

lib/AST/DiagnosticEngine.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -468,6 +468,13 @@ static void formatDiagnosticArgument(StringRef Modifier,
468468

469469
// Strip extraneous parentheses; they add no value.
470470
auto type = Arg.getAsType()->getWithoutParens();
471+
472+
// If a type has an unresolved type, print it with syntax sugar removed for
473+
// clarity. For example, print `Array<_>` instead of `[_]`.
474+
if (type->hasUnresolvedType()) {
475+
type = type->getWithoutSyntaxSugar();
476+
}
477+
471478
bool isAmbiguous = typeSpellingIsAmbiguous(type, Args);
472479

473480
if (isAmbiguous && isa<OpaqueTypeArchetypeType>(type.getPointer())) {

lib/AST/Type.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1252,6 +1252,15 @@ TypeBase *TypeBase::reconstituteSugar(bool Recursive) {
12521252
return Func(this).getPointer();
12531253
}
12541254

1255+
TypeBase *TypeBase::getWithoutSyntaxSugar() {
1256+
auto Func = [](Type Ty) -> Type {
1257+
if (auto *syntaxSugarType = dyn_cast<SyntaxSugarType>(Ty.getPointer()))
1258+
return syntaxSugarType->getSinglyDesugaredType()->getWithoutSyntaxSugar();
1259+
return Ty;
1260+
};
1261+
return Type(this).transform(Func).getPointer();
1262+
}
1263+
12551264
#define TYPE(Id, Parent)
12561265
#define SUGARED_TYPE(Id, Parent) \
12571266
static_assert(std::is_base_of<SugarType, Id##Type>::value, "Sugar mismatch");

test/Constraints/diagnostics.swift

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -424,7 +424,7 @@ enum Color {
424424
}
425425

426426
// FIXME: This used to be better: "'map' produces '[T]', not the expected contextual result type '(Int, Color)'"
427-
let _: (Int, Color) = [1,2].map({ ($0, .Unknown("")) }) // expected-error {{expression type '((Int) throws -> _) throws -> [_]' is ambiguous without more context}}
427+
let _: (Int, Color) = [1,2].map({ ($0, .Unknown("")) }) // expected-error {{expression type '((Int) throws -> _) throws -> Array<_>' is ambiguous without more context}}
428428

429429
let _: [(Int, Color)] = [1,2].map({ ($0, .Unknown("")) })// expected-error {{missing argument label 'description:' in call}}
430430

@@ -1233,3 +1233,24 @@ let baz: (Swift.Error) = Error() //expected-error {{value of type 'diagnostics.E
12331233
let baz2: Swift.Error = (Error()) //expected-error {{value of type 'diagnostics.Error' does not conform to specified type 'Swift.Error'}}
12341234
let baz3: (Swift.Error) = (Error()) //expected-error {{value of type 'diagnostics.Error' does not conform to specified type 'Swift.Error'}}
12351235
let baz4: ((Swift.Error)) = (Error()) //expected-error {{value of type 'diagnostics.Error' does not conform to specified type 'Swift.Error'}}
1236+
1237+
// SyntaxSugarTypes with unresolved types
1238+
func takesGenericArray<T>(_ x: [T]) {}
1239+
takesGenericArray(1) // expected-error {{cannot convert value of type 'Int' to expected argument type 'Array<_>'}}
1240+
func takesNestedGenericArray<T>(_ x: [[T]]) {}
1241+
takesNestedGenericArray(1) // expected-error {{cannot convert value of type 'Int' to expected argument type 'Array<Array<_>>'}}
1242+
func takesSetOfGenericArrays<T>(_ x: Set<[T]>) {}
1243+
takesSetOfGenericArrays(1) // expected-error {{cannot convert value of type 'Int' to expected argument type 'Set<Array<_>>'}}
1244+
func takesArrayOfSetOfGenericArrays<T>(_ x: [Set<[T]>]) {}
1245+
takesArrayOfSetOfGenericArrays(1) // expected-error {{cannot convert value of type 'Int' to expected argument type 'Array<Set<Array<_>>>'}}
1246+
func takesArrayOfGenericOptionals<T>(_ x: [T?]) {}
1247+
takesArrayOfGenericOptionals(1) // expected-error {{cannot convert value of type 'Int' to expected argument type 'Array<Optional<_>>'}}
1248+
func takesGenericDictionary<T, U>(_ x: [T : U]) {}
1249+
takesGenericDictionary(true) // expected-error {{cannot convert value of type 'Bool' to expected argument type 'Dictionary<_, _>'}}
1250+
typealias Z = Int
1251+
func takesGenericDictionaryWithTypealias<T>(_ x: [T : Z]) {}
1252+
takesGenericDictionaryWithTypealias(true) // expected-error {{cannot convert value of type 'Bool' to expected argument type 'Dictionary<_, Z>'}}
1253+
func takesGenericFunction<T>(_ x: ([T]) -> Void) {}
1254+
takesGenericFunction(true) // expected-error {{cannot convert value of type 'Bool' to expected argument type '(Array<_>) -> Void'}}
1255+
func takesTuple<T>(_ x: ([T], [T])) {}
1256+
takesTuple(true) // expected-error {{cannot convert value of type 'Bool' to expected argument type '(Array<_>, Array<_>)'}}

test/expr/closure/anonymous.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ func variadic() {
3535
// expected-error@-1 {{cannot convert value of type '([Int]) -> ()' to specified type '(Int...) -> ()'}}
3636

3737
takesVariadicGeneric({takesIntArray($0)})
38-
// expected-error@-1 {{cannot convert value of type '[_]' to expected argument type '[Int]'}}
38+
// expected-error@-1 {{cannot convert value of type 'Array<_>' to expected argument type '[Int]'}}
3939

4040
takesVariadicGeneric({let _: [Int] = $0})
4141
// expected-error@-1 {{cannot convert value of type '(_) -> ()' to expected argument type '(_...) -> ()'}}

0 commit comments

Comments
 (0)