Open ilyvion opened 2 years ago
I think this is similar to #90907. This isn't exactly related to #[test]
, other than the fact that libtest gets linked in and it depends on std/alloc.
For example:
// foo.rs
#![no_std]
pub fn foo() {
bar::x();
let b = b"hello";
let _v = b.to_vec();
}
// bar.rs
#![no_std]
extern crate alloc;
pub fn x() {}
rustc bar.rs --crate-type=rlib
# This succeeds
rustc foo.rs --crate-type=rlib --extern bar=libbar.rlib
I don't know if anyone else agrees, but this feels like some kind of boundary violation to me. If nothing else it cost me a bunch of time because I knew I wasn't supposed to have .to_vec()
available to me, and yet it just kept on working. 😅
I'm seeing more strange behavior related to this odd alloc
"leak." I had this problem:
error: cannot find macro `format` in this scope
--> src\range_type.rs:246:14
|
246 | &format!("{}", invalid_deserialized_error.unwrap_err()),
(which makes sense, we're in #![no_std]
right?) So I changed it to alloc::format!
, but still:
error[E0433]: failed to resolve: use of undeclared crate or module `alloc`
--> src\range_type.rs:246:14
|
246 | &alloc::format!("{}", invalid_deserialized_error.unwrap_err()),
| ^^^^^ use of undeclared crate or module `alloc`
Right! I forgot to add extern crate alloc;
! But uh...:
warning: unused extern crate
--> src\range_type.rs:161:5
|
160 | / #[warn(unused)]
161 | | extern crate alloc;
| | ^^^^^^^^^^^^^^^^^^-
| |_______________________|
| help: remove it
It finally compiles with extern crate alloc;
there, though. (I have #[warn(unused)]
there because my crate-wide setting is #![deny(unused)]
; although I'll be making the warn
into allow
after making this report, because it clearly isn't truly unused.)
The compiler seems to have a hard time deciding whether or not alloc
really is available here. It yells at me when I have it there and it yells at me when I don't have it there.
I was messing around in a test in a
#[no_std]
crate and discovered that this code:(playground link)
compiles, which really surprised me, because
[T]::to_vec()
is defined in thealloc
crate, and as you can see, I don't have anyextern alloc;
directive. It's even more surprising in that it only works in functions marked either#[test]
or#[cfg(test)]
. If you put it on a regular function (just remove#[test]
from above), you get the expected error:I expected this error to also happen in
#[cfg(test)]
, but it doesn't. This is unexpected and surprising.What makes it even more surprising is that
alloc
isn't actually in scope, because if you changelet _v
tolet _v: alloc::Vec<_>
in the code above, you'll be told as much.