You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: proposals/0443-warning-control-flags.md
+37-36Lines changed: 37 additions & 36 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -32,19 +32,19 @@ The `<group>` parameter is a string identifier of the diagnostic group.
32
32
33
33
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.
34
34
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.
36
36
37
37
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.
38
38
39
39
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."
40
40
41
41
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.
42
42
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.
44
44
45
45
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:
46
46
```
47
-
main.swift:33:1: warning: 'f()' is deprecated [availability_deprecated]
47
+
main.swift:33:1: warning: 'f()' is deprecated [#DeprecatedDeclaration]
48
48
```
49
49
50
50
## Detailed design
@@ -57,22 +57,22 @@ Diagnostic groups form an acyclic graph with the following properties:
57
57
- When using the `-print-diagnostic-groups` flag, it would be inconvenient if a warning corresponded to multiple groups.
58
58
- Documentation lookup will also be easier for the user if a diagnostic has only one identifier.
59
59
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`.
61
61
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.
63
63
64
64
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.
66
66
- 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.
67
67
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:
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.
76
76
77
77
### Compiler options evaluation
78
78
@@ -87,20 +87,21 @@ Compiler options for controlling the behavior of groups are now processed as a s
87
87
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.
88
88
89
89
Examples of option combinations:
90
-
-`-warnings-as-errors -Wwarning deprecated`
90
+
-`-warnings-as-errors -Wwarning Deprecated`
91
91
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.
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.
97
97
98
98
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.
99
99
100
100
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.
104
105
105
106
#### Interaction with `-suppress-warnings`
106
107
@@ -123,15 +124,15 @@ oldFunction()
123
124
```
124
125
When compiled with the `-debug-diagnostic-names` option, the following message will be displayed:
125
126
```
126
-
'oldFunction()' is deprecated: renamed to 'newFunction' [availability_deprecated_rename]
127
+
'oldFunction()' is deprecated: renamed to 'newFunction' [#RenamedDeprecatedDeclaration]
127
128
```
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.
129
130
130
131
When compiling the same code with the `-print-diagnostic-groups` option, the following message will be displayed:
131
132
```
132
-
'oldFunction()' is deprecated: renamed to 'newFunction' [availability_deprecated]
133
+
'oldFunction()' is deprecated: renamed to 'newFunction' [#DeprecatedDeclaration]
133
134
```
134
-
Here, the string `availability_deprecated` is the diagnostic group.
135
+
Here, the string `DeprecatedDeclaration` is the diagnostic group.
135
136
136
137
Often, group names and internal diagnostic identifiers coincide, but this is not always the case.
137
138
@@ -169,31 +170,31 @@ The lack of control over the behavior of specific diagnostics forces users to ab
169
170
Warnings and errors in Swift can change as the compiler evolves.
170
171
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.
171
172
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.
173
174
174
175
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.
175
176
176
177
#### Flat list instead of a graph
177
178
178
179
To solve this problem, we could use an additional alias-ID for diagnostics that does not change when the main identifier changes.
179
180
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
0 commit comments