-
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
Incorrect effect of stability attribute on calling private const fn #75794
Comments
This was a conscious choice: rust/src/librustc_mir/const_eval/fn_queries.rs Lines 66 to 71 in 663d2f5
I suppose we could change this if it's causing problems, but some caution here is warranted. We've made some mistakes in the past with these checks. |
Thanks for the link! Looking at the workaround in https://github.com/rust-lang/rust/pull/75772/files#r474918624 (adding an If we want private helpers to be annotated with But from reading the comment you linked, I'm not sure why this specific error would go away by adding an |
Well the branch that makes rust/src/librustc_mir/const_eval/fn_queries.rs Lines 62 to 63 in 45060c2
As for the "why", I didn't write the code or formulate the rules. My understanding is that, as long as a function is unstable in some way (either with the usual stability attributes or the similar |
What would go wrong if we treat all private functions as They may then separately be |
We would have to ensure that all |
That seems backward--- If "Unstable functions need not conform to min_const_fn" according to #75794 (comment), and we were to treat all private functions as if they were unstable as per #75794 (comment), why would that imply ensuring that all private functions conform to min const fn restrictions? |
If you want to call a function (the callee) from a function that is marked both The hard rule here is that we can't let const-stable functions call functions that do not pass the "min |
I'll poke @oli-obk because from looking at the commit history of the is_min_const_fn logic, this looks like maybe just an implementation oversight in 83b8a56. The scenario is: #![feature(staged_api, const_fn)]
#![stable(feature = "repro", since = "0")]
#![allow(dead_code)]
#[unstable(feature = "detail", issue = "none")] // does not compile
//#[stable(feature = "repro", since = "0")] // compiles
pub mod detail {
pub(crate) const fn bar() {}
}
// not public, not rustc_const_stable, maybe not even used
const fn foo() {
detail::bar();
} @oli-obk can you tell whether it's intentional in this code that |
The thing I want is for I think the code I opened this issue with ended up not being representative of the confusion in #75772. The code in my previous comment is the most accurate. |
In that example, the choice of whether rust/src/librustc_mir/const_eval/fn_queries.rs Lines 66 to 71 in 663d2f5
However, in your original example, the outer function is const-stable, and thus must be "min There's also the question of whether |
I think this is where we are not seeing this the same way. As the libs team sees it, functions in the standard library are one of:
Bar is not unstable, it is private. In reality it appears that |
It seems that you would be more receptive to an explanation if it came from @oli-obk. I'll stop polluting this thread with noise, but I will point out that |
That's where I'm saying the is_min_const_fn implementation is buggy. :) Not knowing the actual implementation but just the practical effect from the libs team point of view, the reason lookup_stability is implemented that way is so that we can be lazy with #![feature(staged_api, const_fn)]
#![stable(feature = "repro", since = "0")]
#[unstable(feature = "wip", issue = "none")]
pub mod detail {
pub struct U;
pub struct V;
} Though note that #![feature(staged_api, const_fn)]
#![stable(feature = "repro", since = "0")]
#[stable(feature = "repro", since = "0")]
pub mod detail {
pub struct U;
pub struct V;
} error: struct has missing stability attribute
--> src/lib.rs:6:5
|
6 | pub struct U;
| ^^^^^^^^^^^^^
error: struct has missing stability attribute
--> src/lib.rs:7:5
|
7 | pub struct V;
| ^^^^^^^^^^^^^ The thing is, before is_min_const_fn existed, the behavior of lookup_stability on anything private was completely irrelevant. Whatever behavior it has is probably whatever was easiest to implement. For the behavior that we want for min const fn, I don't think it makes sense to use lookup_stability in the current way, or else lookup_stability itself needs to change in order to respect that stable/unstable isn't a concept that applies to private things. |
That all makes sense. I have long wanted a more consistent version of these rules, since the current ones seem to be mostly emergent. The hard requirement here is that all publicly exported, const-stable functions pass the "min |
Sounds good, I'm fully on board with that. The hard requirement from the libs team is that functions are exactly one of publicly exported and stable, publicly exported and unstable, or not publicly exported. There mustn't be anything that hinges on whether a private function is "stable" or "unstable". Those things refer to whether we are permitted to make breaking changes still to a public API, and they have no relevance to anything that cannot be accessed publicly. We're fine with an independent dimension of const-stable vs const-unstable which applies to both public and private functions. |
The reason we have this wonky system is that we didn't use to have I would definitely like to have a hard requirement of either I would have thought that #![feature(staged_api, const_fn)]
#![stable(feature = "repro", since = "0")]
#![allow(dead_code)]
#[unstable(feature = "detail", issue = "none")]
pub mod detail {
#[rustc_const_stable(...)]
pub(crate) const fn bar() {}
}
// not public, not rustc_const_stable, maybe not even used
const fn foo() {
detail::bar();
} would compile, which is also how I'd expect all of this to work. Maybe we should not be checking the regular stability of the const fn, but whether the current crate is |
Cc @rust-lang/wg-const-eval (looks like the group hasn't been pinged yet) |
@dtolnay isn't it currently the case that all private methods are considered implicitly "unstable" by the stability system? AFAIK in a crate with If that is the case, then wouldn't the consistent thing to do with EDIT: turns out visibility is taken into account by the normal stability system, that is |
This seems right. I mentioned this issue in #76618, but tweaking these rules can be done separately. I'll need to do a bit of refactoring to incorporate them into |
In general we don't require private functions to have stability attributes. Stable functions are free to call private functions, and stable const functions are free to call private const functions that have no stability attribute.
But when a private const function inherits a stability attribute from an enclosing module, it currently can no longer be called from stable const functions. I think this behavior is not correct. For a private function, I would think stability attributes should be irrelevant.
This is causing trouble in #75772 (comment).
Cross referencing
const fn
tracking issue #57563.The text was updated successfully, but these errors were encountered: