Skip to content

Add an experimental internal attribute for limiting const evaluation to crate-local things - #163092

Draft
oli-obk wants to merge 1 commit into
rust-lang:mainfrom
oli-obk:view-types/rustc_isolated_const-attribute
Draft

oli-obk wants to merge 1 commit into
rust-lang:mainfrom
oli-obk:view-types/rustc_isolated_const-attribute

Conversation

@oli-obk

@oli-obk oli-obk commented Sep 21, 2026 •

Copy link
Copy Markdown
Contributor

View all comments

As a part of rust-lang/goals#620, we'll want to be able to run const eval on MIR created (transitively, through the usual steps) from local AST, but not allow it to access anything outside that body. This is fairly straight forward for many things like accessing structs/functions from the local crate, as we can just handle that at resolving time (or it will automatically happen, as we literally can't see the other items existing). But there are global things like trait solving, where a trait from an upstream crate can be implemented for a type from the current crate, and the compiler will first collect all the impls from all crates when looking at a trait in the trait solver.

This PR adds the forever unstable rustc_isolated_const attribute that changes the solver mode to IsolatedConst, which in turn just doesn't collect any of the local impls at all. This is the most minimal step towards avoiding a query dependency from hir_ty_lowering, typeck, borrowck, and ctfe to the global resolver query. There are more steps necessary, but this PR adds the framework and performs the most visible limitations.

Thanks @scrabsha for doing the major part of the work here and passing it on to me

r? types

@rustbot

rustbot commented Sep 21, 2026

Copy link
Copy Markdown
Collaborator

clippy is developed in its own repository. If possible, consider making this change to rust-lang/rust-clippy instead.

cc @rust-lang/clippy

Some changes occurred to MIR optimizations

cc @rust-lang/wg-mir-opt

Some changes occurred in compiler/rustc_passes/src/check_attr.rs

cc @jdonszelmann, @JonathanBrouwer

Some changes occurred to the CTFE machinery

cc @RalfJung, @lcnr

Some changes occurred in compiler/rustc_attr_ir

cc @jdonszelmann, @JonathanBrouwer

HIR ty lowering was modified

cc @fmease

Some changes occurred to the core trait solver

cc @rust-lang/initiative-trait-system-refactor

Some changes occurred in compiler/rustc_attr_parsing

cc @jdonszelmann, @JonathanBrouwer

@rustbot rustbot added A-attributes Area: Attributes (`#[…]`, `#![…]`) S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-clippy Relevant to the Clippy team. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-rustdoc Relevant to the rustdoc team, which will review and decide on the PR/issue. WG-trait-system-refactor The Rustc Trait System Refactor Initiative (-Znext-solver) labels Sep 21, 2026
@oli-obk

oli-obk commented Sep 21, 2026

Copy link
Copy Markdown
Contributor Author

@bors try @rust-timer queue

@rust-timer

This comment has been minimized.

@rustbot rustbot added the S-waiting-on-perf Status: Waiting on a perf run to be completed. label Sep 21, 2026
@rust-bors

This comment has been minimized.

rust-bors Bot pushed a commit that referenced this pull request Sep 21, 2026
…bute, r=<try>

Add an experimental internal attribute for limiting const evaluation to crate-local things
@rust-bors

rust-bors Bot commented Sep 21, 2026

Copy link
Copy Markdown
Contributor

☀️ Try build successful (CI)
Build commit: 5682a2d (5682a2d90b87b2f67b00147c28c8e7b52c2b2c3a)
Base parent: d287eb7 (d287eb7a292caa8abbe12051dce2ee707fe03200)

@rust-timer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@rust-timer

Copy link
Copy Markdown
Collaborator

Finished benchmarking commit (5682a2d): comparison URL.

Overall result: ❌ regressions - please read:

Benchmarking means the PR may be perf-sensitive. It's automatically marked not fit for rolling up. Overriding is possible but disadvised: it risks changing compiler perf.

Next, please: If you can, justify the regressions found in this try perf run in writing along with @rustbot label: +perf-regression-triaged. If not, fix the regressions and do another perf run. Neutral or positive results will clear the label automatically.

@bors rollup=never rustc-perf
@rustbot label: -S-waiting-on-perf +perf-regression

Instruction count

Our most reliable metric. Used to determine the overall result above. However, even this metric can be noisy.

mean range count
Regressions ❌
(primary)
0.2% [0.2%, 0.2%] 3
Regressions ❌
(secondary)
0.4% [0.1%, 0.8%] 7
Improvements ✅
(primary)
- - 0
Improvements ✅
(secondary)
-0.6% [-0.6%, -0.6%] 1
All ❌✅ (primary) 0.2% [0.2%, 0.2%] 3

Max RSS (memory usage)

Results (primary -2.2%, secondary 6.9%)

A less reliable metric. May be of interest, but not used to determine the overall result above.

mean range count
Regressions ❌
(primary)
- - 0
Regressions ❌
(secondary)
6.9% [6.9%, 6.9%] 1
Improvements ✅
(primary)
-2.2% [-3.3%, -1.1%] 2
Improvements ✅
(secondary)
- - 0
All ❌✅ (primary) -2.2% [-3.3%, -1.1%] 2

Cycles

Results (secondary 7.8%)

A less reliable metric. May be of interest, but not used to determine the overall result above.

