-
Notifications
You must be signed in to change notification settings - Fork 14k
Add very basic "comptime" fn implementation #148820
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
|
Some changes occurred in compiler/rustc_attr_parsing Some changes occurred in compiler/rustc_passes/src/check_attr.rs Some changes occurred in compiler/rustc_hir/src/attrs Some changes occurred to the CTFE machinery Some changes occurred in src/tools/rustfmt cc @rust-lang/rustfmt |
|
rustbot has assigned @JonathanBrouwer. Use |
This comment has been minimized.
This comment has been minimized.
|
Some changes occurred to MIR optimizations cc @rust-lang/wg-mir-opt |
compiler/rustc_hir/src/hir.rs
Outdated
| Comptime, | ||
| Const, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems worth doc comments distinguishing these two.
| let fn_span = self.token.span; | ||
| let header = self.parse_fn_front_matter(vis, case, FrontMatterParsingMode::Function)?; // `const ... fn` | ||
| let mut header = self.parse_fn_front_matter(vis, case, FrontMatterParsingMode::Function)?; // `const ... fn` | ||
| if let Some(attr) = attrs.iter().find(|attr| attr.has_name(sym::rustc_comptime)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doesn't account for #[cfg_attr(…, rustc_comptime)]. I would just leave the parser and ast::Const alone and do the lowering to hir::Constness (which would still have Comptime) in AST lowering. This should simplify things a lot.
Even if you anticipate it being turned into a keyword / qualifier eventually, you can't assume that and it would be super easy anyway to update the parser & AST once it's truly necessary.
This comment has been minimized.
This comment has been minimized.
| } | ||
|
|
||
| #[derive(Copy, Clone, PartialEq, Eq, Debug, Encodable, Decodable, HashStable_Generic)] | ||
| pub enum Constness { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Personally speaking I would rename the variants like so:
pub enum Constness {
Always, // `#[rustc_comptime]`
Maybe, // `const`
Never,
}to mirror BoundConstness which is Always (for const), Maybe (for [const]) and Never. This makes it crystal clear what they represent and leaves no room for ambiguity.
If it were up to me, I would even rename Constness to ItemConstness if traits will be allowed to be compiletime, too. Otherwise, I would split it into FnConstness and TraitConstness.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I prefer this naming over the suggestion I made in https://github.com/rust-lang/rust/pull/148820/files#r2517464261 actually
| ), | ||
| rustc_attr!( | ||
| rustc_comptime, Normal, template!(Word), ErrorFollowing, | ||
| EncodeCrossCrate::Yes, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It this necessary? The other queries would store this information
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
find_attr!(tcx.get_all_attrs(), AttributeKind::Comptime(..))would do the same (slightly slower?) but avoids a new query which might be worth it. You can set CrossCrateEncoding for attributes in compiler/rustc_hir/src/attrs/encode_cross_crate.rs
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In fact, you did mark it as cross-crate encodable oli, so if we keep the query you can turn cross crate encoding of the attribute off (see my other comment)
| if let hir::Constness::Comptime = self.tcx.constness(callee_did) { | ||
| match const_context { | ||
| Some(hir::ConstContext::Const { .. } | hir::ConstContext::Static(_)) => {} | ||
| Some(hir::ConstContext::ConstFn) | None => { | ||
| self.dcx().span_err(span, "comptime fns can only be called at compile time"); | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doesn't enforce cross crate if I use a comptime function in fn if my crate doesn't enable const_trait_impl.
Would it make sense to also add logic to constck? (check_const.rs)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well I'm working on turning this check on unconditionally. I can just move the comptime check before the feature gate check
| #[derive(HashStable_Generic, Walkable)] | ||
| pub enum Const { | ||
| Comptime(Span), | ||
| Yes(Span), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would be nice to some day make all the variant names meaningful. Something like
enum EvaluationTime {
Comptime,
MaybeComptime,
Runtime,
}Looking at your PR yday that's one of the first things I thought. First decided not to comment it because it might not be for this PR but coming back I thought I'd mention it anyway.
| BodyStability { .. } => No, | ||
| Coinductive(..) => No, | ||
| Cold(..) => No, | ||
| Comptime(..) => Yes, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can be No if we do the query
compiler/rustc_hir_pretty/src/lib.rs
Outdated
| match s { | ||
| hir::Constness::NotConst => {} | ||
| hir::Constness::Const => self.word_nbsp("const"), | ||
| hir::Constness::Comptime => self.word_nbsp("comptime"), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Comptime is an attribute for now right; #[rustc_comptime]? Pretty printing doesn't matter so much, but this makes it seem like it's already a keyword. You could make it an unstable keyword ofc. But otherwise, I think the attr is already printed itself in hir pretty printing, so you might not need to emit anything here
compiler/rustc_middle/src/ty/mod.rs
Outdated
| self.def_kind(def_id), | ||
| DefKind::Fn | DefKind::AssocFn | DefKind::Ctor(_, CtorKind::Fn) | DefKind::Closure | ||
| ) && self.constness(def_id) == hir::Constness::Const | ||
| ) && self.constness(def_id) != hir::Constness::NotConst |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know this enum is unlikely to change any time soon, but might be nicer to write as a match exhaustively naming the variants
|
Some changes occurred in src/tools/clippy cc @rust-lang/clippy Some changes occurred to constck cc @fee1-dead |
|
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. |
|
The job Click to see the possible cause of the failure (guessed by this bot)For more information how to resolve CI failures of this job, visit this link. |
Implements functions that cannot be called at runtime (and thus also not from normal const functions, as those could be called from runtime).
This is done via the internal attribute
rustc_comptimethat can be added to normal functions, turning them into compile-time-only functions.Because @fee1-dead and @compiler-errors did amazing work, we even get trait bounds that work inside comptime fns: via unconditionally-const
const Traitbounds.Use cases are
project goal issue: rust-lang/rust-project-goals#406
no tracking issue until we have a feature gate and some sort of syntax
cc @scottmcm as the T-lang goal champion