Skip to content

Commit 5ac8182

Browse files
committed
[PreCheckExpr] Don't silence errors while resolving types for 'literal via coercion' transform
Since `resolveType` caches its results, silencing errors would mean that the error would be lost and each subsequent call to `resolveType` would get `ErrorType` back. This ultimately leads to the compiler failing to produce a diagnostic when invalid type is used in `init` call. Resolves: rdar://94888357
1 parent 601a1dd commit 5ac8182

File tree

2 files changed

+19
-8
lines changed

2 files changed

+19
-8
lines changed

lib/Sema/PreCheckExpr.cpp

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -961,6 +961,9 @@ namespace {
961961

962962
/// Simplify constructs like `UInt32(1)` into `1 as UInt32` if
963963
/// the type conforms to the expected literal protocol.
964+
///
965+
/// \returns Either a transformed expression, or `ErrorExpr` upon type
966+
/// resolution failure, or `nullptr` if transformation is not applicable.
964967
Expr *simplifyTypeConstructionWithLiteralArg(Expr *E);
965968

966969
/// Whether the current expression \p E is in a context that might turn out
@@ -1431,8 +1434,9 @@ namespace {
14311434
return KPE;
14321435
}
14331436

1434-
if (auto *simplified = simplifyTypeConstructionWithLiteralArg(expr))
1435-
return simplified;
1437+
if (auto *result = simplifyTypeConstructionWithLiteralArg(expr)) {
1438+
return isa<ErrorExpr>(result) ? nullptr : result;
1439+
}
14361440

14371441
// If we find an unresolved member chain, wrap it in an
14381442
// UnresolvedMemberChainResultExpr (unless this has already been done).
@@ -2081,12 +2085,8 @@ Expr *PreCheckExpression::simplifyTypeConstructionWithLiteralArg(Expr *E) {
20812085
if (auto precheckedTy = typeExpr->getInstanceType()) {
20822086
castTy = precheckedTy;
20832087
} else {
2084-
const auto options =
2085-
TypeResolutionOptions(TypeResolverContext::InExpression) |
2086-
TypeResolutionFlags::SilenceErrors;
2087-
20882088
const auto result = TypeResolution::resolveContextualType(
2089-
typeExpr->getTypeRepr(), DC, options,
2089+
typeExpr->getTypeRepr(), DC, TypeResolverContext::InExpression,
20902090
[](auto unboundTy) {
20912091
// FIXME: Don't let unbound generic types escape type resolution.
20922092
// For now, just return the unbound generic type.
@@ -2097,7 +2097,9 @@ Expr *PreCheckExpression::simplifyTypeConstructionWithLiteralArg(Expr *E) {
20972097
PlaceholderType::get);
20982098

20992099
if (result->hasError())
2100-
return nullptr;
2100+
return new (getASTContext())
2101+
ErrorExpr(typeExpr->getSourceRange(), result, typeExpr);
2102+
21012103
castTy = result;
21022104
}
21032105

test/type/types.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,3 +194,12 @@ var _: sr5505 = sr5505 // expected-error {{cannot find type 'sr5505' in scope}}
194194
typealias A = (inout Int ..., Int ... = [42, 12]) -> Void // expected-error {{'inout' must not be used on variadic parameters}}
195195
// expected-error@-1 {{only a single element can be variadic}} {{35-39=}}
196196
// expected-error@-2 {{default argument not permitted in a tuple type}} {{39-49=}}
197+
198+
// rdar://94888357 - failed to produce a diagnostic when type is used incorrectly
199+
func rdar94888357() {
200+
struct S<T> { // expected-note {{generic type 'S' declared here}}
201+
init(_ str: String) {}
202+
}
203+
204+
let _ = S<String, String>("") // expected-error {{generic type 'S' specialized with too many type parameters (got 2, but expected 1)}}
205+
}

0 commit comments

Comments
 (0)