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

Guide new users to add use super::*; to mod test. #10559

Closed
sunfishcode opened this issue Apr 12, 2022 · 2 comments · Fixed by #10706
Closed

Guide new users to add use super::*; to mod test. #10559

sunfishcode opened this issue Apr 12, 2022 · 2 comments · Fixed by #10706
Labels
C-feature-request Category: proposal for a feature. Before PR, ping rust-lang/cargo if this is not `Feature accepted` Command-init Command-new

Comments

@sunfishcode
Copy link
Member

Problem

cargo init --lib produces a src/lib.rs file contaning this:

#[cfg(test)]
mod tests {
    #[test]
    fn it_works() {
        let result = 2 + 2;
        assert_eq!(result, 4);
    }
}

When I was first learning Rust, I'd start with this code, and add a new function, and a unit test, like this:

pub fn add_numbers(a: i32, b: i32) -> i32 {
    a + b
}

#[cfg(test)]
mod tests {
    #[test] 
    fn it_works() {
        let result = add_numbers(2, 2);
        assert_eq!(result, 4);
    }
}

But, this doesn't compile:

error[E0425]: cannot find function `add_numbers` in this scope
 --> src/lib.rs:9:22
  |
9 |         let result = add_numbers(2, 2);
  |                      ^^^^^^^^^^^ not found in this scope
  |
help: consider importing this function
  |
8 |     use crate::add_numbers;
  |

So first, this in itself is a mild papercut—the seemingly obvious thing didn't work. But next, if I would follow rustc's suggestions, or let IDEs fix this for me, I'd eventually end up with a big pile of uses, as I write more code and add tests for it. This would add more papercuts: clutter, and a focal point for merge conflicts.

It would almost always be better for me to use use super::* inside the mod tests, because once that's added, it avoids these papercuts from then on. So the feature request is: can we do more to guide users to use super::*;?

The relevant documentation does recommend using use super::*;, but when I was learning Rust, I didn't read that section because I knew what an "assert" was from other languages and didn't think I needed to read that whole section in the docs, so I missed the use super::*; advice within.

As a historical note, these papercuts contributed to my forming a habit of writing unit tests without mod tests, which is what prompted the discussion which led to #10531.

Proposed Solution

Adding use super::*; to the current code would get an unused-import warning. So one option would be to add it, but commented out, like this:

#[cfg(test)]
mod tests {
    // Uncomment this to use items from the containing module.
    //use super::*;

    #[test]
    fn it_works() {
        let result = 2 + 2;
        assert_eq!(result, 4);
    }
}

Notes

No response

@epage
Copy link
Contributor

epage commented May 27, 2022

Copying over from #10706 (comment)

@Muscraft

Thinking about this some more, I think adding something for users to uncomment only solves a symptom of the issue and not the issue itself. I think the main issue is the error message from rustc (which appears to be generated in this function). It might be a better idea (and a harder change), to update the error message to include use super::*;.

Something like:

error[E0425]: cannot find function `add_numbers` in this scope
 --> src/lib.rs:9:22
   |
9  |         let result = add_numbers(2, 2);
   |                      ^^^^^^^^^^^ not found in this scope
   |
help: consider importing one of these items
   |
LL | use super::*;
   |
LL | use crate::add_numbers;
   |

I mocked this from here

I think one of the maintainers may have more insight than I do on the route to go about this

@epage
Copy link
Contributor

epage commented May 27, 2022

Having rustc or rust-analyzer pattern match on test mods and suggest use super::*; is intriguing but I have no idea if the compiler folks tend to take on that kind of policy.

That still leaves the roadbump of hitting the compiler error.

I'm a bit concerned with adding a commented out use as it expands us from 2 to now 3 styles of new-project generation
We seem to have a weird mixture of three strategies

  • Leave out example code (no function)
  • Comment out example code (use)
  • Include example code (the test)

I lean towards either living with the warning:

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn it_works() {
        let result = 2 + 2;
        assert_eq!(result, 4);
    }
}

or going further on our example code:

fn add(left: usize, right: usize) -> usize {
    left + right
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn it_works() {
        let result = add(2, 2);
        assert_eq!(result, 4);
    }
}

@bors bors closed this as completed in ca4edab May 29, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-feature-request Category: proposal for a feature. Before PR, ping rust-lang/cargo if this is not `Feature accepted` Command-init Command-new
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants