Skip to content

Commit d7a3513

Browse files
authored
Merge pull request #9183 from DougGregor/se-0160-disable-warnings-by-default-4.0
[4.0] [SE-0160] Make deprecated @objc inference warnings opt-in.
2 parents aaaea05 + 114848e commit d7a3513

File tree

10 files changed

+70
-28
lines changed

10 files changed

+70
-28
lines changed

cmake/modules/SwiftSource.cmake

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,7 @@ function(_compile_swift_files
278278
endif()
279279

280280
if (SWIFTFILE_IS_STDLIB_CORE OR SWIFTFILE_IS_SDK_OVERLAY)
281-
list(APPEND swift_flags "-warn-swift3-objc-inference")
281+
list(APPEND swift_flags "-warn-swift3-objc-inference-complete")
282282
endif()
283283

284284
list(APPEND swift_flags ${SWIFT_EXPERIMENTAL_EXTRA_FLAGS})

include/swift/Basic/LangOptions.h

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,19 @@ namespace swift {
4646
};
4747
enum { NumPlatformConditionKind = 4 };
4848

49+
/// Describes which Swift 3 Objective-C inference warnings should be
50+
/// emitted.
51+
enum class Swift3ObjCInferenceWarnings {
52+
/// No warnings; this is the default.
53+
None,
54+
/// "Minimal" warnings driven by uses of declarations that make use of
55+
/// the Objective-C entry point directly.
56+
Minimal,
57+
/// "Complete" warnings that add "@objc" for every entry point that
58+
/// Swift 3 would have inferred as "@objc" but Swift 4 will not.
59+
Complete,
60+
};
61+
4962
/// \brief A collection of options that affect the language dialect and
5063
/// provide compiler debugging facilities.
5164
class LangOptions {
@@ -212,7 +225,8 @@ namespace swift {
212225

213226
/// Warn about cases where Swift 3 would infer @objc but later versions
214227
/// of Swift do not.
215-
bool WarnSwift3ObjCInference = false;
228+
Swift3ObjCInferenceWarnings WarnSwift3ObjCInference =
229+
Swift3ObjCInferenceWarnings::None;
216230

217231
/// Enable keypaths.
218232
bool EnableExperimentalKeyPaths = false;

include/swift/Option/Options.td

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -285,9 +285,19 @@ def continue_building_after_errors : Flag<["-"], "continue-building-after-errors
285285
Flags<[FrontendOption, DoesNotAffectIncrementalBuild]>,
286286
HelpText<"Continue building, even after errors are encountered">;
287287

288-
def warn_swift3_objc_inference : Flag<["-"], "warn-swift3-objc-inference">,
288+
def warn_swift3_objc_inference_complete :
289+
Flag<["-"], "warn-swift3-objc-inference-complete">,
290+
Flags<[FrontendOption, DoesNotAffectIncrementalBuild]>,
291+
HelpText<"Warn about deprecated @objc inference in Swift 3 for every declaration that will no longer be inferred as @objc in Swift 4">;
292+
293+
def warn_swift3_objc_inference_minimal :
294+
Flag<["-"], "warn-swift3-objc-inference-minimal">,
289295
Flags<[FrontendOption, DoesNotAffectIncrementalBuild]>,
290-
HelpText<"Warn about deprecated @objc inference in Swift 3">;
296+
HelpText<"Warn about deprecated @objc inference in Swift 3 based on direct uses of the Objective-C entrypoint">;
297+
298+
def warn_swift3_objc_inference : Flag<["-"], "warn-swift3-objc-inference">,
299+
Alias<warn_swift3_objc_inference_complete>,
300+
Flags<[FrontendOption, DoesNotAffectIncrementalBuild, HelpHidden]>;
291301

292302
// Platform options.
293303
def enable_app_extension : Flag<["-"], "application-extension">,

lib/Frontend/CompilerInvocation.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1011,13 +1011,23 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args,
10111011
}
10121012

10131013
Opts.EnableAppExtensionRestrictions |= Args.hasArg(OPT_enable_app_extension);
1014-
Opts.WarnSwift3ObjCInference |= Args.hasArg(OPT_warn_swift3_objc_inference);
10151014

10161015
Opts.EnableSwift3ObjCInference =
10171016
Args.hasFlag(OPT_enable_swift3_objc_inference,
10181017
OPT_disable_swift3_objc_inference,
10191018
Opts.isSwiftVersion3());
10201019

1020+
if (Opts.EnableSwift3ObjCInference) {
1021+
if (const Arg *A = Args.getLastArg(
1022+
OPT_warn_swift3_objc_inference_minimal,
1023+
OPT_warn_swift3_objc_inference_complete)) {
1024+
if (A->getOption().getID() == OPT_warn_swift3_objc_inference_minimal)
1025+
Opts.WarnSwift3ObjCInference = Swift3ObjCInferenceWarnings::Minimal;
1026+
else
1027+
Opts.WarnSwift3ObjCInference = Swift3ObjCInferenceWarnings::Complete;
1028+
}
1029+
}
1030+
10211031
llvm::Triple Target = Opts.Target;
10221032
StringRef TargetArg;
10231033
if (const Arg *A = Args.getLastArg(OPT_target)) {

lib/Migrator/Migrator.cpp

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -96,19 +96,20 @@ Migrator::performAFixItMigration() {
9696
Invocation.clearInputs();
9797
Invocation.getLangOptions().EffectiveLanguageVersion = { 4, 0, 0 };
9898

99-
// The default subset of @objc fix-its, referred to as "minimal" migration
100-
// in SE-0160, adds @objc to things that clearly must be visible to the
101-
// Objective-C runtime. These are compiler error fix-its.
102-
Invocation.getLangOptions().WarnSwift3ObjCInference = true;
103-
Invocation.getLangOptions().EnableSwift3ObjCInference = false;
104-
105-
// However, if the user selects the workflow to keep the behavior of Swift 3's
106-
// implicit Objective-C visibility, force Swift 3 @objc inference to be on.
107-
// Coupled with the -warn-swift3-objc-inference flag above, we'll get warning
108-
// fix-its from the compiler.
109-
if (getMigratorOptions().KeepObjcVisibility) {
110-
Invocation.getLangOptions().EnableSwift3ObjCInference = true;
111-
}
99+
// SE-0160: When migrating, always use the Swift 3 @objc inference rules,
100+
// which drives warnings with the "@objc" Fix-Its.
101+
Invocation.getLangOptions().EnableSwift3ObjCInference = true;
102+
103+
// The default behavior of the migrator, referred to as "minimal" migration
104+
// in SE-0160, only adds @objc Fix-Its to those cases where the Objective-C
105+
// entry point is explicitly used somewhere in the source code. The user
106+
// may also select a workflow that adds @objc for every declaration that
107+
// would infer @objc under the Swift 3 rules but would no longer infer
108+
// @objc in Swift 4.
109+
Invocation.getLangOptions().WarnSwift3ObjCInference =
110+
getMigratorOptions().KeepObjcVisibility
111+
? Swift3ObjCInferenceWarnings::Complete
112+
: Swift3ObjCInferenceWarnings::Minimal;
112113

113114
const auto &OrigFrontendOpts = StartInvocation.getFrontendOptions();
114115

lib/Sema/CSApply.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -949,7 +949,8 @@ namespace {
949949
// complain.
950950
if (auto attr = member->getAttrs().getAttribute<ObjCAttr>()) {
951951
if (attr->isSwift3Inferred() &&
952-
!tc.Context.LangOpts.WarnSwift3ObjCInference) {
952+
tc.Context.LangOpts.WarnSwift3ObjCInference
953+
== Swift3ObjCInferenceWarnings::Minimal) {
953954
tc.diagnose(memberLoc,
954955
diag::expr_dynamic_lookup_swift3_objc_inference,
955956
member->getDescriptiveKind(),
@@ -3954,7 +3955,8 @@ namespace {
39543955
// If this attribute was inferred based on deprecated Swift 3 rules,
39553956
// complain.
39563957
if (attr->isSwift3Inferred() &&
3957-
!tc.Context.LangOpts.WarnSwift3ObjCInference) {
3958+
tc.Context.LangOpts.WarnSwift3ObjCInference
3959+
== Swift3ObjCInferenceWarnings::Minimal) {
39583960
tc.diagnose(E->getLoc(), diag::expr_selector_swift3_objc_inference,
39593961
foundDecl->getDescriptiveKind(), foundDecl->getFullName(),
39603962
foundDecl->getDeclContext()

lib/Sema/TypeCheckDecl.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2416,7 +2416,9 @@ static Optional<ObjCReason> shouldMarkAsObjC(TypeChecker &TC,
24162416
if (TC.Context.LangOpts.EnableSwift3ObjCInference) {
24172417
// If we've been asked to warn about deprecated @objc inference, do so
24182418
// now.
2419-
if (TC.Context.LangOpts.WarnSwift3ObjCInference && !isAccessor) {
2419+
if (TC.Context.LangOpts.WarnSwift3ObjCInference !=
2420+
Swift3ObjCInferenceWarnings::None &&
2421+
!isAccessor) {
24202422
TC.diagnose(VD, diag::objc_inference_swift3_dynamic)
24212423
.highlight(attr->getLocation())
24222424
.fixItInsert(VD->getAttributeInsertionLoc(/*forModifier=*/false),
@@ -2845,7 +2847,8 @@ void swift::markAsObjC(TypeChecker &TC, ValueDecl *D,
28452847
// If we've been asked to unconditionally warn about these deprecated
28462848
// @objc inference rules, do so now. However, we don't warn about
28472849
// accessors---just the main storage declarations.
2848-
if (TC.Context.LangOpts.WarnSwift3ObjCInference &&
2850+
if (TC.Context.LangOpts.WarnSwift3ObjCInference ==
2851+
Swift3ObjCInferenceWarnings::Complete &&
28492852
!(isa<FuncDecl>(D) && cast<FuncDecl>(D)->isGetterOrSetter())) {
28502853
TC.diagnose(D, diag::objc_inference_swift3_objc_derived);
28512854
TC.diagnose(D, diag::objc_inference_swift3_addobjc)
@@ -6136,7 +6139,8 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
61366139

61376140
// When warning about all deprecated @objc inference rules,
61386141
// we only need to do this check if we have implicit 'dynamic'.
6139-
if (TC.Context.LangOpts.WarnSwift3ObjCInference) {
6142+
if (TC.Context.LangOpts.WarnSwift3ObjCInference !=
6143+
Swift3ObjCInferenceWarnings::None) {
61406144
if (auto dynamicAttr = Base->getAttrs().getAttribute<DynamicAttr>())
61416145
if (!dynamicAttr->isImplicit()) return;
61426146
}

lib/Sema/TypeCheckExprObjC.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -333,7 +333,8 @@ Optional<Type> TypeChecker::checkObjCKeyPathExpr(DeclContext *dc,
333333
// If this attribute was inferred based on deprecated Swift 3 rules,
334334
// complain.
335335
if (attr->isSwift3Inferred() &&
336-
!Context.LangOpts.WarnSwift3ObjCInference) {
336+
Context.LangOpts.WarnSwift3ObjCInference ==
337+
Swift3ObjCInferenceWarnings::Minimal) {
337338
diagnose(componentNameLoc, diag::expr_keypath_swift3_objc_inference,
338339
var->getFullName(),
339340
var->getDeclContext()

test/attr/attr_objc_swift3_deprecated.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %target-swift-frontend -disable-objc-attr-requires-foundation-module -typecheck -verify %s -swift-version 3 -warn-swift3-objc-inference
1+
// RUN: %target-swift-frontend -disable-objc-attr-requires-foundation-module -typecheck -verify %s -swift-version 3 -warn-swift3-objc-inference-complete
22
// REQUIRES: objc_interop
33

44
import Foundation

test/attr/attr_objc_swift3_deprecated_uses.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %target-swift-frontend -disable-objc-attr-requires-foundation-module -typecheck -verify %s -swift-version 3
1+
// RUN: %target-swift-frontend -disable-objc-attr-requires-foundation-module -typecheck -verify %s -swift-version 3 -warn-swift3-objc-inference-minimal
22
// REQUIRES: objc_interop
33

44
import Foundation
@@ -30,9 +30,9 @@ class ObjCSubclass : NSObject {
3030
}
3131

3232
class DynamicMembers {
33-
dynamic func foo() { }
33+
dynamic func foo() { } // expected-warning{{inference of '@objc' for 'dynamic' members is deprecated}}{{3-3=@objc }}
3434

35-
dynamic var bar: NSObject? = nil
35+
dynamic var bar: NSObject? = nil // expected-warning{{inference of '@objc' for 'dynamic' members is deprecated}}{{3-3=@objc }}
3636

3737
func overridableFunc() { }
3838
var overridableVar: NSObject? = nil

0 commit comments

Comments
 (0)