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

Tuple-struct constructor visibility leads to inconsistency in pattern matching #76494

Open
Aaron1011 opened this issue Sep 8, 2020 · 1 comment
Labels
A-visibility Area: Visibility / privacy. C-bug Category: This is a bug. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@Aaron1011
Copy link
Member

Aaron1011 commented Sep 8, 2020

The following code:

mod foo {
    pub struct NamedStruct {
        field: u8
    }
    pub struct TupleStruct(u8);
}

use foo::*;

fn test_it(named: NamedStruct, tuple: TupleStruct) {
    if let NamedStruct { .. } = named {}
    if let TupleStruct(..) = tuple {}
}

produces the following error:

error[E0532]: expected tuple struct or tuple variant, found struct `TupleStruct`
  --> src/lib.rs:12:12
   |
12 |     if let TupleStruct(..) = tuple {}
   |            ^^^^^^^^^^^ constructor is not visible here due to private fields

This is caused by the fact that tuple structs have their 'constructor' visibility set to their most restrictive field visibility:

for field in vdata.fields() {
// NOTE: The field may be an expansion placeholder, but expansion sets
// correct visibilities for unnamed field placeholders specifically, so the
// constructor visibility should still be determined correctly.
if let Ok(field_vis) = self.resolve_visibility_speculative(&field.vis, true)
{
if ctor_vis.is_at_least(field_vis, &*self.r) {
ctor_vis = field_vis;
}
}
}

This behavior seems quite inconsistent. As a user, I would expect that tuple structs and named structs are just two different ways of naming the fields of a struct, and behave identically w.r.t privacy.

Is there a reason for this difference in behavior, or is this just a historical quirk of the resolver?

Thanks to @guswynn for bringing this to my attention.

@Aaron1011 Aaron1011 added A-visibility Area: Visibility / privacy. C-bug Category: This is a bug. labels Sep 8, 2020
@Aaron1011
Copy link
Member Author

Aaron1011 commented Sep 8, 2020

On second thought, I suspect this is due to the fact that tuple structs can be used as function pointers:

let fn_ptr: fn(u8) -> TupleStruct = TupleStruct;

If this is the case, then we should probably mention this in relevant error messages.

@Enselic Enselic added the T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. label Dec 16, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-visibility Area: Visibility / privacy. C-bug Category: This is a bug. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

2 participants