Skip to content

Tracking issue for legacy_constructor_visibility compatibility lint #39207

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

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions