Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve diagnostic for E0691 #98071

Closed

Conversation

lukas-code
Copy link
Contributor

fixes #98064

@rustbot rustbot added the T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. label Jun 13, 2022
@rust-highfive
Copy link
Collaborator

r? @wesleywiser

(rust-highfive has picked a reviewer for you, use r? to override)

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Jun 13, 2022
@rust-log-analyzer

This comment has been minimized.

@lukas-code lukas-code force-pushed the repr-transparent-zero-array branch 2 times, most recently from 21c81a5 to 40fa282 Compare June 13, 2022 21:41
Comment on lines 1332 to 1336
let array_len = match ty.kind() {
Array(_, len) => len.try_eval_usize(tcx, param_env),
_ => None,
};
let zst = array_len == Some(0) || layout.map_or(false, |layout| layout.is_zst());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wait, doesn't this change the actual typechecking behavior?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

well, i guess not necessarily, because the align check below will still fail?

I would rather move this is-array check to line 1348, like if (zst || zero_sized_array) && align != Some(1) so we don't need to edit this logic, just in case?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've split zero_sized_array from zst, but the logic stays the same, otherwise we would get #98064 again.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also with a more complex zero-sized but non-trivially-aligned field, we still get the same wrong diagnostic:

struct ComplexZst<A, B> {
    a: [A; 0],
    b: [B; 0],
}

#[repr(transparent)]
struct Aligned<T, A, B> {
    align: ComplexZst<A, B>,
    value: T,
}
error[E0690]: transparent struct needs at most one non-zero-sized field, but has 2
 --> src/lib.rs:7:1
  |
7 | struct Aligned<T, A, B> {
  | ^^^^^^^^^^^^^^^^^^^^^^^ needs at most one non-zero-sized field, but has 2
8 |     align: ComplexZst<A, B>,
  |     ----------------------- this field is non-zero-sized
9 |     value: T,
  |     -------- this field is non-zero-sized

For more information about this error, try `rustc --explain E0690`.

Is it worth trying to fix this? Should there be something like ty.is_zst(tcx, param_env)? I am not really experienced with rustc internals.

@lukas-code
Copy link
Contributor Author

I found a kind of related thing in #98104.
I think it should be possible to resolve #98064, #98104 and #98071 (comment) by editing SizeSkeleton to check for zero-sized arrays and then use it for the repr(transparent) check here.

@apiraino
Copy link
Contributor

Based on this comment, I assume that some work can be done here so I'm switching to waiting on author :) Feel free to request a review when ready, thanks!

@rustbot author

@rustbot rustbot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jun 30, 2022
@bors
Copy link
Contributor

bors commented Jul 6, 2022

☔ The latest upstream changes (presumably #98206) made this pull request unmergeable. Please resolve the merge conflicts.

@JohnCSimon
Copy link
Member

@lukas-code
ping from triage - can you post your status on this PR? Thanks
FYI: when a PR is ready for review, send a message containing
@rustbot ready to switch to S-waiting-on-review so the PR is in the reviewer's backlog.

@JohnCSimon
Copy link
Member

@lukas-code
Ping from triage: I'm closing this due to inactivity, Please reopen when you are ready to continue with this.
Note: if you do please open the PR BEFORE you push to it, else you won't be able to reopen - this is a quirk of github.
Thanks for your contribution.

@rustbot label: +S-inactive

@JohnCSimon JohnCSimon closed this Oct 2, 2022
@rustbot rustbot added the S-inactive Status: Inactive and waiting on the author. This is often applied to closed PRs. label Oct 2, 2022
@lukas-code lukas-code deleted the repr-transparent-zero-array branch December 16, 2022 21:18
dvdhrm added a commit to dvdhrm/rust that referenced this pull request Jul 21, 2023
Include the computed alignment of the violating field when rejecting
transparent types with non-trivially aligned ZSTs.

ZST member fields in transparent types must have an alignment of 1 (to
ensure it does not raise the layout requirements of the transparent
field). The current error message looks like this:

 LL | struct Foobar(u32, [u32; 0]);
    |                    ^^^^^^^^ has alignment larger than 1

This patch changes the report to include the alignment of the violating
field:

 LL | struct Foobar(u32, [u32; 0]);
    |                    ^^^^^^^^ has alignment of 4, which is larger than 1

In case of unknown alignments, it will yield:

 LL | struct Foobar(u32, [u32; 0]);
    |                    ^^^^^^^^ may have alignment larger than 1

This allows developers to get a better grasp why a specific field is
rejected. Knowing the alignment of the violating field makes it easier
to judge where that alignment-requirement originates, and thus hopefully
provide better hints on how to mitigate the problem.

This idea was proposed in 2022 in rust-lang#98071 as part of a bigger change.
This commit simply extracts this error-message change, to decouple it
from the other diagnostic improvements.
dvdhrm added a commit to dvdhrm/rust that referenced this pull request Jul 21, 2023
Include the computed alignment of the violating field when rejecting
transparent types with non-trivially aligned ZSTs.

ZST member fields in transparent types must have an alignment of 1 (to
ensure it does not raise the layout requirements of the transparent
field). The current error message looks like this:

 LL | struct Foobar(u32, [u32; 0]);
    |                    ^^^^^^^^ has alignment larger than 1

This patch changes the report to include the alignment of the violating
field:

 LL | struct Foobar(u32, [u32; 0]);
    |                    ^^^^^^^^ has alignment of 4, which is larger than 1

In case of unknown alignments, it will yield:

 LL | struct Foobar<T>(u32, [T; 0]);
    |                       ^^^^^^ may have alignment larger than 1

This allows developers to get a better grasp why a specific field is
rejected. Knowing the alignment of the violating field makes it easier
to judge where that alignment-requirement originates, and thus hopefully
provide better hints on how to mitigate the problem.

This idea was proposed in 2022 in rust-lang#98071 as part of a bigger change.
This commit simply extracts this error-message change, to decouple it
from the other diagnostic improvements.
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this pull request Jul 21, 2023
error/E0691: include alignment in error message

Include the computed alignment of the violating field when rejecting transparent types with non-trivially aligned ZSTs.

ZST member fields in transparent types must have an alignment of 1 (to ensure it does not raise the layout requirements of the transparent field). The current error message looks like this:

```text
 LL | struct Foobar(u32, [u32; 0]);
    |                    ^^^^^^^^ has alignment larger than 1
```

This patch changes the report to include the alignment of the violating field:

```text
 LL | struct Foobar(u32, [u32; 0]);
    |                    ^^^^^^^^ has alignment of 4, which is larger than 1
```

In case of unknown alignments, it will yield:

```text
 LL | struct Foobar(u32, [u32; 0]);
    |                    ^^^^^^^^ may have alignment larger than 1
```

This allows developers to get a better grasp why a specific field is rejected. Knowing the alignment of the violating field makes it easier to judge where that alignment-requirement originates, and thus hopefully provide better hints on how to mitigate the problem.

This idea was proposed in 2022 in rust-lang#98071 as part of a bigger change. This commit simply extracts this error-message change, to decouple it from the other diagnostic improvements.

(Originally proposed by `@compiler-errors` in rust-lang#98071)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-inactive Status: Inactive and waiting on the author. This is often applied to closed PRs. S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Wrong diagnostic for zero-sized array in transparent struct
9 participants