Skip to content

compiler suggests "&mut mut" #69789

Closed

Description

@matthiaskrgr

I was messing around with this function

    fn build_sidebar_items(&self, m: &clean::Module) -> BTreeMap<String, Vec<NameDoc>> {
        // BTreeMap instead of HashMap to get a sorted output
        let mut map: BTreeMap<_, Vec<_>> = BTreeMap::new();
        for item in &m.items {
            if item.is_stripped() {
                continue;
            }

            let short = item.type_();
            let myname = match item.name {
                None => continue,
                Some(ref s) => s.to_string(),
            };
            let short = short.to_string();
            map.entry(short)
                .or_default()
                .push((myname, Some(plain_summary_line(item.doc_value()))));
        }

        if self.shared.sort_modules_alphabetically {
            for (_, items) in &mut map {
                items.sort();
            }
        }
        map
    }

After I changed the last block to

        if self.shared.sort_modules_alphabetically {
            for items in &mut map.values() {
                items.sort();
            }
        }
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -1542,7 +1542,7 @@ impl Context {
         }
 
         if self.shared.sort_modules_alphabetically {
-            for (_, items) in &mut map {
+            for items in &mut map.values() {
                 items.sort();
             }
         }

The compiler gave this interesting but wrong suggestion: &mut mut map.values()

error[E0596]: cannot borrow `*items` as mutable, as it is behind a `&` reference
    --> src/librustdoc/html/render.rs:1546:17
     |
1545 |             for items in &mut map.values() {
     |                          ----------------- help: consider changing this to be a mutable reference: `&mut mut map.values()`
1546 |                 items.sort();
     |                 ^^^^^ `items` is a `&` reference, so the data it refers to cannot be borrowed as mutable

error: aborting due to previous error

For more information about this error, try `rustc --explain E0596`.

which does not compiler obviously 😄

The correct solution would be to use &mut map.values_mut():

    if self.shared.sort_modules_alphabetically {
            for items in &mut map.values_mut() {
                items.sort();
            }
        }
```

Activity

  1. added
    A-diagnosticsArea: Messages for errors, warnings, and lints
    A-suggestion-diagnosticsArea: Suggestions generated by the compiler applied by `cargo fix`
    D-invalid-suggestionDiagnostics: A structured suggestion resulting in incorrect code.
    T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.
    on Mar 6, 2020
  2. CAD97 commented on Mar 8, 2020

    @CAD97
    Contributor

    Just a minor note: typically these iterators are iterated by-value (e.g. for items in map.values()), so this explains why the diagnostics issue was missed. This gives a less bad error message:

    error[E0596]: cannot borrow `*items` as mutable, as it is behind a `&` reference
      --> src/main.rs:10:9
       |
    9  |     for items in map.values() {
       |         ----- help: consider changing this to be a mutable reference: `&mut std::vec::Vec<u8>`
    10 |         items.sort();
       |         ^^^^^ `items` is a `&` reference, so the data it refers to cannot be borrowed as mutable
    
  3. added 3 commits that reference this issue on Mar 23, 2020
    a897944
    ac78183
    ab2817b
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-diagnosticsArea: Messages for errors, warnings, and lintsA-suggestion-diagnosticsArea: Suggestions generated by the compiler applied by `cargo fix`C-bugCategory: This is a bug.D-invalid-suggestionDiagnostics: A structured suggestion resulting in incorrect code.T-compilerRelevant to the compiler 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