Skip to content
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

Take advantage of Rust 1.82 featues. #541

Merged
merged 5 commits into from
Oct 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ resolver = "2"
# When changing any of these values, be sure to also update the non-workspace packages
# as listed above, if applicable.
edition = "2021"
rust-version = "1.81"
rust-version = "1.82"
license = "MIT OR Apache-2.0"
authors = ["Kevin Reid <[email protected]>"]
# TODO: add homepage = "..." when we have one
Expand Down
44 changes: 38 additions & 6 deletions all-is-cubes-base/src/math/color.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,22 @@ impl Rgb {
/// No other range checks are performed.
#[inline]
#[track_caller]
pub fn new(r: f32, g: f32, b: f32) -> Self {
Self::try_from(vec3(r, g, b)).expect("Color components may not be NaN")
pub const fn new(r: f32, g: f32, b: f32) -> Self {
match Self::try_new(vec3(r, g, b)) {
Ok(color) => color,
Err(_) => panic!("color components may not be NaN"),
}
}

const fn try_new(value: Vector3D<f32, Intensity>) -> Result<Self, FloatIsNan> {
match (
new_nn_f32(value.x),
new_nn_f32(value.y),
new_nn_f32(value.z),
) {
(Ok(r), Ok(g), Ok(b)) => Ok(Self(vec3(r, g, b))),
(Err(e), _, _) | (_, Err(e), _) | (_, _, Err(e)) => Err(e),
}
}

/// Constructs a color from components that have already been checked for not being
Expand All @@ -124,7 +138,8 @@ impl Rgb {
/// Constructs a shade of gray (components all equal). Panics if any component is NaN.
/// No other range checks are performed.
#[inline]
pub fn from_luminance(luminance: f32) -> Self {
#[track_caller]
pub const fn from_luminance(luminance: f32) -> Self {
Self::new(luminance, luminance, luminance)
}

Expand Down Expand Up @@ -224,8 +239,11 @@ impl Rgba {
/// No other range checks are performed.
#[inline]
#[track_caller]
pub fn new(r: f32, g: f32, b: f32, a: f32) -> Self {
Rgb::new(r, g, b).with_alpha(NotNan::new(a).expect("Alpha may not be NaN"))
pub const fn new(r: f32, g: f32, b: f32, a: f32) -> Self {
match new_nn_f32(a) {
Ok(a) => Rgb::new(r, g, b).with_alpha(a),
Err(_) => panic!("alpha may not be NaN"),
}
}

/// Constructs a color from components that have already been checked for not being
Expand All @@ -244,7 +262,8 @@ impl Rgba {
/// Constructs a shade of gray (components all equal). Panics if any component is NaN.
/// No other range checks are performed.
#[inline]
pub fn from_luminance(luminance: f32) -> Self {
#[track_caller]
pub const fn from_luminance(luminance: f32) -> Self {
Rgb::new(luminance, luminance, luminance).with_alpha_one()
}

Expand Down Expand Up @@ -784,6 +803,19 @@ const CONST_LINEAR_LOOKUP_TABLE: &[f32; 256] = &[
0.9882353, 0.99215686, 0.99607843, 1.0,
];

// Const replacement for `NotNan::new()`
const fn new_nn_f32(value: f32) -> Result<NotNan<f32>, FloatIsNan> {
#![allow(clippy::eq_op)]
// This condition is true if and only if the value is NaN
// TODO: Replace this with `.is_nan()` after Rust 1.83 is released with `const_float_classify`.
if value != value {
Err(FloatIsNan)
} else {
// SAFETY: We just checked the only safety condition.
Ok(unsafe { NotNan::new_unchecked(value) })
}
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
3 changes: 1 addition & 2 deletions all-is-cubes-base/src/raycast/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,7 @@ impl TestStep {
fn matches(self, step: &RaycastStep) -> bool {
self.cube == step.cube_ahead()
&& self.face == step.face()
&& self.t_distance.map_or(true, |td| step.t_distance() == td)
&& self.t_distance.map_or(true, |td| step.t_distance() == td)
&& self.t_distance.is_none_or(|td| step.t_distance() == td)
}
}

Expand Down
2 changes: 0 additions & 2 deletions all-is-cubes-desktop/src/glue/rerun_mesh.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,6 @@ impl From<mesh::BlockVertex<NoTexture>> for Vertex {
position: v.position.to_f32().to_array().into(),
color: match v.coloring {
mesh::Coloring::Solid(color) => color.to_srgb8().into(),
#[allow(unreachable_patterns)] // TODO: Remove this arm after Rust 1.82
mesh::Coloring::Texture { .. } => unreachable!(),
},
}
}
Expand Down
17 changes: 8 additions & 9 deletions all-is-cubes-mesh/src/block_mesh/viz.rs
Original file line number Diff line number Diff line change
Expand Up @@ -213,15 +213,14 @@ impl Viz {
state
.mesh_vertex_positions
.extend(vertex_positions.iter().copied());
state.mesh_vertex_colors.extend(
iter::repeat(rg::components::Color(color_fn().into())).take(vertex_positions.len()),
);
state.mesh_vertex_normals.extend(
iter::repeat(rg::components::Vector3D(rg::convert_vec(
normal.normal_vector::<f32, ()>(),
)))
.take(vertex_positions.len()),
);
state.mesh_vertex_colors.extend(iter::repeat_n(
rg::components::Color(color_fn().into()),
vertex_positions.len(),
));
state.mesh_vertex_normals.extend(iter::repeat_n(
rg::components::Vector3D(rg::convert_vec(normal.normal_vector::<f32, ()>())),
vertex_positions.len(),
));
state.mesh_triangle_indices.extend(
relative_indices_iter
.clone()
Expand Down
2 changes: 1 addition & 1 deletion all-is-cubes-mesh/src/space_mesh.rs
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ impl<M: MeshTypes> SpaceMesh<M> {
if let Some(adj_block_index) = space_data_source(adjacent_cube) {
if block_meshes
.get_block_mesh(adj_block_index, adjacent_cube, false)
.map_or(false, |bm| bm.face_vertices[face.opposite()].fully_opaque)
.is_some_and(|bm| bm.face_vertices[face.opposite()].fully_opaque)
{
// Don't draw obscured faces, but do record that we depended on them.
bitset_set_and_get(
Expand Down
4 changes: 2 additions & 2 deletions all-is-cubes-port/src/gltf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@ impl GltfWriter {
for (frame_number, state) in self.frame_states.iter().enumerate() {
for &instance in &state.visible_mesh_instances {
let timeline = timelines.entry(instance).or_default();
if !timeline.last().map_or(true, |&(_, vis)| vis) {
if !timeline.last().is_none_or(|&(_, vis)| vis) {
// Node needs to be made visible.
timeline.push((frame_number, true));
}
Expand All @@ -267,7 +267,7 @@ impl GltfWriter {
match timelines.entry(instance) {
Entry::Occupied(mut e) => {
let timeline = e.get_mut();
if timeline.last().map_or(true, |&(_, vis)| vis) {
if timeline.last().is_none_or(|&(_, vis)| vis) {
// Node needs to be made invisible.
timeline.push((frame_number, false));
}
Expand Down
2 changes: 0 additions & 2 deletions all-is-cubes-ui/src/ui_content/pages.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,6 @@ pub(super) fn new_paused_page(
// TODO: quit_fn should be an async function, but we don't have a way to
// kick off a “Quitting...” task yet.
move || match quit_fn() {
#[allow(unreachable_patterns, reason = "TODO: Remove this arm after Rust 1.82")]
Ok(s) => match s {},
Err(_cancelled) => {

// TODO: display message indicating failure
Expand Down
2 changes: 1 addition & 1 deletion all-is-cubes-wasm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ name = "all-is-cubes-wasm"
version = "0.8.0"
authors = ["Kevin Reid <[email protected]>"]
edition = "2021"
rust-version = "1.81"
rust-version = "1.82"
description = "Web client for the recursive voxel game All is Cubes."
# TODO: add homepage = "..." when we have one
repository = "https://github.com/kpreid/all-is-cubes"
Expand Down
2 changes: 1 addition & 1 deletion all-is-cubes/src/behavior.rs
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ impl<H: Host> BehaviorSet<H> {
}
},
)
.filter(move |qi| type_filter.map_or(true, |t| (*qi.behavior).type_id() == t))
.filter(move |qi| type_filter.is_none_or(|t| (*qi.behavior).type_id() == t))
}

pub(crate) fn step(
Expand Down
9 changes: 5 additions & 4 deletions all-is-cubes/src/block/attributes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ impl BlockAttributes {
Self::DEFAULT
}

#[mutants::skip] // currently used only as an optimization, and hard to test usefully
pub(crate) fn rotationally_symmetric(&self) -> bool {
let Self {
display_name: _,
Expand All @@ -150,12 +151,12 @@ impl BlockAttributes {

inventory.rotationally_symmetric()
&& rotation_rule.rotationally_symmetric()
&& !tick_action
&& tick_action
.as_ref()
.is_some_and(|a| !a.rotationally_symmetric())
&& !activation_action
.is_none_or(|a| a.rotationally_symmetric())
&& activation_action
.as_ref()
.is_some_and(|a| !a.rotationally_symmetric())
.is_none_or(|a| a.rotationally_symmetric())
}

pub(crate) fn rotate(self, rotation: GridRotation) -> BlockAttributes {
Expand Down
2 changes: 1 addition & 1 deletion all-is-cubes/src/block/eval/evaluated.rs
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,7 @@ impl EvaluatedBlock {
let inventory = inv::Inventory::from_slots(
itertools::Itertools::zip_longest(
contents,
core::iter::repeat(inv::Slot::Empty).take(config.size),
core::iter::repeat_n(inv::Slot::Empty, config.size),
)
.map(|z| z.into_left())
.collect::<Box<[inv::Slot]>>(),
Expand Down
1 change: 0 additions & 1 deletion all-is-cubes/src/content/palette.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
//
// 0xBB is the sRGB value approximating linear value 0.5.

#![allow(unknown_lints)] // TODO: remove after Rust 1.82 is released
#![allow(clippy::too_long_first_doc_paragraph, reason = "false positive on SVG")]

use crate::math::{rgb_const, Rgb};
Expand Down
1 change: 0 additions & 1 deletion all-is-cubes/src/drawing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,6 @@ pub fn rectangle_to_aab(rectangle: Rectangle, transform: Gridgid, max_brush: Gri
// way, since it is precisely about identifying the volume occupied by drawing a
// 2D-pixel.

#![allow(unknown_lints)] // TODO: remove after Rust 1.82 is released
#![allow(clippy::too_long_first_doc_paragraph)] // TODO: find better phrasing

if rectangle.size.width == 0 || rectangle.size.height == 0 {
Expand Down
3 changes: 2 additions & 1 deletion all-is-cubes/src/space/light/queue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -211,9 +211,10 @@ impl LightUpdateQueue {

/// Removes and returns the highest priority queue entry.
#[inline]
#[mutants::skip] // if it fails to pop, causes hangs
pub fn pop(&mut self) -> Option<LightUpdateRequest> {
if let Some(sweep) = &mut self.sweep {
if peek_priority(&self.queue).map_or(true, |p| self.sweep_priority > p) {
if peek_priority(&self.queue).is_none_or(|p| self.sweep_priority > p) {
if let Some(cube) = sweep.next() {
return Some(LightUpdateRequest {
cube,
Expand Down
3 changes: 2 additions & 1 deletion all-is-cubes/src/space/light/updater.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,11 +113,12 @@ impl LightStorage {
}
}

#[mutants::skip] // lots of ways for this to still work when modified
pub(crate) fn light_needs_update_in_region(&mut self, region: GridAab, priority: Priority) {
let Some(region) = region.intersection_cubes(self.contents.bounds()) else {
return;
};
if !region.volume().is_some_and(|v| v <= 400) {
if region.volume().is_none_or(|v| v > 400) {
self.light_update_queue.sweep(region, priority);
} else {
for cube in region.interior_iter() {
Expand Down
Loading