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

New lint: mutating implicit copy of const #4882

Open
ExoticMatter opened this issue Dec 5, 2019 · 0 comments
Open

New lint: mutating implicit copy of const #4882

ExoticMatter opened this issue Dec 5, 2019 · 0 comments
Labels
A-lint Area: New lints E-medium Call for participation: Medium difficulty level problem and requires some initial experience. L-correctness Lint: Belongs in the correctness lint group

Comments

@ExoticMatter
Copy link

Constants are instantiated every time they are used, even for non-Copy types. This results in behavior that may seem unintuitive at a first glance. The following code looks like it shouldn't compile at all:

#[derive(Debug)]
struct Foo {
    v: Vec<usize>,
}

const FOO: Foo = Foo { v: Vec::new() };

fn main() {
    for i in 0..32 {
        FOO.v.push(i); // attempting to modify a constant
    }
    println!("{:?}", FOO);
}

However, this code is actually valid. Of course, constants can't actually be modified. What really happens is that every usage of FOO creates a new temporary-like value that can be freely mutated even though FOO is const.

Suggest creating a local variable from the constant and mutating the variable instead, or using a static with interior mutability if a global state is truly necessary.


As a side note, the following code does work. Is it bad style?

fn main() {
    let foo = &mut FOO; // actually borrows an implicit local variable, not FOO
    for i in 0..32 {
        foo.v.push(i);
    }
    println!("{:?}", foo); // Foo: { v: [0, 1, 2, 3, ...] }
    println!("{:?}", FOO); // Foo: { v: [] }
}
@flip1995 flip1995 added L-correctness Lint: Belongs in the correctness lint group E-medium Call for participation: Medium difficulty level problem and requires some initial experience. A-lint Area: New lints labels Dec 5, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-lint Area: New lints E-medium Call for participation: Medium difficulty level problem and requires some initial experience. L-correctness Lint: Belongs in the correctness lint group
Projects
None yet
Development

No branches or pull requests

2 participants