Remove DiagnosticsEditorMode

Migrate the last diagnostic to be independent of `DiagnosticEditorMode` and remove that option.

rdar://133111163
This commit is contained in:
Alex Hoppen
2024-08-08 16:47:50 -07:00
parent 915b5312ba
commit 577727ad55
27 changed files with 55 additions and 154 deletions

View File

@@ -84,13 +84,6 @@ The correct spelling of this feature is "fix-it" rather than "fixit". In [camelc
[camelcased]: https://en.wikipedia.org/wiki/Camel_case
### "Editor Mode" ###
The Swift compiler has a setting (under LangOptions) called `DiagnosticsEditorMode`. When set, diagnostics should be customized for an interactive editor that can display and apply complex fix-its, and worry less about the appearance in build logs and command-line environments.
Most diagnostics have no reason to change behavior under editor mode. An example of an exception is the "protocol requirements not satisfied diagnostic"; on the command line, it may be better to show all unsatisfied requirements, while in an IDE a single multi-line fix-it would be preferred.
### Educational Notes ###
Educational notes are short-form documentation attached to a diagnostic which explain relevant language concepts. They are intended to further Swift's goal of progressive disclosure by providing a learning resource at the point of use when encountering an error message for the first time. In very limited circumstances, they also allow the main diagnostic message to use precise terminology (e.g. nominal types) which would otherwise be too unfriendly for beginners.

View File

@@ -2813,11 +2813,10 @@ ERROR(conditional_conformances_cannot_imply_conformances,none,
NOTE(note_explicitly_state_conditional_conformance_different,none,
"did you mean to explicitly state the conformance with different bounds?", ())
NOTE(note_explicitly_state_conditional_conformance_relaxed,none,
"did you mean to explicitly state the conformance with relaxed bounds?", ())
"did you mean to explicitly state the conformance with relaxed bounds using '%0'?",
(StringRef))
NOTE(note_explicitly_state_conditional_conformance_same,none,
"did you mean to explicitly state the conformance with the same bounds?", ())
NOTE(note_explicitly_state_conditional_conformance_noneditor,none,
"did you mean to explicitly state the conformance like '%0where ...'?",
"did you mean to explicitly state the conformance with the same bounds using '%0'?",
(StringRef))
ERROR(protocol_has_missing_requirements,none,
"type %0 cannot conform to protocol %1 because it has requirements that "

View File

@@ -458,10 +458,6 @@ namespace swift {
/// [TODO: Clang-type-plumbing] Turn on for feature rollout.
bool UseClangFunctionTypes = false;
/// If set to true, the diagnosis engine can assume the emitted diagnostics
/// will be used in editor. This usually leads to more aggressive fixit.
bool DiagnosticsEditorMode = false;
/// Access or distribution level of the whole module being parsed.
LibraryLevel LibraryLevel = LibraryLevel::Other;

View File

@@ -779,9 +779,6 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args,
Opts.UseMalloc |= Args.hasArg(OPT_use_malloc);
Opts.DiagnosticsEditorMode |= Args.hasArg(OPT_diagnostics_editor_mode,
OPT_serialize_diagnostics_path);
Opts.EnableExperimentalConcurrency |=
Args.hasArg(OPT_enable_experimental_concurrency);

View File

@@ -223,7 +223,6 @@ bool ide::initCompilerInvocation(
auto &LangOpts = Invocation.getLangOptions();
LangOpts.AttachCommentsToDecls = true;
LangOpts.DiagnosticsEditorMode = true;
LangOpts.CollectParsedToken = true;
#if defined(_WIN32)
// Source files that might be open in an editor should not be memory mapped on Windows,

View File

@@ -2173,21 +2173,11 @@ static void diagnoseConformanceImpliedByConditionalConformance(
<< indent;
}
if (!ctxt.LangOpts.DiagnosticsEditorMode) {
// The fixits below are too complicated for the command line: the suggested
// code ends up not being displayed, and the text by itself doesn't help. So
// instead we skip all that and just have some text.
Diags.diagnose(loc,
diag::note_explicitly_state_conditional_conformance_noneditor,
prefix.str());
return;
}
// First, we do the fixit for "matching" requirements (i.e. X: P where T: P).
bool matchingIsValid = true;
llvm::SmallString<128> matchingFixit = prefix;
llvm::SmallString<128> matchingWhereClause;
{
llvm::raw_svector_ostream matchingStream(matchingFixit);
llvm::raw_svector_ostream matchingStream(matchingWhereClause);
matchingStream << "where ";
bool first = true;
for (const auto &req : implyingConf->getConditionalRequirements()) {
@@ -2207,35 +2197,30 @@ static void diagnoseConformanceImpliedByConditionalConformance(
}
if (matchingIsValid) {
matchingFixit += suffix;
Diags
.diagnose(loc,
diag::note_explicitly_state_conditional_conformance_relaxed)
.fixItInsert(loc, matchingFixit);
diag::note_explicitly_state_conditional_conformance_relaxed, matchingWhereClause)
.fixItInsert(loc, (prefix + matchingWhereClause + suffix).str());
}
// Next, do the fixit for using the same requirements, but be resilient to a
// missing `where` clause: this is one of a few fixits that get emitted here,
// and so is a very low priority diagnostic, and so shouldn't crash.
if (auto TWC = ext->getTrailingWhereClause()) {
llvm::SmallString<128> sameFixit = prefix;
llvm::SmallString<128> sameWhereClause;
auto CSR =
Lexer::getCharSourceRangeFromSourceRange(SM, TWC->getSourceRange());
sameFixit += SM.extractText(CSR);
sameFixit += suffix;
sameWhereClause += SM.extractText(CSR);
Diags
.diagnose(loc, diag::note_explicitly_state_conditional_conformance_same)
.fixItInsert(loc, sameFixit);
.diagnose(loc, diag::note_explicitly_state_conditional_conformance_same, sameWhereClause)
.fixItInsert(loc, (prefix + sameWhereClause + suffix).str());
}
// And finally, just the generic new-requirements one:
llvm::SmallString<128> differentFixit = prefix;
differentFixit += "where <#requirements#>";
differentFixit += suffix;
Diags
.diagnose(loc,
diag::note_explicitly_state_conditional_conformance_different)
.fixItInsert(loc, differentFixit);
.fixItInsert(loc, (prefix + "where <#requirements#>" + suffix).str());
}
/// Determine whether there are additional semantic checks for conformance

View File

@@ -11,7 +11,8 @@ extension Pair: Codable where A: Codable, B: Codable {}
extension Pair: Collection where A == B {
// expected-error@-1 {{conditional conformance of type 'Pair<A, B>' to protocol 'Collection' does not imply conformance to inherited protocol 'Sequence'}}
// expected-note@-2 {{did you mean to explicitly state the conformance like 'extension Pair: Sequence where ...'?}}
// expected-note@-2 {{did you mean to explicitly state the conformance with the same bounds using 'where A == B'?}}
// expected-note@-3 {{did you mean to explicitly state the conformance with different bounds?}}
typealias Element = A
var startIndex: Int { return 0 }

View File

@@ -148,8 +148,9 @@ struct CountSteps1<T> : Collection {
extension CountSteps1 // expected-error {{type 'CountSteps1<T>' does not conform to protocol 'RandomAccessCollection'}}
// expected-note@-1 {{add stubs for conformance}}
// expected-error@-2 {{conditional conformance of type 'CountSteps1<T>' to protocol 'RandomAccessCollection' does not imply conformance to inherited protocol 'BidirectionalCollection'}}
// expected-note@-3 {{did you mean to explicitly state the conformance like 'extension CountSteps1: BidirectionalCollection where ...'?}}
// expected-error@-4 {{type 'CountSteps1<T>' does not conform to protocol 'BidirectionalCollection'}}
// expected-note@-3 {{did you mean to explicitly state the conformance with the same bounds using 'where T : Equatable'?}}
// expected-note@-4 {{did you mean to explicitly state the conformance with different bounds?}}
// expected-error@-5 {{type 'CountSteps1<T>' does not conform to protocol 'BidirectionalCollection'}}
: RandomAccessCollection
where T : Equatable
{

View File

@@ -9,7 +9,9 @@ struct One<T> { // expected-note {{consider making generic parameter 'T' confor
extension One: P where T: P {}
// expected-error@-1 {{conditional conformance of type 'One<T>' to protocol 'P' does not imply conformance to inherited protocol 'Sendable'}}
// expected-note@-2 {{did you mean to explicitly state the conformance like 'extension One: Sendable where ...'}}
// expected-note@-2 {{did you mean to explicitly state the conformance with relaxed bounds using 'where T: Sendable'?}}
// expected-note@-3 {{did you mean to explicitly state the conformance with the same bounds using 'where T: P'?}}
// expected-note@-4 {{did you mean to explicitly state the conformance with different bounds?}}
struct Both<T> { // expected-note {{consider making generic parameter 'T' conform to the 'Sendable' protocol}}
var t: T // expected-error {{stored property 't' of 'Sendable'-conforming generic struct 'Both' has non-sendable type 'T'}}
@@ -17,7 +19,9 @@ struct Both<T> { // expected-note {{consider making generic parameter 'T' confor
extension Both: P where T: P {}
// expected-error@-1 {{conditional conformance of type 'Both<T>' to protocol 'P' does not imply conformance to inherited protocol 'Sendable'}}
// expected-note@-2 {{did you mean to explicitly state the conformance like 'extension Both: Sendable where ...'}}
// expected-note@-2 {{did you mean to explicitly state the conformance with relaxed bounds using 'where T: Sendable'?}}
// expected-note@-3 {{did you mean to explicitly state the conformance with the same bounds using 'where T: P'?}}
// expected-note@-4 {{did you mean to explicitly state the conformance with different bounds?}}
extension Both: Q where T: Q {}

View File

@@ -1,4 +1,4 @@
// RUN: not %swift -typecheck -target %target-triple -primary-file %s -emit-fixits-path %t.main.remap -primary-file %S/Inputs/batch-mode-helper.swift -emit-fixits-path %t.helper.remap -diagnostics-editor-mode
// RUN: not %swift -typecheck -target %target-triple -primary-file %s -emit-fixits-path %t.main.remap -primary-file %S/Inputs/batch-mode-helper.swift -emit-fixits-path %t.helper.remap
// RUN: %FileCheck -check-prefix=CHECK-MAIN %s < %t.main.remap
// RUN: %FileCheck -check-prefix=NEGATIVE-MAIN %s < %t.main.remap
// RUN: %FileCheck -check-prefix=CHECK-HELPER %s < %t.helper.remap

View File

@@ -1,4 +1,4 @@
// RUN: %target-typecheck-verify-swift %s -I %S/Inputs -diagnostics-editor-mode
// RUN: %target-typecheck-verify-swift %s -I %S/Inputs
enum E1 {
case e1
@@ -17,6 +17,6 @@ func foo1(_ e: E1) {
}
func foo1 (_ i : Int) {
switch i { // expected-error {{'switch' statement body must have at least one 'case' or 'default' block; add a default case}} {{+1:3-3=default:\n<#code#>\n}}
switch i { // expected-error {{'switch' statement body must have at least one 'case' or 'default' block; add a default case}} {{+1:3-3=default:\n<#code#>\n}}
}
}

View File

@@ -1,4 +1,4 @@
// RUN: not %swift -emit-sil -target %target-triple %s -emit-fixits-path %t.remap -I %S/Inputs -diagnostics-editor-mode
// RUN: not %swift -emit-sil -target %target-triple %s -emit-fixits-path %t.remap -I %S/Inputs
// RUN: c-arcmt-test %t.remap | arcmt-test -verify-transformed-files %s.result
func something() -> Bool { return true }

View File

@@ -1,4 +1,4 @@
// RUN: not %swift -emit-sil -target %target-triple %s -emit-fixits-path %t.remap -I %S/Inputs -diagnostics-editor-mode
// RUN: not %swift -emit-sil -target %target-triple %s -emit-fixits-path %t.remap -I %S/Inputs
// RUN: c-arcmt-test %t.remap | arcmt-test -verify-transformed-files %s.result
func something() -> Bool { return true }

View File

@@ -1,4 +1,4 @@
// RUN: %target-swift-frontend -emit-sil %s -enable-library-evolution -enable-nonfrozen-enum-exhaustivity-diagnostics -diagnostics-editor-mode -verify -swift-version 6
// RUN: %target-swift-frontend -emit-sil %s -enable-library-evolution -enable-nonfrozen-enum-exhaustivity-diagnostics -verify -swift-version 6
enum Runcible {
case spoon

View File

@@ -1,4 +1,4 @@
// RUN: %target-swift-frontend -emit-sil %s -I %S/Inputs -diagnostics-editor-mode -verify
// RUN: %target-swift-frontend -emit-sil %s -I %S/Inputs -verify
enum E1 : Int {
case e1

View File

@@ -334,14 +334,16 @@ struct InheritImplicitOne<T> {}
// incorrect/insufficiently general).
extension InheritImplicitOne: P5 where T: P1 {}
// expected-error@-1{{conditional conformance of type 'InheritImplicitOne<T>' to protocol 'P5' does not imply conformance to inherited protocol 'P2'}}
// expected-note@-2{{did you mean to explicitly state the conformance like 'extension InheritImplicitOne: P2 where ...'?}}
// expected-note@-2{{did you mean to explicitly state the conformance with the same bounds using 'where T: P1'?}}
// expected-note@-3 {{did you mean to explicitly state the conformance with different bounds?}}
struct InheritImplicitTwo<T> {}
// Even if we relax the rule about implication, this double-up should still be
// an error, because either conformance could imply InheritImplicitTwo: P2.
extension InheritImplicitTwo: P5 where T: P1 {}
// expected-error@-1{{conditional conformance of type 'InheritImplicitTwo<T>' to protocol 'P5' does not imply conformance to inherited protocol 'P2'}}
// expected-note@-2{{did you mean to explicitly state the conformance like 'extension InheritImplicitTwo: P2 where ...'?}}
// expected-note@-2{{did you mean to explicitly state the conformance with the same bounds using 'where T: P1'?}}
// expected-note@-3 {{did you mean to explicitly state the conformance with different bounds?}}
extension InheritImplicitTwo: P6 where T: P1 {}
// However, if there's a non-conditional conformance that implies something, we

View File

@@ -1,5 +1,4 @@
// RUN: %target-typecheck-verify-swift -emit-fixits-path %t.remap -fixit-all -diagnostics-editor-mode
// RUN: c-arcmt-test %t.remap | arcmt-test -verify-transformed-files %s.result
// RUN: %target-typecheck-verify-swift
protocol P1 {}
protocol P2: P1 {}
@@ -9,8 +8,8 @@ struct S1<T> {}
extension S1: P2 where T: P1 {}
// expected-error@-1 {{conditional conformance of type 'S1<T>' to protocol 'P2' does not imply conformance to inherited protocol 'P1'}}
// expected-note@-2 {{did you mean to explicitly state the conformance with the same bounds?}}
// expected-note@-3 {{did you mean to explicitly state the conformance with different bounds?}}
// expected-note@-2 {{did you mean to explicitly state the conformance with the same bounds using 'where T: P1'?}} {{1-1=extension S1: P1 where T: P1 {\n <#witnesses#>\n\}\n\n}}
// expected-note@-3 {{did you mean to explicitly state the conformance with different bounds?}} {{1-1=extension S1: P1 where <#requirements#> {\n <#witnesses#>\n\}\n\n}}
protocol P3 {
associatedtype X
@@ -19,23 +18,23 @@ struct S2<T, U, V: P3> {}
extension S2: P2 where T: P2, U: P2, V.X: P2 {}
// expected-error@-1 {{conditional conformance of type 'S2<T, U, V>' to protocol 'P2' does not imply conformance to inherited protocol 'P1'}}
// expected-note@-2 {{did you mean to explicitly state the conformance with relaxed bounds?}}
// expected-note@-3 {{did you mean to explicitly state the conformance with the same bounds?}}
// expected-note@-4 {{did you mean to explicitly state the conformance with different bounds?}}
// expected-note@-2 {{did you mean to explicitly state the conformance with relaxed bounds using 'where T: P1, U: P1, V.X: P1'?}} {{1-1=extension S2: P1 where T: P1, U: P1, V.X: P1 {\n <#witnesses#>\n\}\n\n}}
// expected-note@-3 {{did you mean to explicitly state the conformance with the same bounds using 'where T: P2, U: P2, V.X: P2'?}} {{1-1=extension S2: P1 where T: P2, U: P2, V.X: P2 {\n <#witnesses#>\n\}\n\n}}
// expected-note@-4 {{did you mean to explicitly state the conformance with different bounds?}} {{1-1=extension S2: P1 where <#requirements#> {\n <#witnesses#>\n\}\n\n}}
struct S3<T, U, V: P3> {}
extension S3: P2 where T: P2, U: P2, V.X == Int {}
// expected-error@-1 {{conditional conformance of type 'S3<T, U, V>' to protocol 'P2' does not imply conformance to inherited protocol 'P1'}}
// expected-note@-2 {{did you mean to explicitly state the conformance with the same bounds?}}
// expected-note@-3 {{did you mean to explicitly state the conformance with different bounds?}}
// expected-note@-2 {{did you mean to explicitly state the conformance with the same bounds using 'where T: P2, U: P2, V.X == Int'?}} {{1-1=extension S3: P1 where T: P2, U: P2, V.X == Int {\n <#witnesses#>\n\}\n\n}}
// expected-note@-3 {{did you mean to explicitly state the conformance with different bounds?}} {{1-1=extension S3: P1 where <#requirements#> {\n <#witnesses#>\n\}\n\n}}
struct S4<T, U, V: P3> {}
extension S4: P2 where T: P2, U: P3, V.X: P2 {}
// expected-error@-1 {{conditional conformance of type 'S4<T, U, V>' to protocol 'P2' does not imply conformance to inherited protocol 'P1'}}
// expected-note@-2 {{did you mean to explicitly state the conformance with the same bounds?}}
// expected-note@-3 {{did you mean to explicitly state the conformance with different bounds?}}
// expected-note@-2 {{did you mean to explicitly state the conformance with the same bounds using 'where T: P2, U: P3, V.X: P2'?}} {{1-1=extension S4: P1 where T: P2, U: P3, V.X: P2 {\n <#witnesses#>\n\}\n\n}}
// expected-note@-3 {{did you mean to explicitly state the conformance with different bounds?}} {{1-1=extension S4: P1 where <#requirements#> {\n <#witnesses#>\n\}\n\n}}

View File

@@ -1,77 +0,0 @@
// RUN: %target-typecheck-verify-swift -emit-fixits-path %t.remap -fixit-all -diagnostics-editor-mode
// RUN: c-arcmt-test %t.remap | arcmt-test -verify-transformed-files %s.result
protocol P1 {}
protocol P2: P1 {}
struct S1<T> {}
extension S1: P1 where T: P1 {
<#witnesses#>
}
extension S1: P1 where <#requirements#> {
<#witnesses#>
}
extension S1: P2 where T: P1 {}
// expected-error@-1 {{conditional conformance of type 'S1<T>' to protocol 'P2' does not imply conformance to inherited protocol 'P1'}}
// expected-note@-2 {{did you mean to explicitly state the conformance with the same bounds?}}
// expected-note@-3 {{did you mean to explicitly state the conformance with different bounds?}}
protocol P3 {
associatedtype X
}
struct S2<T, U, V: P3> {}
extension S2: P1 where T: P1, U: P1, V.X: P1 {
<#witnesses#>
}
extension S2: P1 where T: P2, U: P2, V.X: P2 {
<#witnesses#>
}
extension S2: P1 where <#requirements#> {
<#witnesses#>
}
extension S2: P2 where T: P2, U: P2, V.X: P2 {}
// expected-error@-1 {{conditional conformance of type 'S2<T, U, V>' to protocol 'P2' does not imply conformance to inherited protocol 'P1'}}
// expected-note@-2 {{did you mean to explicitly state the conformance with relaxed bounds?}}
// expected-note@-3 {{did you mean to explicitly state the conformance with the same bounds?}}
// expected-note@-4 {{did you mean to explicitly state the conformance with different bounds?}}
struct S3<T, U, V: P3> {}
extension S3: P1 where T: P2, U: P2, V.X == Int {
<#witnesses#>
}
extension S3: P1 where <#requirements#> {
<#witnesses#>
}
extension S3: P2 where T: P2, U: P2, V.X == Int {}
// expected-error@-1 {{conditional conformance of type 'S3<T, U, V>' to protocol 'P2' does not imply conformance to inherited protocol 'P1'}}
// expected-note@-2 {{did you mean to explicitly state the conformance with the same bounds?}}
// expected-note@-3 {{did you mean to explicitly state the conformance with different bounds?}}
struct S4<T, U, V: P3> {}
extension S4: P1 where T: P2, U: P3, V.X: P2 {
<#witnesses#>
}
extension S4: P1 where <#requirements#> {
<#witnesses#>
}
extension S4: P2 where T: P2, U: P3, V.X: P2 {}
// expected-error@-1 {{conditional conformance of type 'S4<T, U, V>' to protocol 'P2' does not imply conformance to inherited protocol 'P1'}}
// expected-note@-2 {{did you mean to explicitly state the conformance with the same bounds?}}
// expected-note@-3 {{did you mean to explicitly state the conformance with different bounds?}}

View File

@@ -34,8 +34,10 @@ protocol Derived1: Base1 {}
extension Tuple: Derived1 where repeat each Element: Derived1 {}
// expected-error@-1 {{conditional conformance of type '(repeat each Element)' to protocol 'Derived1' does not imply conformance to inherited protocol 'Base1'}}
// expected-note@-2 {{did you mean to explicitly state the conformance like 'extension Tuple: Base1 where ...'?}}
// expected-error@-3 {{tuple extension must declare conformance to exactly one protocol}}
// expected-note@-2 {{did you mean to explicitly state the conformance with relaxed bounds using 'where each Element: Base1'?}}
// expected-note@-3 {{did you mean to explicitly state the conformance with the same bounds using 'where repeat each Element: Derived1'?}}
// expected-note@-4 {{did you mean to explicitly state the conformance with different bounds?}}
// expected-error@-5 {{tuple extension must declare conformance to exactly one protocol}}
protocol Base2 {}
protocol Derived2: Base2 {}

View File

@@ -1,6 +1,6 @@
// RUN: %empty-directory(%t)
// RUN: %target-build-swift -emit-module -emit-library -module-name Types %S/Inputs/fixits-derived-conformances-multifile.swift -o %t/%target-library-name(Types)
// RUN: %swift -typecheck -target %target-triple -I %t -diagnostics-editor-mode -verify %s
// RUN: %swift -typecheck -target %target-triple -I %t -verify %s
import Types

View File

@@ -1,4 +1,4 @@
// RUN: %target-typecheck-verify-swift -enable-experimental-feature Extern -emit-fixits-path %t.remap -fixit-all -diagnostics-editor-mode
// RUN: %target-typecheck-verify-swift -enable-experimental-feature Extern -emit-fixits-path %t.remap -fixit-all
// RUN: c-arcmt-test %t.remap | arcmt-test -verify-transformed-files %s.result
@_extern(c) // expected-warning {{C name '+' may be invalid; explicitly specify the name in @_extern(c) to suppress this warning}}

View File

@@ -1,4 +1,4 @@
// RUN: %target-typecheck-verify-swift -enable-experimental-feature Extern -emit-fixits-path %t.remap -fixit-all -diagnostics-editor-mode
// RUN: %target-typecheck-verify-swift -enable-experimental-feature Extern -emit-fixits-path %t.remap -fixit-all
// RUN: c-arcmt-test %t.remap | arcmt-test -verify-transformed-files %s.result
@_extern(c, "+") // expected-warning {{C name '+' may be invalid; explicitly specify the name in @_extern(c) to suppress this warning}}

View File

@@ -1,7 +1,7 @@
// RUN: %empty-directory(%t)
// RUN: %target-swift-frontend %S/Inputs/fixit_stub_mutability_proto_module.swift -emit-module -parse-as-library -o %t
// RUN: %target-swift-frontend -typecheck %s -I %t -verify -diagnostics-editor-mode
// RUN: %target-swift-frontend -typecheck %s -I %t -verify
protocol P0_A { associatedtype T } // expected-note{{protocol requires nested type 'T'}}
protocol P0_B { associatedtype T }

View File

@@ -1,7 +1,7 @@
// RUN: %empty-directory(%t)
// RUN: %target-swift-frontend %S/Inputs/fixit_stub_ambiguity_module.swift -module-name Ambiguous -emit-module -parse-as-library -o %t
// RUN: %target-swift-frontend -typecheck %s -I %t -verify -diagnostics-editor-mode
// RUN: %target-swift-frontend -typecheck %s -I %t -verify
import Ambiguous

View File

@@ -1,4 +1,4 @@
// RUN: %target-swift-frontend -typecheck -diagnostics-editor-mode -verify %s
// RUN: %target-swift-frontend -typecheck -verify %s
// Test that we emit fix-its to insert requirement stubs for the missing protocol conformance, in addition to adding the conformance.

View File

@@ -1,4 +1,4 @@
// RUN: %target-typecheck-verify-swift -diagnostics-editor-mode -enable-library-evolution -enable-nonfrozen-enum-exhaustivity-diagnostics
// RUN: %target-typecheck-verify-swift -enable-library-evolution -enable-nonfrozen-enum-exhaustivity-diagnostics
public enum NonExhaustive {
case a, b