Skip to content

Commit 142e5dd

Browse files
authored
Merge pull request #2829 from tshortli/se0433-diagnostic-group-name-style
SE-0443: Update proposal to reflect chosen diagnostic group name style
2 parents 937c901 + 83cd77f commit 142e5dd

File tree

1 file changed

+37
-36
lines changed

1 file changed

+37
-36
lines changed

proposals/0443-warning-control-flags.md

Lines changed: 37 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -32,19 +32,19 @@ The `<group>` parameter is a string identifier of the diagnostic group.
3232

3333
A diagnostic group is a stable identifier for an error or warning. It is an abstraction layer over the diagnostic identifiers used within the compiler. This is necessary because diagnostics within the compiler may change, but we need to provide stable user-facing identifiers for them.
3434

35-
A diagnostic group may include errors, warnings, or other diagnostic groups. For example, the `availability_deprecated` diagnostic group includes warnings related to the use of an API marked with the `@available(..., deprecated: ...)` attribute. The `deprecated` diagnostic group includes the `availability_deprecated` group and other groups related to deprecation.
35+
A diagnostic group may include errors, warnings, or other diagnostic groups. For example, the `DeprecatedDeclaration` diagnostic group includes warnings related to the use of an API marked with the `@available(..., deprecated: ...)` attribute. The `Deprecated` diagnostic group includes the `DeprecatedDeclaration` group and other groups related to deprecation.
3636

3737
Diagnostic groups may expand over time, but they can never become narrower. When a new diagnostic is added to the compiler, it is either included in an existing group or a new group is created for it, which in turn can also be included in one of the broader groups, if appropriate.
3838

3939
The order in which these flags are specified when invoking the compiler is important. If two or more options change the behavior of the same warning, we follow the rule "the last one wins."
4040

4141
We also retain the existing compiler options but modify their handling algorithm so that they are considered in the general list with the new options and follow the "last one wins" rule as well.
4242

43-
Thus, for example, you can use the combination `-warnings-as-errors -Wwarning deprecated`, which will upgrade all warnings to errors except for those in the `deprecated` group. However, if these flags are specified in the reverse order(`-Wwarning deprecated -warnings-as-errors`) it will be interpreted as upgrading all warnings to errors, as the `-warnings-as-errors` flag is the last one.
43+
Thus, for example, you can use the combination `-warnings-as-errors -Wwarning Deprecated`, which will upgrade all warnings to errors except for those in the `Deprecated` group. However, if these flags are specified in the reverse order(`-Wwarning Deprecated -warnings-as-errors`) it will be interpreted as upgrading all warnings to errors, as the `-warnings-as-errors` flag is the last one.
4444

4545
We are also introducing a new compiler flag, `-print-diagnostic-groups`, to display the names of diagnostic groups along with the textual representation of the warnings. When used, the warning message will be followed by the name of the narrowest group that includes that warning, enclosed in square brackets. For example:
4646
```
47-
main.swift:33:1: warning: 'f()' is deprecated [availability_deprecated]
47+
main.swift:33:1: warning: 'f()' is deprecated [#DeprecatedDeclaration]
4848
```
4949

5050
## Detailed design
@@ -57,22 +57,22 @@ Diagnostic groups form an acyclic graph with the following properties:
5757
- When using the `-print-diagnostic-groups` flag, it would be inconvenient if a warning corresponded to multiple groups.
5858
- Documentation lookup will also be easier for the user if a diagnostic has only one identifier.
5959

60-
- A diagnostic group may include any number of other diagnostic groups. This will allow organizing groups into sets with similar meanings but different specific diagnostics. For example, the warnings `availability_deprecated` and `unsafe_global_actor_deprecated` are part of the supergroup `deprecated`.
60+
- A diagnostic group may include any number of other diagnostic groups. This will allow organizing groups into sets with similar meanings but different specific diagnostics. For example, the warnings `DeprecatedDeclaration` and `UnsafeGlobalActorDeprecated` are part of the supergroup `Deprecated`.
6161

62-
- A diagnostic group can be included in any number of diagnostic groups. This allows expressing the membership of a group in multiple supergroups, where appropriate. For example, the group `unsafe_global_actor_deprecated` is part of both the `deprecated` and `concurrency` groups.
62+
- A diagnostic group can be included in any number of diagnostic groups. This allows expressing the membership of a group in multiple supergroups, where appropriate. For example, the group `UnsafeGlobalActorDeprecated` is part of both the `Deprecated` and `Concurrency` groups.
6363

