-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
refactor: const
-ify the core primitives
#5032
base: master
Are you sure you want to change the base?
Conversation
…b::or` It's slightly tempting to deprecate the old function signature, but I'll delegate that decision to @emilk.
pub const fn const_default_pos(mut self, default_pos: Pos2) -> Self { | ||
self.default_pos = Some(default_pos); | ||
self | ||
} | ||
|
||
/// See [`Self::const_default_pos`]. | ||
#[inline] | ||
pub fn default_pos(self, default_pos: impl Into<Pos2>) -> Self { | ||
let default_pos = default_pos.into(); | ||
self.const_default_pos(default_pos) | ||
} |
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 seems excessive - realistically, why would you want to construct a const Area
?
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 does sound funny, but the overall goal of this PR is to at least enable the user to compute certain initial states at compile-time. I presume that the #[inline]
already does this for optimized builds, but the added bonus feature of const
is that the user can now store these Area
configurations inside a const
or a static
so that they are guaranteed to be initialized at compile-time (rather than hoping that #[inline]
would do that for us).
So yes, semantically, a "movable const
container" is silly. Though I think the const
-ness is a misnomer for what we're actually enabling here. That is, we're not enforcing an immutable Area
; rather, we are enabling the compile-time initialization of an Area
. The const
keyword is just an unfortunately overloaded term.
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.
Adding const
to some methods is fine, but duplicating methods is not - please revert those changes
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.
Some of the trivially const
methods in the higher-level abstractions rely on the lower-level const_*
duplicates. For instance, this PR's modification of the egui::style:Visuals::dark
constructor invokes Stroke::const_new
in order to be trivially const
.
Line 1280 in fae5fdd
window_stroke: Stroke::const_new(1.0, Color32::from_gray(60)), |
Would it be amenable to keep the const
alternatives private in the meantime (i.e., until const
traits stabilize) just so we can keep the powers of const
available even in the higher-level abstractions without cluttering the public interface with duplicates?
This PR attempts to make some good changes, but the API should be consistent and solid in its usage. Because these new The best thing about this PR is adding |
That's totally fair. I'll wait on Emil's thumbs up before I start reverting some commits. |
const
-ifying the coreAs a long-time user of this library, I've noticed many of the core primitives in
emath
,epaint
, andegui
lackconst
constructors and helpers. I'm a huge fan of guaranteeing that work gets offloaded during compile-time. So in this PR, I set out toconst
-ify pretty much everything I can reasonablyconst
-ify within the constraints of stable Rust. This should empower our users to better useconst
andstatic
in their code to avoid duplicate runtime work.A Note on
const
Traits and Backwards-CompatibilityIn pursuit of API ergonomics, I noted that some functions take in
impl Into<T>
arguments. One such instance is theRect::from_x_y_ranges
constructor, which take in twoimpl Into<Rangef>
arguments.Unfortunately, due to the absence of
const
traits in stable Rust (for now!), these functions cannot be triviallyconst
-ified. Thus, I have worked around this limitation by providingconst
-ified alternatives to these functions that require exactlyT
instead ofimpl Into<T>
. I've prefixed these "alternative" functions withconst_
as the naming convention. In the future, I hope to remove theseconst_
functions when they are obsoleted by the eventual stabilization ofconst
traits.I've settled on this solution to uphold backwards-compatibility. As you can imagine, recklessly changing
impl Into<T>
into simplyT
is a recipe for disaster in the next release ofegui
.The following is a demonstration of the mechanical changes I applied to the code for
const
-ification:Future Work
There is still some more work to be done. I've left several
TODO
comments on data types that rely onDefault::default
as their respective constructors. Sinceconst Default
is not stable yet, it's impossible toconst
-ify these constructors unless we manually inlineDefault::default
into the constructor (i.e.,T::new
) and then haveDefault::default
delegate toT::new
instead. This is quite tedious, especially considering the alternative:#[derive(Default)]
.