mean range count
Regressions ❌
(primary)
- - 0
Regressions ❌
(secondary)
18.2% [18.2%, 18.2%] 1
Improvements ✅
(primary)
- - 0
Improvements ✅
(secondary)
-2.6% [-2.6%, -2.6%] 1
All ❌✅ (primary) - - 0

Binary size

This perf run didn't have relevant results for this metric.

Bootstrap: 503.997s -> 496.497s (-1.49%)
Artifact size: 408.93 MiB -> 406.90 MiB (-0.50%)

@rustbot rustbot added perf-regression Performance regression. and removed S-waiting-on-perf Status: Waiting on a perf run to be completed. labels Sep 21, 2026
@oli-obk
oli-obk force-pushed the view-types/rustc_isolated_const-attribute branch from ab2f929 to 3971432 Compare September 22, 2026 06:53
@rustbot

rustbot commented Sep 22, 2026

Copy link
Copy Markdown
Collaborator

This PR was rebased onto a different main 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.

@oli-obk
oli-obk force-pushed the view-types/rustc_isolated_const-attribute branch 2 times, most recently from 26c0a13 to 8cd3a15 Compare September 22, 2026 07:34
@rust-log-analyzer

This comment has been minimized.

@oli-obk
oli-obk force-pushed the view-types/rustc_isolated_const-attribute branch from 8cd3a15 to 8eb7f88 Compare September 22, 2026 08:59
ty::TypingMode::Typeck { defining_opaque_types_and_generators } => {
defining_opaque_types_and_generators
}
ty::TypingMode::IsolatedConst => ty::List::empty(),

@lcnr lcnr Sep 22, 2026 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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.

XD I was thinking I should add a comment here... typeck needs to know about IsolatedConst as well, but that would mean essentially adding a new dimension typing mode, where everything can be an isolated const, but also have the normal typingmode.

Instead this MVP just forbids having opaque types at all, even if we could make RPITs work. TAITs won't work as they require access to other items from the current crate

if self
.tcx
.all_impls(candidate.def_id)
.all_impls(candidate.def_id, self.typing_mode().include_local_impls())

@lcnr lcnr Sep 22, 2026 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

when do we use all_impls without specifying the typing mode? because if so, there should maybe just be an infcx.all_impls wrapper which considers the typing mode

View changes since the review

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.

we should never use all_impls without specifying the mode, and always use the mode of the infcx if available

ty::TypingMode::PostAnalysis | ty::TypingMode::Codegen => {}
ty::TypingMode::PostAnalysis
| ty::TypingMode::Codegen
| ty::TypingMode::IsolatedConst => {}

@lcnr lcnr Sep 22, 2026 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

same here, feel like a lot of these matches should be bug! instead?

or well, should this be a bug!, maybe not

View changes since the review

/// layouts.
Codegen,

/// During isolated const, forbid referring to traits defined in the current trait.

@lcnr lcnr Sep 22, 2026 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

this comment needs a lot more info. Also, the PR title is wrong? isn't this limiting ctfe to non-local things?

View changes since the review

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.

the intent is to have CTFE run while only depending on non-local things. We need to prevent the trait solver from accessing things from the current crate, too (I typoed crate and wrote trait in the comment here)

@RalfJung RalfJung Sep 22, 2026 •

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This doesn't actually check that the functions invoked during CTFE are all from the current crate, does it?

View changes since the review

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.

That's not important in practice for the end goal. Either the resolver doesn't even let you call that function, or you get a cycle error, or you can call that function. All the work here is to avoid cycle errors, and we'll see how far we can take this

@RalfJung

Copy link
Copy Markdown
Member

limiting const evaluation to crate-local things

I read this as "only allow crate-local things". But looking at the goal it seems you mean the opposite?

@lcnr

lcnr commented Sep 22, 2026

Copy link
Copy Markdown
Contributor

This currently does not handle nested queries during CTFE, e.g. impossible_predicates. Effectively any query which takes a def_id and does trait solving (i.e. everything that does TypingEnv::fully_monomorphized() can cause query cycles here)

Similarly, just doing it for CTFE is insufficient as we also need to do the same during all queries affecting a given body, e.g. typeck, borrowck, and so on. This means that just a single typingmode is not enough and we need something more of a TypingMode x MayAccessUpstream.

Given the way this is incredibly pervasive, it might even make sense to integrate support for this in the query system itself, as we likely do want to cache results between these queries if they don't actually depend on anything local and as explicitly tracking this flag is a very invasive change.

Having some uses of the trait solver be able to access all impls while others only access foreign ones also makes me somewhat worried about things being inconsistent/unsound, e.g. impossible_predicates could encounter ForeignType: Trait<LocalTy> and consider it to be impossible, even though it can be implemented in the current crate. Effectively only limiting impls, but not types, should be unsound. This means it may also be nice to integrate it into the TyCtxt and maybe even add asserts that one cannot access LocalDefIds while in this mode or sth

@lcnr
lcnr marked this pull request as draft September 22, 2026 11:40
@rustbot rustbot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Sep 22, 2026
@rust-bors

rust-bors Bot commented Sep 22, 2026

Copy link
Copy Markdown
Contributor

☔ The latest upstream changes (presumably #163165) made this pull request unmergeable. Please resolve the merge conflicts by rebasing.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-attributes Area: Attributes (`#[…]`, `#![…]`) perf-regression Performance regression. S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-clippy Relevant to the Clippy team. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-rustdoc Relevant to the rustdoc team, which will review and decide on the PR/issue. WG-trait-system-refactor The Rustc Trait System Refactor Initiative (-Znext-solver)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants