Skip to content

fix [std_instead_of_core]: false positive for multi-imports#17252

Open
bushrat011899 wants to merge 1 commit into
rust-lang:masterfrom
bushrat011899:std_instead_of_core_multi_imports
Open

fix [std_instead_of_core]: false positive for multi-imports#17252
bushrat011899 wants to merge 1 commit into
rust-lang:masterfrom
bushrat011899:std_instead_of_core_multi_imports

Conversation

@bushrat011899

@bushrat011899 bushrat011899 commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

Objective

Solution

The current version of this lint can improperly trigger a suggestion for certain complex use statements. This PR attempts to resolve this by tracking ItemKind::Use items, which allows determining when paths are used within the context of a multi-import (UseKind::ListStem). Lints can then be appropriately grouped before determining if a suggestion is possible.

This PR is the first commit from a re-write branch #17364, which acts on this suggestion and attempts to resolve many currently open issues for this lint.

One consequence of this PR is that CrateNum is used to determine what crate items are being imported from, instead of the symbol of the first segment in the path. This resolves an unreported issue where doing something like extern crate core as std; would cause std_instead_of_core to emit erroneously. It also caused cases like extern crate std as core; to not emit std_instead_of_core.

Unfortunately, this does lead to an issue for extern crate std as alloc; (which is used e.g. here), since the suggestion will be to replace alloc with alloc. This is fixed in #17364 since it also fixes #15836 & #16695 by checking what name alloc is available under, and demotes the suggestion to a help if it isn't.


Notes


Please write a short comment explaining your change (or "none" for internal only changes)

changelog: [std_instead_of_core], [std_instead_of_alloc], [alloc_instead_of_core]: fix certain false positives for mulit-imports.
changelog: [std_instead_of_core], [std_instead_of_alloc], [alloc_instead_of_core]: lint cases where std or alloc are renamed.

@rustbot rustbot added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties label Jun 15, 2026
@rustbot

rustbot commented Jun 15, 2026

Copy link
Copy Markdown
Collaborator

Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @llogiq (or someone else) some time within the next two weeks.

Please see the contribution instructions for more information. Namely, in order to ensure the minimum review times lag, PR authors and assigned reviewers should ensure that the review label (S-waiting-on-review and S-waiting-on-author) stays updated, invoking these commands when appropriate:

  • @rustbot author: the review is finished, PR author should check the comments and take action accordingly
  • @rustbot review: the author is ready for a review, this PR will be queued again in the reviewer's queue
Why was this reviewer chosen?

The reviewer was selected based on:

  • Owners of files modified in this PR: 8 candidates
  • 8 candidates expanded to 8 candidates
  • Random selection from Jarcho, dswij, llogiq, samueltardieu

@github-actions

github-actions Bot commented Jun 15, 2026

Copy link
Copy Markdown

Lintcheck changes for 6adb667

Lint Added Removed Changed
clippy::alloc_instead_of_core 3 1 1
clippy::std_instead_of_alloc 7 2 15
clippy::std_instead_of_core 11 40 26

This comment will be updated if you push new changes

@bushrat011899 bushrat011899 force-pushed the std_instead_of_core_multi_imports branch 4 times, most recently from db1918a to 5dc77a7 Compare June 15, 2026 14:15
Comment thread tests/ui/std_instead_of_core_unfixable.rs Outdated
@rustbot rustbot added S-waiting-on-author Status: This is awaiting some action from the author. (Use `@rustbot ready` to update this status) and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties labels Jun 15, 2026
@rustbot

rustbot commented Jun 15, 2026

Copy link
Copy Markdown
Collaborator

Reminder, once the PR becomes ready for a review, use @rustbot ready.

@Jarcho

Jarcho commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

r? Jarcho

@rustbot rustbot assigned Jarcho and unassigned llogiq Jun 15, 2026
@bushrat011899 bushrat011899 force-pushed the std_instead_of_core_multi_imports branch 5 times, most recently from 3885b82 to 2eda7d5 Compare June 16, 2026 11:07
@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties and removed S-waiting-on-author Status: This is awaiting some action from the author. (Use `@rustbot ready` to update this status) labels Jun 16, 2026

