Repository: rust-lang/rust-clippy (Rust)

Issue:
`alloc-instead-of-core` there is no ` core::Layout `


Using the following flags

`--force-warn clippy::alloc-instead-of-core`

this code:

```rust
use core::sync::atomic::AtomicBool;
use core::sync::atomic::Ordering;
use std::alloc;

static FLAG: AtomicBool = AtomicBool::new(false);

fn protector_data_race(v: &u8) {
    println!("{v}");
    FLAG.store(true, Ordering::Release);
    // Implicit read from protector not detected as a data race(?), but uncommenting this will be
    // detected:
    //println!("{v}");
}

fn main() {
    let layout = alloc::Layout::new::<u8>();
    let ptr = unsafe { alloc::alloc(layout) };
    assert!(!ptr.is_null());
    unsafe { *ptr = 8 };

    struct SendPtr(*mut u8);
    unsafe impl Send for SendPtr {}
    let send_ptr = SendPtr(ptr);

    std::thread::spawn(|| {
        let send_ptr = send_ptr;
        let r = unsafe { &*send_ptr.0 };
        protector_data_race(r);
    });

    loop {
        if FLAG.load(Ordering::Acquire) {
            // There is an actual race since we need to delay here to prevent the dealloc from
            // running while the protector still exists (generating a different kind of error).
            //
            // But we want to preserve the race to test the race detector... so this just loops,
            // perhaps there is a better and less fragile way to do this.
            for _ in 0..100 {}
            unsafe { alloc::dealloc(ptr.cast(), layout) };
            break;
        }
    }
}
```

caused the following diagnostics:

```
    Checking _snippet_0 v0.1.0 (/tmp/icemaker_global_tempdir.W9mV5T7suTWy/icemaker_clippyfix_tempdir.0KPPgB6AQPhi/_snippet_0)
warning: used import from `alloc` instead of `core`
  --> src/main.rs:16:18
   |
16 |     let layout = alloc::Layout::new::<u8>();
   |                  ^^^^^ help: consider importing the item from `core`: `core`
   |
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#alloc_instead_of_core
   = note: requested on the command line with `--force-warn clippy::alloc-instead-of-core`

warning: `_snippet_0` (bin "_snippet_0") generated 1 warning (run `cargo clippy --fix --bin "_snippet_0"` to apply 1 suggestion)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.22s

```

However after applying these diagnostics, the resulting code:

```rust
use core::sync::atomic::AtomicBool;
use core::sync::atomic::Ordering;
use std::alloc;

static FLAG: AtomicBool = AtomicBool::new(false);

fn protector_data_race(v: &u8) {
    println!("{v}");
    FLAG.store(true, Ordering::Release);
    // Implicit read from protector not detected as a data race(?), but uncommenting this will be
    // detected:
    //println!("{v}");
}

fn main() {
    let layout = core::Layout::new::<u8>();
    let ptr = unsafe { alloc::alloc(layout) };
    assert!(!ptr.is_null());
    unsafe { *ptr = 8 };

    struct SendPtr(*mut u8);
    unsafe impl Send for SendPtr {}
    let send_ptr = SendPtr(ptr);

    std::thread::spawn(|| {
        let send_ptr = send_ptr;
        let r = unsafe { &*send_ptr.0 };
        protector_data_race(r);
    });

    loop {
        if FLAG.load(Ordering::Acquire) {
            // There is an actual race since we need to delay here to prevent the dealloc from
            // running while the protector still exists (generating a different kind of error).
            //
            // But we want to preserve the race to test the race detector... so this just loops,
            // perhaps there is a better and less fragile way to do this.
            for _ in 0..100 {}
            unsafe { alloc::dealloc(ptr.cast(), layout) };
            break;
        }
    }
}
```
no longer compiled:

```
    Checking _snippet_0 v0.1.0 (/tmp/icemaker_global_tempdir.W9mV5T7suTWy/icemaker_clippyfix_tempdir.0KPPgB6AQPhi/_snippet_0)
warning: error applying suggestions to `src/main.rs`

The full error message was:

> cannot replace slice of data that was already replaced

This likely indicates a bug in either rustc or cargo itself,
and we would appreciate a bug report! You're likely to see
a number of compiler warnings after this message which cargo
attempted to fix but failed. If you could open an issue at
https://github.com/rust-lang/rust-clippy/issues
quoting the full output of this command we'd be very appreciative!
Note that you may be able to make some more progress in the near-term
fixing code with the `--broken-code` flag

warning: failed to automatically apply fixes suggested by rustc to crate `_snippet_0`

after fixes were automatically applied the compiler reported errors within these files:

  * src/main.rs

This likely indicates a bug in either rustc or cargo itself,
and we would appreciate a bug report! You're likely to see
a number of compiler warnings after this message which cargo
attempted to fix but failed. If you could open an issue at
https://github.com/rust-lang/rust-clippy/issues
quoting the full output of this command we'd be very appreciative!
Note that you may be able to make some more progress in the near-term
fixing code with the `--broken-code` flag

The following errors were reported:
error[E0433]: failed to resolve: could not find `Layout` in `core`
  --> src/main.rs:16:24
   |
16 |     let layout = core::Layout::new::<u8>();
   |                        ^^^^^^ could not find `Layout` in `core`
   |
help: consider importing one of these structs
   |
 1 + use crate::alloc::Layout;
   |
 1 + use std::alloc::Layout;
   |
help: if you import `Layout`, refer to it directly
   |
16 -     let layout = core::Layout::new::<u8>();
16 +     let layout = Layout::new::<u8>();
   |

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0433`.
Original diagnostics will follow.

