-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
Add #[default_method_body_is_const] #86857
Conversation
(rust-highfive has picked a reviewer for you, use r? to override) |
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'm not familiar with const fn
s, but I'd expect that functions marked #[default_method_body_is_const]
must abide by the same restrictions as const fn
s (you can't call non-const functions, etc). Apparently const checking occurs in rustc_mir::transform::check_consts
, you might want to take a look there.
Also, IIUC a function with #[default_method_body_is_const]
is considered a const fn
only in a const impl
. I know nothing about how the compiler handles calls to const fn
s, but I'd expect that someone needs to point out that, hey, that function is const
here. Can't help much with that though, so I'll pass the PR to someone that actually understands the mechanisms at play 😅
Left a few nits as well.
r? @RalfJung do you want to take this? |
I agree, the problem is with the current changes a definition below would not error: trait DefaultNonConstIsConst {
#[default_method_body_is_const]
fn i_lied() {
println!("WARNING: NOT CONST")
}
} I will look into this, but I would also appreciate it if someone can point me in the right direction. EDIT: I don't know where I can make it check a default function of trait, if marked by the attribute... |
I'm afraid this week I am rather swamped, and this is not code I have ever touched. (I didn't even know there is const checking going on in "rustc passes".) |
Is there somewhere a description of the point of this feature and how it fits in the larger story of |
I'm not sure if this does the trick or whether default bodies have other gotchas, but it should suffice to check in |
EDIT: it worked, I put the "lying" trait into another file instead of the one containing errors. |
It does the const check, but it has some issues, as shown in the code below: #![feature(const_trait_impl)]
#![allow(incomplete_features)]
#![feature(const_fn_trait_bound)] // <- why is this needed?
trait ConstDefaultFn: Sized {
fn b(self);
#[default_method_body_is_const]
fn a(self) {
self.b(); // Should not error here as this is only in `impl const ConstDefaultFn for Whatever`
}
}
struct NonConstImpl;
struct ConstImpl;
impl ConstDefaultFn for NonConstImpl {
fn b(self) {}
}
impl const ConstDefaultFn for ConstImpl {
fn b(self) {}
}
const fn test() {
NonConstImpl.a(); // Should error: `fn a(self) of NonConstImpl is not const`
ConstImpl.a();
}
fn main() {}
This is beyond my knowledge of the const-checking system, and I am not sure what to do next. I will push a commit with the (failed) test and mark this as a draft. |
This comment has been minimized.
This comment has been minimized.
maybe due to the implicit |
this is tricky. we need to treat the |
So...
caller has the attribute and callee is a method on the same trait as caller . I'm not sure how super traits work with impl const Trait right now, but once that works, we can include methods from super traits, too.
|
This comment has been minimized.
This comment has been minimized.
Done, I don't think making the trait function NonConstImpl.a(); currently does not error. If it is special-cased in |
aw. why is this happening. Probably because of the way default method bodies are desugared. They are in fact using something like specialization in the background, so we get something like trait ConstDefaultFn: Sized {
fn b(self);
fn a(self);
}
default impl<T> const ConstDefaultFn for T {
fn a(self) {
self.b();
}
}
struct NonConstImpl;
struct ConstImpl;
impl ConstDefaultFn for NonConstImpl {
fn b(self) {}
}
impl const ConstDefaultFn for ConstImpl {
fn b(self) {}
} and the the last two impls never get their own DefId for their So neither the attribute system we have now, nor the desugared specialization scheme will work as desired. rust/compiler/rustc_middle/src/hir/map/mod.rs Line 467 in d04ec47
is_const_fn right now. This treats the body as const fn, which is exactly what we want. The body will now get const checked. We should probably look at all call sites of body_const_context to see if this is indeed how this function is used, and then document that it may only be used for body information, never to assume things about the signature.
Now we need to figure out a way to be able to call functions that have the attribute. It is not sufficient to, just before your newly added same-trait check, check that the callee has the attribute and return true. This would effectively make the attribute equivalent to having So... my next idea was to check if the impl of the trait for the So... I guess we can use https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/context/struct.TyCtxt.html#method.for_each_relevant_impl to iterate over all impls of the trait for the type (remember, with specialization there can be multiple) and check if they are all Finally, the above changes have sufficiently changed things up for CTFE's dynamic checks to bail out when trying to eval such functions (as they use
|
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
Thank you for the detailed mentor instructions. I have applied all of them and will mark this as ready for review now. |
r? @oli-obk |
Other tests suggest that non-x86 arches have the correct size. This error is spurious, my code has not changed dylib stuff...
|
@fee1-dead: 🔑 Insufficient privileges: not in try users |
@bors retry |
⌛ Testing commit 7c9e214 with merge 622ec7f53c6edc9f546196a035c2afb023674b70... |
The job Click to see the possible cause of the failure (guessed by this bot)
|
💔 Test failed - checks-actions |
This comment has been minimized.
This comment has been minimized.
@oli-obk please tell bors to retry this, thx |
☀️ Test successful - checks-actions |
@rustbot label F-const_trait_impl