Skip to content

Commit 50d7916

Browse files
authored
Merge pull request #59724 from xedin/rdar-94888357-5.7
[5.7][PreCheckExpr] Don't silence errors while resolving types for 'litera…
2 parents 4359460 + f0ca515 commit 50d7916

File tree

4 files changed

+32
-11
lines changed

4 files changed

+32
-11
lines changed

lib/Sema/PreCheckExpr.cpp

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

953953
/// Simplify constructs like `UInt32(1)` into `1 as UInt32` if
954954
/// the type conforms to the expected literal protocol.
955+
///
956+
/// \returns Either a transformed expression, or `ErrorExpr` upon type
957+
/// resolution failure, or `nullptr` if transformation is not applicable.
955958
Expr *simplifyTypeConstructionWithLiteralArg(Expr *E);
956959

957960
/// Whether the current expression \p E is in a context that might turn out
@@ -1422,8 +1425,9 @@ namespace {
14221425
return KPE;
14231426
}
14241427

1425-
if (auto *simplified = simplifyTypeConstructionWithLiteralArg(expr))
1426-
return simplified;
1428+
if (auto *result = simplifyTypeConstructionWithLiteralArg(expr)) {
1429+
return isa<ErrorExpr>(result) ? nullptr : result;
1430+
}
14271431

14281432
// If we find an unresolved member chain, wrap it in an
14291433
// UnresolvedMemberChainResultExpr (unless this has already been done).
@@ -2077,12 +2081,8 @@ Expr *PreCheckExpression::simplifyTypeConstructionWithLiteralArg(Expr *E) {
20772081
if (auto precheckedTy = typeExpr->getInstanceType()) {
20782082
castTy = precheckedTy;
20792083
} else {
2080-
const auto options =
2081-
TypeResolutionOptions(TypeResolverContext::InExpression) |
2082-
TypeResolutionFlags::SilenceErrors;
2083-
20842084
const auto result = TypeResolution::resolveContextualType(
2085-
typeExpr->getTypeRepr(), DC, options,
2085+
typeExpr->getTypeRepr(), DC, TypeResolverContext::InExpression,
20862086
[](auto unboundTy) {
20872087
// FIXME: Don't let unbound generic types escape type resolution.
20882088
// For now, just return the unbound generic type.
@@ -2093,7 +2093,9 @@ Expr *PreCheckExpression::simplifyTypeConstructionWithLiteralArg(Expr *E) {
20932093
PlaceholderType::get);
20942094

20952095
if (result->hasError())
2096-
return nullptr;
2096+
return new (getASTContext())
2097+
ErrorExpr(typeExpr->getSourceRange(), result, typeExpr);
2098+
20972099
castTy = result;
20982100
}
20992101

lib/Sema/TypeCheckType.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3793,6 +3793,19 @@ NeverNullType TypeResolver::resolveImplicitlyUnwrappedOptionalType(
37933793
if (doDiag && !options.contains(TypeResolutionFlags::SilenceErrors)) {
37943794
// Prior to Swift 5, we allow 'as T!' and turn it into a disjunction.
37953795
if (getASTContext().isSwiftVersionAtLeast(5)) {
3796+
// Mark this repr as invalid. This is the only way to indicate that
3797+
// something went wrong without supressing checking other reprs in
3798+
// the same type. For example:
3799+
//
3800+
// struct S<T, U> { ... }
3801+
//
3802+
// _ = S<Int!, String!>(...)
3803+
//
3804+
// Compiler should diagnose both `Int!` and `String!` as invalid,
3805+
// but returning `ErrorType` from here would stop type resolution
3806+
// after `Int!`.
3807+
repr->setInvalid();
3808+
37963809
diagnose(repr->getStartLoc(),
37973810
diag::implicitly_unwrapped_optional_in_illegal_position)
37983811
.fixItReplace(repr->getExclamationLoc(), "?");

test/Sema/diag_erroneous_iuo.swift

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,11 +61,8 @@ func genericFunctionSigil<T>(
6161
}
6262

6363
func genericFunctionSigilArray<T>(
64-
// FIXME: We validate these types multiple times resulting in multiple diagnostics
6564
iuo: [T!] // expected-error {{'!' is not allowed here; perhaps '?' was intended?}}{{10-11=?}}
66-
// expected-error@-1 {{'!' is not allowed here; perhaps '?' was intended?}}{{10-11=?}}
6765
) -> [T!] { // expected-error {{'!' is not allowed here; perhaps '?' was intended?}}{{8-9=?}}
68-
// expected-error@-1 {{'!' is not allowed here; perhaps '?' was intended?}}{{8-9=?}}
6966
return iuo
7067
}
7168

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)