Skip to content

A lint for taking a mutable reference to a constant #829

Closed

Description

@petrochenkov

i.e. rust-lang/rfcs#885

This is currently legal and prints 0 1 because a and ARR[0] are actually references to temporaries and not to C and ARR, but this is confusing as hell.

const C: u8 = 0;
const ARR: [u8; 3] = [1, 2, 3];

fn main() {
    let a = &mut C;
    *a = 1;
    ARR[0] = 4;
    println!("{} {}", C, ARR[0]);
}

Activity

  1. mcarton commented on Apr 2, 2016

    @mcarton
    Contributor

    😕 Rust

  2. added
    good first issueThese issues are a good way to get started with Clippy
    A-lintArea: New lints
    E-mediumCall for participation: Medium difficulty level problem and requires some initial experience.
    and removed
    good first issueThese issues are a good way to get started with Clippy
    on Apr 2, 2016
  3. oli-obk commented on Apr 3, 2016

    @oli-obk
    Contributor

    haha great catch!

  4. oli-obk commented on Apr 3, 2016

    @oli-obk
    Contributor

    *&mut 1 = 5; is legal, too xD

    I think the let a = &mut C case should not be caught by linting against taking a mutable reference to a constant, but by improving the unused_assignments lint. This would also catch ARR[0] = 4. But I fear we need to do this analysis in MIR.

    As an intermediate step, simply linting against having a constant on the lhs of an assignment op or taking a mutable reference to it would be good.

  5. petrochenkov commented on Apr 3, 2016

    @petrochenkov
    ContributorAuthor

    @oli-obk
    With &mut 1 or &mut (a + b) it's not so bad because it's fairly evident, that the reference is bound to a temporary, in case of &mut C or ARR[0] it looks completely like taking a reference to a lvalue.

  6. tgnottingham commented on Jul 19, 2020

    @tgnottingham

    This is probably obvious, but just want to point out that this applies to calling methods that take &mut self. Silly example:

    const VEC: Vec<i32> = Vec::new();                                                                                                                                                                                                                                                           
                                                                                                                                                                                                                                                                                                
    fn main() {                                                                                                                                                                                                                                                                                 
        VEC.push(1);                                                                                                                                                                                                                                                                            
    }
    

    Also, I think that this would be more appropriate as a compiler warning or error, FWIW.

  7. camsteffen commented on Dec 16, 2020

    @camsteffen
    Contributor

    This is resolved by the new rustc lint 👆

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-lintArea: New lintsE-mediumCall for participation: Medium difficulty level problem and requires some initial experience.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions