Skip to content

Commit e597b95

Browse files
authored
Merge pull request #25893 from owenv/desugar_confusing_types_for_diagnosis
2 parents 647fd3e + 89eaa1e commit e597b95

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
@@ -461,6 +461,10 @@ class alignas(1 << TypeAlignInBits) TypeBase {
461461
/// types, optionals, etc.
462462
TypeBase *reconstituteSugar(bool Recursive);
463463

464+
// If this type is a syntax sugar type, desugar it. Also desugar any nested
465+
// syntax sugar types.
466+
TypeBase *getWithoutSyntaxSugar();
467+
464468
/// getASTContext - Return the ASTContext that this type belongs to.
465469
ASTContext &getASTContext() {
466470
// 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
@@ -1259,6 +1259,15 @@ TypeBase *TypeBase::reconstituteSugar(bool Recursive) {
12591259
return Func(this).getPointer();
12601260
}
12611261

1262+
TypeBase *TypeBase::getWithoutSyntaxSugar() {
1263+
auto Func = [](Type Ty) -> Type {
1264+
if (auto *syntaxSugarType = dyn_cast<SyntaxSugarType>(Ty.getPointer()))
1265+
return syntaxSugarType->getSinglyDesugaredType()->getWithoutSyntaxSugar();
1266+
return Ty;
1267+
};
1268+
return Type(this).transform(Func).getPointer();
1269+
}
1270+
12621271
#define TYPE(Id, Parent)
12631272
#define SUGARED_TYPE(Id, Parent) \
12641273
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
@@ -425,7 +425,7 @@ enum Color {
425425
}
426426

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

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

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