Skip to content

Commit 3e54c73

Browse files
authored
Merge pull request #59685 from xedin/dont-silence-errors-while-resolving-types
[PreCheckExpr] Don't silence errors while resolving types for 'literal via coercion' transform
2 parents 8be672a + 5ac8182 commit 3e54c73

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
@@ -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

lib/Sema/TypeCheckType.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3810,6 +3810,19 @@ NeverNullType TypeResolver::resolveImplicitlyUnwrappedOptionalType(
38103810
if (doDiag && !options.contains(TypeResolutionFlags::SilenceErrors)) {
38113811
// Prior to Swift 5, we allow 'as T!' and turn it into a disjunction.
38123812
if (getASTContext().isSwiftVersionAtLeast(5)) {
3813+
// Mark this repr as invalid. This is the only way to indicate that
3814+
// something went wrong without supressing checking other reprs in
3815+
// the same type. For example:
3816+
//
3817+
// struct S<T, U> { ... }
3818+
//
3819+
// _ = S<Int!, String!>(...)
3820+
//
3821+
// Compiler should diagnose both `Int!` and `String!` as invalid,
3822+
// but returning `ErrorType` from here would stop type resolution
3823+
// after `Int!`.
3824+
repr->setInvalid();
3825+
38133826
diagnose(repr->getStartLoc(),
38143827
diag::implicitly_unwrapped_optional_in_illegal_position)
38153828
.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)