6464
The internal structure of the graph may change to some extent. However, the set of diagnostics included in a diagnostic group (directly or transitively) should not shrink. There are two typical situations where the graph structure may change:
65-
- When adding a new diagnostic to the compiler, consider creating a new group corresponding to that diagnostic. If the new group is created it can also be included in one or more existing groups if it belongs to them. For example, it is expected that the `deprecated` group will continuously include new subgroups.
65+
- When adding a new diagnostic to the compiler, consider creating a new group corresponding to that diagnostic. If the new group is created it can also be included in one or more existing groups if it belongs to them. For example, it is expected that the `Deprecated` group will continuously include new subgroups.
6666
- If an existing diagnostic is split into more specific versions, and we want to allow users to use the more specific version in compiler options, a separate group is created for it, which **must** be included in the group of the original diagnostic.
6767

68-
For example, suppose we split the `availability_deprecated` warning into a general version and a specialized version `availability_deprecated_same_module`, which the compiler emits if the deprecated symbol is declared in the same module. In this case, the `availability_deprecated_same_module` group must be added to the `availability_deprecated` group to ensure that the overall composition of the `availability_deprecated` group does not change. The final structure should look like this:
68+
For example, suppose we split the `DeprecatedDeclaration` warning into a general version and a specialized version `DeprecatedDeclarationSameModule`, which the compiler emits if the deprecated symbol is declared in the same module. In this case, the `DeprecatedDeclarationSameModule` group must be added to the `DeprecatedDeclaration` group to ensure that the overall composition of the `DeprecatedDeclaration` group does not change. The final structure should look like this:
6969
```
70-
availability_deprecated (group)
71-
├─ availability_deprecated (internal diag id)
72-
└─ availability_deprecated_same_module (group)
73-
└─ availability_deprecated_same_module (internal diag id)
70+
DeprecatedDeclaration (group)
71+
├─ DeprecatedDeclaration (internal diag id)
72+
└─ DeprecatedDeclarationSameModule (group)
73+
└─ DeprecatedDeclarationSameModule (internal diag id)
7474
```
75-
Thus, invoking the compiler with the `-Werror availability_deprecated` parameter will cover both versions of the warning, and the behavior will remain unchanged. At the same time, the user can control the behavior of the narrower `availability_deprecated_same_module` group if they want to.
75+
Thus, invoking the compiler with the `-Werror DeprecatedDeclaration` parameter will cover both versions of the warning, and the behavior will remain unchanged. At the same time, the user can control the behavior of the narrower `DeprecatedDeclarationSameModule` group if they want to.
7676

7777
### Compiler options evaluation
7878

@@ -87,20 +87,21 @@ Compiler options for controlling the behavior of groups are now processed as a s
8787
When these options are passed to the compiler, we sequentially apply the specified behavior to all warnings within the specified group from left to right. For `-warnings-as-errors` and `-no-warnings-as-errors`, we apply the behavior to all warnings.
8888

8989
Examples of option combinations:
90-
- `-warnings-as-errors -Wwarning deprecated`
90+
- `-warnings-as-errors -Wwarning Deprecated`
9191

92-
Warnings from the `deprecated` group will be kept as warnings, but all the rest will be upgraded to errors.
92+
Warnings from the `Deprecated` group will be kept as warnings, but all the rest will be upgraded to errors.
9393

94-
- `-Werror deprecated -Wwarning availability_deprecated`
94+
- `-Werror Deprecated -Wwarning DeprecatedDeclaration`
9595

96-
Warnings from the `availability_deprecated` group will remain as warnings. Other warnings from the `deprecated` group will be upgraded to errors. All others will be kept as warnings.
96+
Warnings from the `DeprecatedDeclaration` group will remain as warnings. Other warnings from the `Deprecated` group will be upgraded to errors. All others will be kept as warnings.
9797

9898
It’s crucial to understand that the order in which these flags are applied can significantly affect the behavior of diagnostics. The rule is "the last one wins", meaning that if multiple flags apply to the same diagnostic group, the last one specified on the command line will determine the final behavior.
9999

100100
It is also important to note that the order matters even if the specified groups are not explicitly related but have a common subgroup.
101-
For example, as mentioned above, the `unsafe_global_actor_deprecated` group is part of both the `deprecated` and `concurrency` groups. So the order in which options for the `deprecated` and `concurrency` groups are applied will change the final behavior of the `unsafe_global_actor_deprecated` group. Specifically:
102-
- `-Wwarning deprecated -Werror concurrency` will make it an error,
103-
- `-Werror concurrency -Wwarning deprecated` will keep it as a warning.
101+
For example, as mentioned above, the `UnsafeGlobalActorDeprecated` group is part of both the `Deprecated` and `Concurrency` groups. So the order in which options for the `Deprecated` and `Concurrency` groups are applied will change the final behavior of the `UnsafeGlobalActorDeprecated` group. Specifically:
102+
103+
- `-Wwarning Deprecated -Werror Concurrency` will make it an error,
104+
- `-Werror Concurrency -Wwarning Deprecated` will keep it as a warning.
104105

105106
#### Interaction with `-suppress-warnings`
106107

@@ -123,15 +124,15 @@ oldFunction()
123124
```
124125
When compiled with the `-debug-diagnostic-names` option, the following message will be displayed:
125126
```
126-
'oldFunction()' is deprecated: renamed to 'newFunction' [availability_deprecated_rename]
127+
'oldFunction()' is deprecated: renamed to 'newFunction' [#RenamedDeprecatedDeclaration]
127128
```
128-
The string `availability_deprecated_rename` is the internal identifier of this warning, not the group. Accordingly, it is not supported by the new compiler options.
129+
The string `RenamedDeprecatedDeclaration` is the internal identifier of this warning, not the group. Accordingly, it is not supported by the new compiler options.
129130

130131
When compiling the same code with the `-print-diagnostic-groups` option, the following message will be displayed:
131132
```
132-
'oldFunction()' is deprecated: renamed to 'newFunction' [availability_deprecated]
133+
'oldFunction()' is deprecated: renamed to 'newFunction' [#DeprecatedDeclaration]
133134
```
134-
Here, the string `availability_deprecated` is the diagnostic group.
135+
Here, the string `DeprecatedDeclaration` is the diagnostic group.
135136

136137
Often, group names and internal diagnostic identifiers coincide, but this is not always the case.
137138

@@ -169,31 +170,31 @@ The lack of control over the behavior of specific diagnostics forces users to ab
169170
Warnings and errors in Swift can change as the compiler evolves.
170171
For example, one error might be renamed or split into two that are applied in different situations to improve the clarity of the text message depending on the context. Such a change would result in a new ID for the new error variant.
171172

172-
The example of `availability_deprecated_same_module` illustrates this well. If we used the warning ID, the behavior of the compiler with the `-Wwarning availability_deprecated` option would change when a new version of the warning is introduced, as this warning would no longer be triggered for the specific case of the same module.
173+
The example of `DeprecatedDeclarationSameModule` illustrates this well. If we used the warning ID, the behavior of the compiler with the `-Wwarning DeprecatedDeclaration` option would change when a new version of the warning is introduced, as this warning would no longer be triggered for the specific case of the same module.
173174

174175
Therefore, we need a solution that allows us to modify errors and warnings within the compiler while providing a reliable mechanism for identifying diagnostics that can be used by the user.
175176

176177
#### Flat list instead of a graph
177178

178179
To solve this problem, we could use an additional alias-ID for diagnostics that does not change when the main identifier changes.
179180

180-
Suppose we split the `availability_deprecated` diagnostic into a generic variant and `availability_deprecated_same_module`. To retain the existing name for the new variant, we could describe these two groups as
181+
Suppose we split the `DeprecatedDeclaration` diagnostic into a generic variant and `DeprecatedDeclarationSameModule`. To retain the existing name for the new variant, we could describe these two groups as
181182
```
182-
availability_deprecated (alias: availability_deprecated)
183-
availability_deprecated_same_module (alias: availability_deprecated)
183+
DeprecatedDeclaration (alias: DeprecatedDeclaration)
184+
DeprecatedDeclarationSameModule (alias: DeprecatedDeclaration)
184185
```
185-
However, this solution would not allow specifying the narrower `availability_deprecated_same_module` or the broader group `deprecated`.
186+
However, this solution would not allow specifying the narrower `DeprecatedDeclarationSameModule` or the broader group `Deprecated`.
186187

187188
#### Using multiple alias IDs for diagnostics
188189
To express a diagnostic's membership in multiple groups, we could allow multiple alias-IDs to be listed.
189190
```
190-
availability_deprecated aliases:
191-
availability_deprecated
192-
deprecated
193-
availability_deprecated_same_module aliases:
194-
availability_deprecated_same_module
195-
availability_deprecated
196-
deprecated
191+
DeprecatedDeclaration aliases:
192+
DeprecatedDeclaration
193+
Deprecated
194+
DeprecatedDeclarationSameModule aliases:
195+
DeprecatedDeclarationSameModule
196+
DeprecatedDeclaration
197+
Deprecated
197198
```
198199
However, such a declaration lacks structure and makes it difficult to understand which alias-ID is the most specific.
199200

@@ -222,7 +223,7 @@ Since `-debug-diagnostic-names` has been available in the compiler for a long ti
222223

223224
To avoid overlap, we would need to use a different format, for example:
224225
```
225-
'foo()' is deprecated [availability_deprecated] [group:availability_deprecated]
226+
'foo()' is deprecated [#DeprecatedDeclaration] [group:#DeprecatedDeclaration]
226227
```
227228

228229
However, even this does not eliminate the possibility of breaking code that parses the compiler's output.

0 commit comments

Comments
 (0)