@bushrat011899 bushrat011899 left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few comments that might be relevant for reviewers!

View changes since this review

Comment thread clippy_lints/src/std_instead_of_core.rs Outdated
Comment thread clippy_lints/src/std_instead_of_core.rs Outdated
@rustbot

This comment has been minimized.

@bushrat011899 bushrat011899 force-pushed the std_instead_of_core_multi_imports branch from 2eda7d5 to 98e1658 Compare June 16, 2026 12:36
@rustbot

This comment has been minimized.

rust-bors Bot pushed a commit to rust-lang/rust that referenced this pull request Jun 17, 2026
…li-obk

Fix(ICE): Remove `unwrap` from `get_module_children`

# Objective

Fix an ICE I ran into while developing rust-lang/rust-clippy#17252 that stems from `rustc_metadata::rmeta::decoder::CrateMetadata::get_module_children` calling `unwrap`. The local value `non_reexports` can be `None` when the passed in `DefIndex` is for a non-module-like item. The documentation for `get_module_children` *implies* that it must only be called with module-like item indices, however it seems to me that it would be appropriate to just return nothing when called on a non-module-like item (if it isn't module-like, it has zero children).

## Solution

- Switched from an `Option::unwrap` to an `if let Some(...)`

---

## Notes

* No AI tooling of any kind was used during the creation of this PR.
* Please see [Zulip](https://rust-lang.zulipchat.com/#narrow/channel/122651-general/topic/.E2.9C.94.20.60rustc.60.20ICE.20from.20.60TyCtxt.3A.3Amodule_children.60/with/603700184) for some discussion.
* Please see this [failed Clippy CI run](https://github.com/rust-lang/rust-clippy/actions/runs/27596428127/job/81587609898#step:5:1) for an example of the ICE caused.
@bushrat011899 bushrat011899 force-pushed the std_instead_of_core_multi_imports branch from 98e1658 to 130da4a Compare June 18, 2026 01:19
@bushrat011899 bushrat011899 force-pushed the std_instead_of_core_multi_imports branch from 130da4a to 28d43c3 Compare June 18, 2026 01:39
rust-bors Bot pushed a commit to rust-lang/rust that referenced this pull request Jun 18, 2026
…etrochenkov,oli-obk

Replace `unwrap` with `expect` in `get_module_children`

# Objective

I ran into an ICE I ran into while developing rust-lang/rust-clippy#17252 that stems from `rustc_metadata::rmeta::decoder::CrateMetadata::get_module_children` calling `unwrap`. The local value `non_reexports` can be `None` when the passed in `DefIndex` is for a non-module-like item. The documentation for `get_module_children` *implies* that it must only be called with module-like item indices, however the use of `unwrap` makes diagnosing the ICE trickier than it has to be. Additionally, this behaviour is not documented on `TyCtxt::module_children`.

## Solution

- Switched from an `Option::unwrap` to a `Option::expect`
- Added panic documentation to `get_module_children`
- Replicated documentation for `TyCtxt::module_children`

---

## Notes

* No AI tooling of any kind was used during the creation of this PR.
* Please see [Zulip](https://rust-lang.zulipchat.com/#narrow/channel/122651-general/topic/.E2.9C.94.20.60rustc.60.20ICE.20from.20.60TyCtxt.3A.3Amodule_children.60/with/603700184) for some discussion.
* Please see this [failed Clippy CI run](https://github.com/rust-lang/rust-clippy/actions/runs/27596428127/job/81587609898#step:5:1) for an example of the ICE caused.
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request Jun 18, 2026
…unwrap, r=petrochenkov,oli-obk

Replace `unwrap` with `expect` in `get_module_children`

# Objective

I ran into an ICE I ran into while developing rust-lang/rust-clippy#17252 that stems from `rustc_metadata::rmeta::decoder::CrateMetadata::get_module_children` calling `unwrap`. The local value `non_reexports` can be `None` when the passed in `DefIndex` is for a non-module-like item. The documentation for `get_module_children` *implies* that it must only be called with module-like item indices, however the use of `unwrap` makes diagnosing the ICE trickier than it has to be. Additionally, this behaviour is not documented on `TyCtxt::module_children`.

## Solution

- Switched from an `Option::unwrap` to a `Option::expect`
- Added panic documentation to `get_module_children`
- Replicated documentation for `TyCtxt::module_children`

---

## Notes

* No AI tooling of any kind was used during the creation of this PR.
* Please see [Zulip](https://rust-lang.zulipchat.com/#narrow/channel/122651-general/topic/.E2.9C.94.20.60rustc.60.20ICE.20from.20.60TyCtxt.3A.3Amodule_children.60/with/603700184) for some discussion.
* Please see this [failed Clippy CI run](https://github.com/rust-lang/rust-clippy/actions/runs/27596428127/job/81587609898#step:5:1) for an example of the ICE caused.
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request Jun 18, 2026
…unwrap, r=petrochenkov,oli-obk

Replace `unwrap` with `expect` in `get_module_children`

# Objective

I ran into an ICE I ran into while developing rust-lang/rust-clippy#17252 that stems from `rustc_metadata::rmeta::decoder::CrateMetadata::get_module_children` calling `unwrap`. The local value `non_reexports` can be `None` when the passed in `DefIndex` is for a non-module-like item. The documentation for `get_module_children` *implies* that it must only be called with module-like item indices, however the use of `unwrap` makes diagnosing the ICE trickier than it has to be. Additionally, this behaviour is not documented on `TyCtxt::module_children`.

## Solution

- Switched from an `Option::unwrap` to a `Option::expect`
- Added panic documentation to `get_module_children`
- Replicated documentation for `TyCtxt::module_children`

---

## Notes

* No AI tooling of any kind was used during the creation of this PR.
* Please see [Zulip](https://rust-lang.zulipchat.com/#narrow/channel/122651-general/topic/.E2.9C.94.20.60rustc.60.20ICE.20from.20.60TyCtxt.3A.3Amodule_children.60/with/603700184) for some discussion.
* Please see this [failed Clippy CI run](https://github.com/rust-lang/rust-clippy/actions/runs/27596428127/job/81587609898#step:5:1) for an example of the ICE caused.
GuillaumeGomez added a commit to GuillaumeGomez/rust that referenced this pull request Jun 18, 2026
…unwrap, r=petrochenkov,oli-obk

Replace `unwrap` with `expect` in `get_module_children`

# Objective

I ran into an ICE I ran into while developing rust-lang/rust-clippy#17252 that stems from `rustc_metadata::rmeta::decoder::CrateMetadata::get_module_children` calling `unwrap`. The local value `non_reexports` can be `None` when the passed in `DefIndex` is for a non-module-like item. The documentation for `get_module_children` *implies* that it must only be called with module-like item indices, however the use of `unwrap` makes diagnosing the ICE trickier than it has to be. Additionally, this behaviour is not documented on `TyCtxt::module_children`.

## Solution

- Switched from an `Option::unwrap` to a `Option::expect`
- Added panic documentation to `get_module_children`
- Replicated documentation for `TyCtxt::module_children`

---

## Notes

* No AI tooling of any kind was used during the creation of this PR.
* Please see [Zulip](https://rust-lang.zulipchat.com/#narrow/channel/122651-general/topic/.E2.9C.94.20.60rustc.60.20ICE.20from.20.60TyCtxt.3A.3Amodule_children.60/with/603700184) for some discussion.
* Please see this [failed Clippy CI run](https://github.com/rust-lang/rust-clippy/actions/runs/27596428127/job/81587609898#step:5:1) for an example of the ICE caused.
rust-timer added a commit to rust-lang/rust that referenced this pull request Jun 18, 2026
Rollup merge of #158002 - bushrat011899:get_module_children_unwrap, r=petrochenkov,oli-obk

Replace `unwrap` with `expect` in `get_module_children`

# Objective

I ran into an ICE I ran into while developing rust-lang/rust-clippy#17252 that stems from `rustc_metadata::rmeta::decoder::CrateMetadata::get_module_children` calling `unwrap`. The local value `non_reexports` can be `None` when the passed in `DefIndex` is for a non-module-like item. The documentation for `get_module_children` *implies* that it must only be called with module-like item indices, however the use of `unwrap` makes diagnosing the ICE trickier than it has to be. Additionally, this behaviour is not documented on `TyCtxt::module_children`.

## Solution

- Switched from an `Option::unwrap` to a `Option::expect`
- Added panic documentation to `get_module_children`
- Replicated documentation for `TyCtxt::module_children`

---

## Notes

* No AI tooling of any kind was used during the creation of this PR.
* Please see [Zulip](https://rust-lang.zulipchat.com/#narrow/channel/122651-general/topic/.E2.9C.94.20.60rustc.60.20ICE.20from.20.60TyCtxt.3A.3Amodule_children.60/with/603700184) for some discussion.
* Please see this [failed Clippy CI run](https://github.com/rust-lang/rust-clippy/actions/runs/27596428127/job/81587609898#step:5:1) for an example of the ICE caused.
@bushrat011899 bushrat011899 force-pushed the std_instead_of_core_multi_imports branch from 28d43c3 to 5e134b4 Compare June 23, 2026 01:13
Comment thread clippy_lints/src/std_instead_of_core.rs Outdated
Comment thread clippy_lints/src/std_instead_of_core.rs Outdated
@Jarcho

Jarcho commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

This lint really needs to be re-written to work on check_item for use paths instead. Doing so will let you use UseKind::ListStem to know when braces were used and rebuild the use tree which you need to handle more complex cases.

You;ll want a setup like:

fn check_item(&mut self, cx: &LateContext<'tcx>, i: &'tcx Item<'_>) {
  if let ItemKind::Use(p, kind) = i.kind {
    if p.segments.len() > 2 {
      self.skip_paths += u8::from(p.res.value_ns.is_some()) + u8::from(p.res.type_ns.is_some()) + u8::from(p.res.mac_ns.is_some());
    }
    // Continue linting
  }
}

fn check_path(&mut self, cx: &LateContext<'tcx>, p: &'tcx Path<'_>) {
  if let [first, mid @ .., last] = path.segments {
    if let Some(count) = self.skip_paths.checked_sub(1) {
      self.skip_paths = count;
      return;
    }
    // Continue linting
  }
}

Note that you want to do the minimum amount of work possible for single segment paths since they are by far the most common and trivially not lintable.


If you want a fun case you can do something like:

use {
  some_crate::foo,
  ::{
    std::{fmt::{*, Formatter}, fs, sync::atomic},
    core::u32,
    some_crate::bar,
  },
  ::alloc::fmt::Result as FmtResult,
};

@bushrat011899

Copy link
Copy Markdown
Contributor Author

That's a good idea, thanks! I'm going to play with it and see what I can come up with.

@rustbot author

@rustbot rustbot added S-waiting-on-author Status: This is awaiting some action from the author. (Use `@rustbot ready` to update this status) and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties labels Jul 1, 2026
@bushrat011899 bushrat011899 force-pushed the std_instead_of_core_multi_imports branch from 5e134b4 to f3f0728 Compare July 7, 2026 00:44
@rustbot

This comment has been minimized.

@bushrat011899 bushrat011899 force-pushed the std_instead_of_core_multi_imports branch from f3f0728 to 90de61a Compare July 7, 2026 00:59
@rustbot

rustbot commented Jul 7, 2026

Copy link
Copy Markdown
Collaborator

This PR was rebased onto a different master commit. Here's a range-diff highlighting what actually changed.

Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers.

@bushrat011899 bushrat011899 force-pushed the std_instead_of_core_multi_imports branch from 90de61a to 6adb667 Compare July 7, 2026 01:06
@bushrat011899

Copy link
Copy Markdown
Contributor Author

@rustbot ready

Thanks for the suggestion Jarcho! I've done a larger re-write fixing multiple issues with this lint in #17364, but I've structured it so the multi-import fix can be pulled out into this PR for the sake of review. I've tried to structure my rewrite to match the original implementation as much as possible to make the diff easier to review, but it's probably easier to just read the new implementation as if it's new.

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties and removed S-waiting-on-author Status: This is awaiting some action from the author. (Use `@rustbot ready` to update this status) labels Jul 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

S-waiting-on-review Status: Awaiting review from the assignee but also interested parties

Projects

None yet

Development

Successfully merging this pull request may close these issues.

std-instead-of-core: core not in scope std_instead_of_core creates an invalid fix on stacked imports

4 participants