Skip to content

Recursion stack for detecting cyclic imports#158035

Open
LorrensP-2158466 wants to merge 1 commit into
rust-lang:mainfrom
LorrensP-2158466:import-cycle-det
Open

Recursion stack for detecting cyclic imports#158035
LorrensP-2158466 wants to merge 1 commit into
rust-lang:mainfrom
LorrensP-2158466:import-cycle-det

Conversation

@LorrensP-2158466

Copy link
Copy Markdown
Contributor

Instead of using the borrow_mut counter of a RefCell for a NameResolution for detecting cyclic imports during import resolution, we use an explicit recursion stack that keeps track of the current used NameResolutions.

Because of the upcoming parallelisation of the import resolution algorithm, the current way cannot used in a parallel context.

r? @petrochenkov

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Jun 17, 2026
Comment on lines +361 to +369
thread_local! {
/// During import resolution, recursive imports can form cycles.
/// This set stores the active resolution stack for the current thread.
/// So it's essentially a recursion stack.
///
/// The key is the address of a `NameResolution`; we only need identity,
/// not access to the value.
static ACTIVE_RESOLUTIONS: CacheRefCell<BTreeSet<*const ()>> = Default::default();
}

@LorrensP-2158466 LorrensP-2158466 Jun 17, 2026

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.

So I already did it using TLS to show how I was thinking of a solution for parallel import resolution.

Can be easily translated to Rc<RefCell<...>> in the Resolver itself.

View changes since the review

@rust-log-analyzer

This comment has been minimized.

…mut`. Place recursion stack in TLS ahead of parallel import resolution
active.remove(&self.key);
});
}
}

@LorrensP-2158466 LorrensP-2158466 Jun 17, 2026

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.

DropGuard is possible (unstable feature though). But I don't like how I need to fill in the types:

/// We need a way to remove the resolution from the stack whenever we return, this type
/// holds that resolution key and removes it on drop.
pub(crate) type ImportCycleGuard<D: FnOnce(*const ())> = DropGuard<*const (), D>;

pub(crate) fn enter_cycle_detector(
    &self,
    resolution: &'ra CmRefCell<NameResolution<'ra>>,
) -> Result<ImportCycleGuard<impl FnOnce(*const ())>, ()> {

View changes since the review

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. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants