Skip to content

Tracking issue for legacy_constructor_visibility compatibility lint #39207

Closed
@petrochenkov

Description

@petrochenkov

What is this lint about

#38932 introduces new rules for privacy of tuple struct constructors. Constructor is a function automatically created by a tuple struct having the same name as the struct itself.

struct S(u8); // defines `struct S { ... }` and `fn S(u8) -> S` 

See RFC 1506 for more details.

With these new rules constructor function of a public struct S(....) is defined as private if at least one of the fields is private.
More precisely, visibility(constructor_fn) = min(visibility(struct), visibility(field_1), ..., visibility(field_N)) (this definition takes RFC 1422 into account).

This change is done to make a struct with private fields being a tuple struct an implementation detail. So libraries can freely change it into non-tuple struct and back, and nothing breaks.
This change is mostly backward compatible due to some ad-hoc privacy checks existing previously (e.g. error[E0450]: cannot invoke tuple struct constructor with private fields), however there's one pattern that is broken by it:

mod m {
    // Tuple struct with a private field.
    // Type S is pub(pub).
    // The field S::0 is pub(m).
    // Constructor S is min(pub(pub), pub(m)) -> pub(m).
    pub struct S(u8);
    
    fn f() {
        // Try to use S from the root module in value namespace.
        // No success, ::S exists only in type namespace.
        // How to fix: use S from this module instead of ::S from the root module.
        ::S;
    }
}

// This imports S only in type namespace, value S is too private.
// This is expected filtering behavior of imports described in RFC 1560.
use m::S;

fn main() {}

legacy_constructor_visibility lint tries to detect this patterns and make name resolution succeed with a warning to keep backward compatibility. However, this detection is pretty hacky and not entirely precise, so it will need to go away eventually.

How to fix this warning/error

Use the constructor from its original location X and not through reexports in modules outer to X.

Current status

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-lintsArea: Lints (warnings about flaws in source code) such as unused_mut.B-unstableBlocker: Implemented in the nightly compiler and unstable.C-future-incompatibilityCategory: Future-incompatibility lintsT-langRelevant to the language team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions