-
Notifications
You must be signed in to change notification settings - Fork 13.3k
change some statics to constants #25823
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
Conversation
@@ -105,10 +105,12 @@ pub struct LocalKey<T> { | |||
#[allow_internal_unstable] | |||
macro_rules! thread_local { | |||
(static $name:ident: $t:ty = $init:expr) => ( | |||
#[cfg_attr(not(stage0), allow(static_could_be_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.
these might have interior mutability... The error messages the user would get would be quite confusing, I'm not sure what to do. for now they are simply ignored
At a quick glance, this doesn't seem to handle statics referencing other statics. |
won't calling the |
@oli-obk sure, but the location of the struct is unimportant, the function pointer inside returns the actual TLS pointer. |
I don't think that there's a great way to draw a line and say precisely whether a value should be a constant or a static, so I would personally not be in favor of this lint (unless it's possibly allow-by-default). For example:
There are certainly some switches from static to const in this PR which I think are fine, but I'm very worried about the noise a lint like this will generate. |
@alexcrichton Is there any case where you have a significant address and no inner mutability? The metadata bloat is more interesting. Reusing allocation space for constants across crates is something we should do before we switch over large constants to it. As for the |
I don't personally have an example offhand, but I would not be prepared to say that 100% of these cases should be constants.
We've had use-cases in the past for just having a significant address, that's how the old TLS system worked.
Ideally I'd prefer to not have these weird layers of indirection, so in the future it may be possible to have a What's the |
@@ -88,10 +88,14 @@ macro_rules! lint_initializer { | |||
macro_rules! declare_lint { | |||
// FIXME(#14660): deduplicate | |||
(pub $name:ident, $level:ident, $desc:expr) => ( | |||
// cannot be const, otherwise random lints fail to lint | |||
#[cfg_attr(not(stage0), allow(static_could_be_const))] | |||
pub static $name: &'static ::rustc::lint::Lint |
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 is one example where it has to stay static
Oops, that was meant to be I definitely agree with keeping the door open for a cleaner design - I am guessing it's a matter of disallowing passing This ability should also not depend on whether |
Won't the metadata be about the size of the saved static allocation space? Also, many static arrays are not converted to constant arrays, but to |
@oli-obk a |
so all |
static $name: ::std::thread::LocalKey<$t> = { | ||
#[cfg_attr(all(any(target_os = "macos", target_os = "linux"), | ||
not(target_arch = "aarch64")), | ||
thread_local)] | ||
#[cfg_attr(not(stage0), allow(static_could_be_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.
Wait, these ones shouldn't need the allow
, AFAIK they always contain interior mutability.
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.
then we have a bug on our hands
@oli-obk no, all constants (no matter what size) should reuse the LLVM globals across crates, instead of duplicating them. |
I wasn't specifically thinking about sending between threads, but yes this change may need to be made, I'd have to think about it.
Unfortunately the metadata required to encode a static can often be orders of magnitude larger than that of the compiled version. For example a 1000 entry constant creates a 68K rlib while a static creates an 11K rlib.
Note that we do not emit globals for constants, only if you take the address of them. We do already make use of available_externally where possible I believe as well. |
@alexcrichton if you copy a const value (e.g. a large array) to the stack, it will copy from .rodata, instead of generating code to write the data on the stack. |
I guess there's potential for optimization right there? But the duplication in every crate using it issue might then still be there. |
☔ The latest upstream changes (presumably #25858) made this pull request unmergeable. Please resolve the merge conflicts. |
d2aad59
to
935e641
Compare
rebased and changed the lint to only warn for non-public items or public ref items. I also made sure that no large constants are publicly available due to my changes. |
@@ -15,7 +15,7 @@ macro_rules! panic { | |||
panic!("explicit panic") | |||
); | |||
($msg:expr) => ({ | |||
static _MSG_FILE_LINE: (&'static str, &'static str, u32) = ($msg, file!(), line!()); | |||
const _MSG_FILE_LINE: (&'static str, &'static str, u32) = ($msg, file!(), line!()); |
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 is a case where the use of a static
is actually done as an optimization. This guarantees that the data here is translated at most once and makes calling the underlying function efficient. (e.g. this should remain a static
)
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.
(same below as well)
I'm personally still worried about the number of false positives cropping up here, there's quite a few instances that are intended to be statics but are being changed to constants. Lints like this which may in theory hurt performance in various aspects I think should never need an opt-out of the warning, but instead the warning should only happen when it's 100% certainly an improvement. |
935e641
to
54c7372
Compare
yea. I agree, the false positive rate is insane. The programmer is already opting into a fixed address with |
54c7372
to
fa99d90
Compare
@@ -369,7 +369,7 @@ impl<'a> DoubleEndedIterator for Graphemes<'a> { | |||
} | |||
|
|||
// https://tools.ietf.org/html/rfc3629 | |||
static UTF8_CHAR_WIDTH: [u8; 256] = [ | |||
const UTF8_CHAR_WIDTH: [u8; 256] = [ |
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 and the ascii maps below are getting somewhat large, how come they're constants instead of statics?
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.
they are not public, therefore I assumed they don't appear in the metadata
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.
Constants can indirectly be required to go into the metadata, for example if they're used in an #[inline]
function. If this function is never inlined then I don't believe there's a benefit one way or the other for using a static
or a const
, so it seems more appropriate to use a static
as it's an assertion that this should never go into the metadata.
d1eae73
to
ec078a0
Compare
addressed comments and squashed |
💔 Test failed - auto-mac-32-opt |
I'm not really sure how I could have caused this failure, I didn't change any docs... |
@bors: retry On Sun, Jun 7, 2015 at 11:11 PM, Oliver Schneider [email protected]
|
⚡ Previous build results for auto-mac-64-opt are reusable. Rebuilding only auto-linux-32-nopt-t, auto-linux-32-opt, auto-linux-64-nopt-t, auto-linux-64-opt, auto-linux-64-x-android-t, auto-mac-32-opt, auto-mac-64-nopt-t, auto-win-gnu-32-nopt-t, auto-win-gnu-32-opt, auto-win-gnu-64-nopt-t, auto-win-gnu-64-opt... |
r? @eddyb