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
compiler/hir/check: be more clear about transparent layout violations
Extend the error-messages of rustc to distinguish between non-zero-sized
fields and fields without layout when annotating `repr(transparent)`
violations.
When compiling `repr(transparent)` structures, the compiler checks that
there is at most one field with non-zero size *OR* having unknown
layout. However, the error message treats both conditions as the same,
thus always annotating them as;
a: u32,
------ this field is non-zero-sized
In most situations, this is reasonable. However, if you consider generic
fields, this can easily become confusing. Consider the following error
message:
a: [T; 0],
--------- this field is non-zero-sized
This field is clearly zero-sized, yet the compiler is correct to refuse
it. This is because the field might raise the alignment requirements of
the transparent field, thus change the overall layout.
This patch changes the error message to distinguish non-zero-sized
fields _with_ known layout from fields with _unknown_ layout. The logic
_when_ to emit errors is not changed. Before this patch, it would emit
an error when `non_zst_count >= 2` (but `non_zst_count` counted fields
without layout *AND* fields with guaranteed non-zero layout). After this
patch, `non_zst_count` is changed to only count fields with guaranteed
non-zero layout, but `non_layout_count` counts fields without layout.
The new `non_transparent_count` is the sum of both and should be
equivalent to the previous `non_zst_count`.
Long story short, the new error output looks like this:
error[E0690]: transparent struct needs at most one field of non-zero size or alignment larger than 1, but has 2
--> src/foobar.rs:2:1
|
2 | struct Test<T: Sized> {
| ^^^^^^^^^^^^^^^^^^^^^ needs at most one field of non-zero size or alignment larger than 1, but has 2
3 | a: u32,
| ------ this field is non-zero-sized
4 | b: [T; 0],
| --------- this field may have alignment larger than 1
Previously, any field without known layout was annotated as "non-zero
size", now this is changed to annotate those fields as "may have
alignment larger than 1". This is a catch-all that is, to my knowledge,
true for all generic fields without layout, since one cannot control
their alignment. This might need refinement in the future, when other
cases of layout-violation occur.
One might even argue that the entire error-message could be made more
generic, ala:
transparent struct needs at most one field with non-trivial layout
However, I think the current error-message is much more helpful in
stating the 2 obvious violations: non-ZST and non-alignment-of-1
Hence, this commit retains the original error-message style and simply
extends it with the alignment-violation notice.
Originally reported in: #98064
Copy file name to clipboardExpand all lines: compiler/rustc_hir_analysis/messages.ftl
+9-7
Original file line number
Diff line number
Diff line change
@@ -270,13 +270,15 @@ hir_analysis_transparent_enum_variant = transparent enum needs exactly one varia
270
270
.many_label = too many variants in `{$path}`
271
271
.multi_label = variant here
272
272
273
-
hir_analysis_transparent_non_zero_sized = transparent {$desc} needs at most one non-zero-sized field, but has {$field_count}
274
-
.label = needs at most one non-zero-sized field, but has {$field_count}
275
-
.labels = this field is non-zero-sized
276
-
277
-
hir_analysis_transparent_non_zero_sized_enum = the variant of a transparent {$desc} needs at most one non-zero-sized field, but has {$field_count}
278
-
.label = needs at most one non-zero-sized field, but has {$field_count}
279
-
.labels = this field is non-zero-sized
273
+
hir_analysis_transparent_layout = transparent {$desc} needs at most one field of non-zero size or alignment larger than 1, but has {$field_count}
274
+
.label = needs at most one field of non-zero size or alignment larger than 1, but has {$field_count}
275
+
.non_layout_labels = this field may have an alignment larger than 1
276
+
.non_zst_labels = this field is non-zero-sized
277
+
278
+
hir_analysis_transparent_layout_enum = the variant of a transparent {$desc} needs at most one field of non-zero size or alignment larger than 1, but has {$field_count}
279
+
.label = needs at most one field of non-zero size or alignment larger than 1, but has {$field_count}
280
+
.non_layout_labels = this field may have an alignment larger than 1
0 commit comments