diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index afab15a0..9ca9ef5a 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -22,7 +22,7 @@ jobs: - uses: actions-rs/toolchain@v1 with: profile: default - toolchain: 1.92.0 + toolchain: 1.95.0 override: true - name: Install packages (Linux) @@ -70,7 +70,7 @@ jobs: - uses: actions-rs/toolchain@v1 with: profile: minimal - toolchain: 1.92.0 + toolchain: 1.95.0 target: wasm32-unknown-unknown override: true components: clippy @@ -95,7 +95,7 @@ jobs: - uses: actions/checkout@v3 - uses: EmbarkStudios/cargo-deny-action@v2 with: - rust-version: "1.92.0" + rust-version: "1.95.0" log-level: warn command: check @@ -109,7 +109,7 @@ jobs: - uses: actions-rs/toolchain@v1 with: profile: minimal - toolchain: 1.92.0 + toolchain: 1.95.0 target: wasm32-unknown-unknown override: true - name: Download and install Trunk binary @@ -131,7 +131,7 @@ jobs: lfs: true - uses: dtolnay/rust-toolchain@master with: - toolchain: 1.92.0 + toolchain: 1.95.0 - name: Set up cargo cache uses: Swatinem/rust-cache@v2 diff --git a/Cargo.lock b/Cargo.lock index 45ba4cd5..ac51fd4f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -867,9 +867,9 @@ dependencies = [ [[package]] name = "crossbeam-epoch" -version = "0.9.18" +version = "0.9.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +checksum = "2d6914041f254d6e9176c01941b21115dcfb7089e55135a35411081bd106ef3f" dependencies = [ "crossbeam-utils", ] diff --git a/Cargo.toml b/Cargo.toml index 772f0abd..db82594f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,7 +11,7 @@ members = [ [workspace.package] edition = "2024" license = "MIT OR Apache-2.0" -rust-version = "1.92" +rust-version = "1.95" version = "0.36.0" @@ -92,6 +92,7 @@ rust_2018_idioms = { level = "warn", priority = -1 } rust_2021_prelude_collisions = "warn" semicolon_in_expressions_from_macros = "warn" trivial_numeric_casts = "warn" +unexpected_cfgs = "warn" unsafe_op_in_unsafe_fn = "warn" # `unsafe_op_in_unsafe_fn` may become the default in future Rust versions: https://github.com/rust-lang/rust/issues/71668 unused_extern_crates = "warn" unused_import_braces = "warn" @@ -103,6 +104,7 @@ unused_qualifications = "allow" [workspace.lints.rustdoc] all = "warn" +broken_intra_doc_links = "warn" missing_crate_level_docs = "warn" # See also clippy.toml @@ -124,6 +126,7 @@ coerce_container_to_any = "warn" comparison_chain = "warn" dbg_macro = "warn" debug_assert_with_mut_call = "warn" +decimal_bitwise_operands = "warn" default_union_representation = "warn" derive_partial_eq_without_eq = "warn" disallowed_macros = "warn" # See clippy.toml @@ -136,9 +139,10 @@ doc_comment_double_space_linebreaks = "warn" doc_include_without_cfg = "warn" doc_link_with_quotes = "warn" doc_markdown = "warn" +duration_suboptimal_units = "warn" elidable_lifetime_names = "warn" -empty_enum = "warn" empty_enum_variants_with_brackets = "warn" +empty_enums = "warn" empty_line_after_outer_attr = "warn" enum_glob_use = "warn" equatable_if_let = "warn" @@ -154,10 +158,12 @@ flat_map_option = "warn" float_cmp_const = "warn" fn_params_excessive_bools = "warn" fn_to_numeric_cast_any = "warn" +format_push_string = "warn" from_iter_instead_of_collect = "warn" get_unwrap = "warn" if_let_mutex = "warn" ignore_without_reason = "warn" +ignored_unit_patterns = "warn" implicit_clone = "warn" implied_bounds_in_impls = "warn" imprecise_flops = "warn" @@ -190,6 +196,7 @@ lossy_float_literal = "warn" macro_use_imports = "warn" manual_assert = "warn" manual_clamp = "warn" +manual_ilog2 = "warn" manual_instant_elapsed = "warn" manual_is_power_of_two = "warn" manual_is_variant_and = "warn" @@ -208,6 +215,7 @@ mismatching_type_param_order = "warn" missing_assert_message = "warn" missing_enforced_import_renames = "warn" missing_errors_doc = "warn" +missing_fields_in_debug = "warn" missing_safety_doc = "warn" mixed_attributes_style = "warn" mut_mut = "warn" @@ -217,10 +225,13 @@ needless_continue = "warn" needless_for_each = "warn" needless_pass_by_ref_mut = "warn" needless_pass_by_value = "warn" +needless_raw_string_hashes = "warn" +needless_type_cast = "warn" negative_feature_names = "warn" non_std_lazy_statics = "warn" non_zero_suggestions = "warn" nonstandard_macro_braces = "warn" +only_used_in_recursion = "warn" option_as_ref_cloned = "warn" option_option = "warn" or_fun_call = "warn" @@ -237,11 +248,13 @@ rc_mutex = "warn" readonly_write_lock = "warn" redundant_type_annotations = "warn" ref_as_ptr = "warn" +ref_option = "warn" ref_option_ref = "warn" ref_patterns = "warn" rest_pat_in_fully_bound_structs = "warn" return_and_then = "warn" same_functions_in_if_condition = "warn" +same_length_and_capacity = "warn" self_only_used_in_recursion = "warn" semicolon_if_nothing_returned = "warn" set_contains_or_insert = "warn" @@ -259,6 +272,7 @@ suspicious_command_arg_space = "warn" suspicious_xor_used_as_pow = "warn" todo = "warn" too_long_first_doc_paragraph = "warn" +too_many_arguments = "warn" too_many_lines = "warn" trailing_empty_array = "warn" trait_duplication_in_bounds = "warn" @@ -277,6 +291,7 @@ unnecessary_safety_doc = "warn" unnecessary_self_imports = "warn" unnecessary_semicolon = "warn" unnecessary_struct_initialization = "warn" +unnecessary_trailing_comma = "warn" unnecessary_wraps = "warn" unnested_or_patterns = "warn" unused_async = "warn" diff --git a/clippy.toml b/clippy.toml index 9f217cc4..e3db8ec5 100644 --- a/clippy.toml +++ b/clippy.toml @@ -5,7 +5,7 @@ # ----------------------------------------------------------------------------- # Section identical to scripts/clippy_wasm/clippy.toml: -msrv = "1.92" +msrv = "1.95" allow-unwrap-in-tests = true diff --git a/deny.toml b/deny.toml index c059fd7d..a6d13211 100644 --- a/deny.toml +++ b/deny.toml @@ -31,7 +31,11 @@ all-features = true [advisories] version = 2 ignore = [ - "RUSTSEC-2024-0436", # https://rustsec.org/advisories/RUSTSEC-2024-0436 - paste is unmaintained - https://github.com/dtolnay/paste + # All of these come in via `eframe`, which is only a dev-dependency of ours, + # and only on Linux. We cannot upgrade them without upstream doing so first. + "RUSTSEC-2026-0192", # https://rustsec.org/advisories/RUSTSEC-2026-0192 - ttf-parser is unmaintained, via ab_glyph -> sctk-adwaita -> winit. There is no fixed version. + "RUSTSEC-2026-0194", # https://rustsec.org/advisories/RUSTSEC-2026-0194 - quick-xml DoS, via zbus_xml -> accesskit_unix. Fixed in 0.41, but zbus_xml requires 0.39. + "RUSTSEC-2026-0195", # https://rustsec.org/advisories/RUSTSEC-2026-0195 - quick-xml DoS, via zbus_xml -> accesskit_unix. Fixed in 0.41, but zbus_xml requires 0.39. ] diff --git a/egui_plot/src/aesthetics.rs b/egui_plot/src/aesthetics.rs index c84d2eea..d02564fa 100644 --- a/egui_plot/src/aesthetics.rs +++ b/egui_plot/src/aesthetics.rs @@ -67,7 +67,7 @@ impl LineStyle { if highlight { stroke.width *= 2.0; } - let golden_ratio = (5.0_f32.sqrt() - 1.0) / 2.0; // 0.61803398875 + let golden_ratio = std::f32::consts::GOLDEN_RATIO - 1.0; // 0.61803398875 shapes.extend(Shape::dashed_line( &line, Stroke::new(stroke.width, path_stroke_color), diff --git a/egui_plot/src/items/bar_chart.rs b/egui_plot/src/items/bar_chart.rs index 16685233..65415c22 100644 --- a/egui_plot/src/items/bar_chart.rs +++ b/egui_plot/src/items/bar_chart.rs @@ -23,7 +23,7 @@ use crate::items::PlotGeometry; use crate::items::PlotItem; use crate::items::PlotItemBase; use crate::items::add_rulers_and_text; -use crate::label::LabelFormatter; +use crate::label::LabelFormatterFn; use crate::math::find_closest_rect; use crate::rect_elem::RectElement; @@ -210,7 +210,7 @@ impl PlotItem for BarChart { shapes: &mut Vec, cursors: &mut Vec, plot: &PlotConfig<'_>, - _: &Option>, + _: Option<&LabelFormatterFn<'_>>, ) { let bar = &self.bars[elem.index]; diff --git a/egui_plot/src/items/box_plot.rs b/egui_plot/src/items/box_plot.rs index 74c3238d..c5de980d 100644 --- a/egui_plot/src/items/box_plot.rs +++ b/egui_plot/src/items/box_plot.rs @@ -22,7 +22,7 @@ use crate::items::PlotGeometry; use crate::items::PlotItem; use crate::items::PlotItemBase; use crate::items::add_rulers_and_text; -use crate::label::LabelFormatter; +use crate::label::LabelFormatterFn; use crate::math::find_closest_rect; use crate::rect_elem::RectElement; @@ -176,7 +176,7 @@ impl PlotItem for BoxPlot { shapes: &mut Vec, cursors: &mut Vec, plot: &PlotConfig<'_>, - _: &Option>, + _: Option<&LabelFormatterFn<'_>>, ) { let box_plot = &self.boxes[elem.index]; diff --git a/egui_plot/src/items/heatmap.rs b/egui_plot/src/items/heatmap.rs index ed8d1428..94b440bd 100644 --- a/egui_plot/src/items/heatmap.rs +++ b/egui_plot/src/items/heatmap.rs @@ -24,7 +24,7 @@ use crate::items::PlotConfig; use crate::items::PlotGeometry; use crate::items::PlotItem; use crate::items::PlotItemBase; -use crate::label::LabelFormatter; +use crate::label::LabelFormatterFn; /// Default resolution for heatmap color palette pub const DEFAULT_RESOLUTION: usize = 128; @@ -459,7 +459,7 @@ impl PlotItem for Heatmap { shapes: &mut Vec, _cursors: &mut Vec, plot: &PlotConfig<'_>, - _: &Option>, + _: Option<&LabelFormatterFn<'_>>, ) { let (rect, color, text) = self.tile_view_info(plot.ui, plot.transform, elem.index); let mut mesh = Mesh::default(); diff --git a/egui_plot/src/items/mod.rs b/egui_plot/src/items/mod.rs index 6781a99f..95d381bb 100644 --- a/egui_plot/src/items/mod.rs +++ b/egui_plot/src/items/mod.rs @@ -41,7 +41,7 @@ pub use crate::items::series::Line; pub use crate::items::span::Span; pub use crate::items::text::Text; use crate::label::HoverPosition; -use crate::label::LabelFormatter; +use crate::label::LabelFormatterFn; use crate::rect_elem::RectElement; mod arrows; @@ -175,7 +175,7 @@ pub trait PlotItem { shapes: &mut Vec, cursors: &mut Vec, plot: &PlotConfig<'_>, - label_formatter: &Option>, + label_formatter: Option<&LabelFormatterFn<'_>>, ) { let points = match self.geometry() { PlotGeometry::Points(points) => points, @@ -283,7 +283,7 @@ pub(super) fn rulers_and_tooltip_at_value( nearest_point: Option<(&str, usize)>, plot: &PlotConfig<'_>, cursors: &mut Vec, - label_formatter: &Option>, + label_formatter: Option<&LabelFormatterFn<'_>>, ) { // Add crosshair rulers if enabled if plot.show_crosshair { diff --git a/egui_plot/src/items/series.rs b/egui_plot/src/items/series.rs index cd634cae..f77ce8ba 100644 --- a/egui_plot/src/items/series.rs +++ b/egui_plot/src/items/series.rs @@ -218,12 +218,12 @@ impl PlotItem for Line<'_> { let expected_intersections = 20; mesh.reserve_triangles((n_values - 1) * 2); mesh.reserve_vertices(n_values * 2 + expected_intersections); - values_tf.windows(2).for_each(|w| { - let fill_color = fill_color_for_point(w[0]); + for [prev, next] in values_tf.array_windows::<2>() { + let fill_color = fill_color_for_point(*prev); let i = mesh.vertices.len() as u32; - mesh.colored_vertex(w[0], fill_color); - mesh.colored_vertex(pos2(w[0].x, y), fill_color); - if let Some(x) = y_intersection(&w[0], &w[1], y) { + mesh.colored_vertex(*prev, fill_color); + mesh.colored_vertex(pos2(prev.x, y), fill_color); + if let Some(x) = y_intersection(prev, next, y) { let point = pos2(x, y); mesh.colored_vertex(point, fill_color_for_point(point)); mesh.add_triangle(i, i + 1, i + 2); @@ -232,7 +232,7 @@ impl PlotItem for Line<'_> { mesh.add_triangle(i, i + 1, i + 2); mesh.add_triangle(i + 1, i + 2, i + 3); } - }); + } let last = values_tf[n_values - 1]; let fill_color = fill_color_for_point(last); mesh.colored_vertex(last, fill_color); @@ -260,11 +260,11 @@ impl PlotItem for Line<'_> { } points - .windows(2) + .array_windows::<2>() .enumerate() - .map(|(i, w)| { - let p0 = transform.position_from_point(&w[0]); - let p1 = transform.position_from_point(&w[1]); + .map(|(i, [v0, v1])| { + let p0 = transform.position_from_point(v0); + let p1 = transform.position_from_point(v1); let dist_sq = dist_sq_to_segment(point, [p0, p1]); // Pick the closer endpoint so the tooltip shows a real data point let index = if point.distance_sq(p0) <= point.distance_sq(p1) { diff --git a/egui_plot/src/label.rs b/egui_plot/src/label.rs index ea1e2bdd..d982723f 100644 --- a/egui_plot/src/label.rs +++ b/egui_plot/src/label.rs @@ -16,7 +16,8 @@ pub fn format_number(number: f64, num_decimals: usize) -> String { } } -type LabelFormatterFn<'a> = dyn Fn(&HoverPosition<'_>) -> Option + 'a; +/// The unboxed form of [`LabelFormatter`]. +pub type LabelFormatterFn<'a> = dyn Fn(&HoverPosition<'_>) -> Option + 'a; /// Optional label formatter function for customizing hover labels. pub type LabelFormatter<'a> = Box>; diff --git a/egui_plot/src/lib.rs b/egui_plot/src/lib.rs index 91bbae06..ac7c4033 100644 --- a/egui_plot/src/lib.rs +++ b/egui_plot/src/lib.rs @@ -63,6 +63,7 @@ pub use crate::items::Text; pub use crate::items::VLine; pub use crate::label::HoverPosition; pub use crate::label::LabelFormatter; +pub use crate::label::LabelFormatterFn; pub use crate::label::default_label_formatter; pub use crate::label::format_number; pub use crate::memory::PlotMemory; diff --git a/egui_plot/src/plot.rs b/egui_plot/src/plot.rs index d993f974..687a4dd9 100644 --- a/egui_plot/src/plot.rs +++ b/egui_plot/src/plot.rs @@ -1424,9 +1424,9 @@ impl<'a> Plot<'a> { response: &Response, transform: &PlotTransform, painter: &Painter, - coordinates_formatter: &Option<(Corner, CoordinatesFormatter<'_>)>, + coordinates_formatter: Option<&(Corner, CoordinatesFormatter<'_>)>, ) { - if let Some((corner, formatter)) = coordinates_formatter.as_ref() { + if let Some((corner, formatter)) = coordinates_formatter { let hover_pos = response.hover_pos(); if let Some(pointer) = hover_pos { let font_id = TextStyle::Monospace.resolve(ui.style()); @@ -1591,7 +1591,7 @@ impl<'a> Plot<'a> { shapes, &mut cursors, &plot, - &self.label_formatter, + self.label_formatter.as_deref(), ); Some(item.id()) } else { @@ -1602,7 +1602,7 @@ impl<'a> Plot<'a> { None, &plot, &mut cursors, - &self.label_formatter, + self.label_formatter.as_deref(), ); None }; @@ -1679,7 +1679,7 @@ impl<'a> Plot<'a> { &plot_ui.response, &mem.transform, &painter, - &self.coordinates_formatter, + self.coordinates_formatter.as_ref(), ); // Show legend and update memory @@ -1890,7 +1890,7 @@ impl<'a> PlotUi<'a> { fn auto_color(&mut self) -> Color32 { let i = self.next_auto_color_idx; self.next_auto_color_idx += 1; - let golden_ratio = (5.0_f32.sqrt() - 1.0) / 2.0; // 0.61803398875 + let golden_ratio = std::f32::consts::GOLDEN_RATIO - 1.0; // 0.61803398875 let h = i as f32 * golden_ratio; Hsva::new(h, 0.85, 0.5, 1.0).into() // TODO(#165): OkLab or some other perspective color space } diff --git a/rust-toolchain b/rust-toolchain index ce5b5098..7fb2669f 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -5,6 +5,6 @@ # to the user in the error, instead of "error: invalid channel name '[toolchain]'". [toolchain] -channel = "1.92.0" +channel = "1.95.0" components = ["rustfmt", "clippy"] targets = ["wasm32-unknown-unknown"] diff --git a/scripts/check.sh b/scripts/check.sh index 640f31da..ee92ad51 100755 --- a/scripts/check.sh +++ b/scripts/check.sh @@ -9,7 +9,7 @@ set -x # Checks all tests, lints etc. # Basically does what the CI does. -cargo +1.92.0 install --quiet typos-cli +cargo +1.95.0 install --quiet typos-cli export RUSTFLAGS="-D warnings" export RUSTDOCFLAGS="-D warnings" # https://github.com/emilk/egui/pull/1454 diff --git a/scripts/clippy_wasm/clippy.toml b/scripts/clippy_wasm/clippy.toml index 1feb2bc8..920856ce 100644 --- a/scripts/clippy_wasm/clippy.toml +++ b/scripts/clippy_wasm/clippy.toml @@ -8,7 +8,7 @@ # ----------------------------------------------------------------------------- # Section identical to the main clippy.toml: -msrv = "1.92" +msrv = "1.95" allow-unwrap-in-tests = true