A deprecated module containing tests emits an incredibly confusing deprecation warning that is impossible to silence

72bc799
Opened by Sage Griffin at 2025-03-27 14:07:56

This code demonstrates the issue in question:

#[deprecated(since = "0.1.0")]
mod foo {
    #[test]
    fn stuff() {}
}

Attempting to run cargo test on this will give an incredibly opaque error message: use of deprecated item 'foo::__test_reexports'. I had to resort to grepping rustc's codebase to figure out where this was coming from.

Additionally, there is no way to silence this error, other than allowing use of deprecated items for the entire crate. Attempting to put #[allow(deprecated)] either on the test itself, or on the deprecated module has no effect.

  1. We've gotten a slightly less confusing error message, but quick reproduce:

    If you've gotten a module structure of humpty::dumpty::tests, with things like the following

    // humpty.rs
    
    #[deprecated]
    pub mod dumpty;
    
    // dumpty.rs
    
    const DATA: &str = "Oh hello there!";
    
    #[cfg(test)]
    mod tests {
    	use super::DATA;
    
        #[test]
        fn testing() {
            DATA.as_str();
        }
    }
    

    No matter if the allow(deprecated) is put on the use, the mod tests, or the fn testing, the warning message will appear on the usage inside the #[test] item, something like so;

    warning: use of deprecated constant `humpty::dumpty::DATA`
        |
    XXX | /     fn testing() {
    XXX | |         DATA.as_str();
    XXX | |     }
        | |_____^
        |
        = note: `#[warn(deprecated)]` on by default
    

    Interestingly, no warning messages appear on the use of use super::DATA and the likes, even though these appear when the tests are moved outside of the deprecated module's tree.

    Jonathan de Jong at 2023-05-25 08:26:52

  2. Just ran into this myself. Seems to still be a problem in Rust 1.77.

    This seems to be a problem even without constants like DATA. Minimal reproducer at this Playground. As demonstrated there, there doesn't seem to be any placement of #[allow(deprecated)] that silences the warning

    Craig Disselkoen at 2024-05-09 15:06:44

  3. Hit this bug with code similar to this:

    pub mod inner {
        #![deprecated]
        #![allow(deprecated)]
    
        pub struct Deprecated;
    
        #[test]
        fn test() {
            let _ = Deprecated;
        }
    }
    

    I think you hit this bug the instant you try to deprecate a module that contains any tests at all, which I imagine is pretty frequent with libraries?

    The only workaround is to put #![allow(deprecated)] on the crate root, which is obviously not ideal.

    Sludge at 2025-03-27 14:07:56