@@ -5405,32 +5405,40 @@ NeverNullType TypeResolver::resolveImplicitlyUnwrappedOptionalType(
54055405 }
54065406
54075407 if (doDiag && !options.contains (TypeResolutionFlags::SilenceErrors)) {
5408- // Prior to Swift 5, we allow 'as T!' and turn it into a disjunction.
5409- if (ctx.isSwiftVersionAtLeast (5 )) {
5410- // Mark this repr as invalid. This is the only way to indicate that
5411- // something went wrong without supressing checking other reprs in
5412- // the same type. For example:
5413- //
5414- // struct S<T, U> { ... }
5415- //
5416- // _ = S<Int!, String!>(...)
5417- //
5418- // Compiler should diagnose both `Int!` and `String!` as invalid,
5419- // but returning `ErrorType` from here would stop type resolution
5420- // after `Int!`.
5408+ // In language modes up to Swift 5, we allow `T!` in invalid position for
5409+ // compatibility and downgrade the error to a warning.
5410+ const unsigned swiftLangModeForError = 5 ;
5411+
5412+ // If we are about to error, mark this node as invalid.
5413+ // This is the only way to indicate that something went wrong without
5414+ // supressing checking of sibling nodes.
5415+ // For example:
5416+ //
5417+ // struct S<T, U> { ... }
5418+ //
5419+ // _ = S<Int!, String!>(...)
5420+ //
5421+ // Compiler should diagnose both `Int!` and `String!` as invalid,
5422+ // but returning `ErrorType` from here would stop type resolution
5423+ // after `Int!`.
5424+ if (ctx.isSwiftVersionAtLeast (swiftLangModeForError)) {
54215425 repr->setInvalid ();
5426+ }
54225427
5423- diagnose (repr->getStartLoc (),
5424- diag::implicitly_unwrapped_optional_in_illegal_position)
5425- .fixItReplace (repr->getExclamationLoc (), " ?" );
5426- } else if (options.is (TypeResolverContext::ExplicitCastExpr)) {
5427- diagnose (
5428- repr->getStartLoc (),
5429- diag::implicitly_unwrapped_optional_deprecated_in_this_position);
5430- } else {
5431- diagnose (
5432- repr->getStartLoc (),
5433- diag::implicitly_unwrapped_optional_in_illegal_position_interpreted_as_optional)
5428+ Diag<> diagID = diag::iuo_deprecated_here;
5429+ if (ctx.isSwiftVersionAtLeast (swiftLangModeForError)) {
5430+ diagID = diag::iuo_invalid_here;
5431+ }
5432+
5433+ diagnose (repr->getExclamationLoc (), diagID)
5434+ .warnUntilSwiftVersion (swiftLangModeForError);
5435+
5436+ // Suggest a regular optional, but not when `T!` is the right-hand side of
5437+ // a cast expression.
5438+ // In this case, the user is likely trying to cast an expression of optional
5439+ // type, and this fix-it is not generally helpful.
5440+ if (!options.is (TypeResolverContext::ExplicitCastExpr)) {
5441+ diagnose (repr->getExclamationLoc (), diag::iuo_use_optional_instead)
54345442 .fixItReplace (repr->getExclamationLoc (), " ?" );
54355443 }
54365444 }
0 commit comments