error[E0433]: failed to resolve: could not find `Layout` in `core`
  --> src/main.rs:16:24
   |
16 |     let layout = core::Layout::new::<u8>();
   |                        ^^^^^^ could not find `Layout` in `core`
   |
help: consider importing one of these structs
   |
 1 + use crate::alloc::Layout;
   |
 1 + use std::alloc::Layout;
   |
help: if you import `Layout`, refer to it directly
   |
16 -     let layout = core::Layout::new::<u8>();
16 +     let layout = Layout::new::<u8>();
   |

For more information about this error, try `rustc --explain E0433`.
error: could not compile `_snippet_0` (bin "_snippet_0" test) due to 1 previous error
warning: build failed, waiting for other jobs to finish...
warning: error applying suggestions to `src/main.rs`

The full error message was:

> cannot replace slice of data that was already replaced

This likely indicates a bug in either rustc or cargo itself,
and we would appreciate a bug report! You're likely to see
a number of compiler warnings after this message which cargo
attempted to fix but failed. If you could open an issue at
https://github.com/rust-lang/rust-clippy/issues
quoting the full output of this command we'd be very appreciative!
Note that you may be able to make some more progress in the near-term
fixing code with the `--broken-code` flag

warning: failed to automatically apply fixes suggested by rustc to crate `_snippet_0`

after fixes were automatically applied the compiler reported errors within these files:

  * src/main.rs

This likely indicates a bug in either rustc or cargo itself,
and we would appreciate a bug report! You're likely to see
a number of compiler warnings after this message which cargo
attempted to fix but failed. If you could open an issue at
https://github.com/rust-lang/rust-clippy/issues
quoting the full output of this command we'd be very appreciative!
Note that you may be able to make some more progress in the near-term
fixing code with the `--broken-code` flag

The following errors were reported:
error[E0433]: failed to resolve: could not find `Layout` in `core`
  --> src/main.rs:16:24
   |
16 |     let layout = core::Layout::new::<u8>();
   |                        ^^^^^^ could not find `Layout` in `core`
   |
help: consider importing one of these structs
   |
 1 + use crate::alloc::Layout;
   |
 1 + use std::alloc::Layout;
   |
help: if you import `Layout`, refer to it directly
   |
16 -     let layout = core::Layout::new::<u8>();
16 +     let layout = Layout::new::<u8>();
   |

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0433`.
Original diagnostics will follow.

error: could not compile `_snippet_0` (bin "_snippet_0") due to 1 previous error

```

Version:
```
rustc 1.91.0-nightly (91ee6a405 2025-08-26)
binary: rustc
commit-hash: 91ee6a4057ce4bf1ab6d2f932cae497488d67c81
commit-date: 2025-08-26
host: x86_64-unknown-linux-gnu
release: 1.91.0-nightly
LLVM version: 21.1.0

```




Discussion:

Patch:
diff --git a/clippy_lints/src/std_instead_of_core.rs b/clippy_lints/src/std_instead_of_core.rs
index e9534bc63a69..8c4a50041e67 100644
--- a/clippy_lints/src/std_instead_of_core.rs
+++ b/clippy_lints/src/std_instead_of_core.rs
@@ -126,6 +126,8 @@ impl<'tcx> LateLintPass<'tcx> for StdReexports {
             && !is_from_proc_macro(cx, &first_segment.ident)
             && !matches!(def_kind, DefKind::Macro(_))
             && let Some(last_segment) = path.segments.last()
+            && let Res::Def(DefKind::Mod, crate_def_id) = first_segment.res
+            && crate_def_id.is_crate_root()
         {
             let (lint, used_mod, replace_with) = match first_segment.ident.name {
                 sym::std => match cx.tcx.crate_name(def_id.krate) {


Test patch:
diff --git a/tests/ui/std_instead_of_core.fixed b/tests/ui/std_instead_of_core.fixed
index 603ab0accb0b..c27cec558242 100644
--- a/tests/ui/std_instead_of_core.fixed
+++ b/tests/ui/std_instead_of_core.fixed
@@ -89,3 +89,10 @@ fn msrv_1_76(_: std::net::IpAddr) {}
 #[clippy::msrv = "1.77"]
 fn msrv_1_77(_: core::net::IpAddr) {}
 //~^ std_instead_of_core
+
+#[warn(clippy::alloc_instead_of_core)]
+fn issue15579() {
+    use std::alloc;
+
+    let layout = alloc::Layout::new::<u8>();
+}
diff --git a/tests/ui/std_instead_of_core.rs b/tests/ui/std_instead_of_core.rs
index b6d4abad9f8f..7d53f7fc3072 100644
--- a/tests/ui/std_instead_of_core.rs
+++ b/tests/ui/std_instead_of_core.rs
@@ -89,3 +89,10 @@ fn msrv_1_76(_: std::net::IpAddr) {}
 #[clippy::msrv = "1.77"]
 fn msrv_1_77(_: std::net::IpAddr) {}
 //~^ std_instead_of_core
+
+#[warn(clippy::alloc_instead_of_core)]
+fn issue15579() {
+    use std::alloc;
+
+    let layout = alloc::Layout::new::<u8>();
+}