diff --git a/Cargo.toml b/Cargo.toml index ccd73410..e496437e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -102,6 +102,7 @@ missing_crate_level_docs = "warn" # See also clippy.toml [workspace.lints.clippy] allow_attributes = "warn" +allow_attributes_without_reason = "warn" as_ptr_cast_mut = "warn" await_holding_lock = "warn" bool_to_int_with_if = "warn" @@ -133,6 +134,7 @@ expl_impl_clone_on_copy = "warn" explicit_deref_methods = "warn" explicit_into_iter_loop = "warn" explicit_iter_loop = "warn" +expect_used = "warn" fallible_impl_from = "warn" filter_map_next = "warn" flat_map_option = "warn" @@ -206,6 +208,7 @@ non_zero_suggestions = "warn" nonstandard_macro_braces = "warn" option_as_ref_cloned = "warn" option_option = "warn" +or_fun_call = "warn" path_buf_push_overwrite = "warn" pathbuf_init_then_push = "warn" precedence_bits = "warn" diff --git a/demo/src/app.rs b/demo/src/app.rs index 5458c44f..8a2d1038 100644 --- a/demo/src/app.rs +++ b/demo/src/app.rs @@ -131,6 +131,7 @@ impl DemoGallery { ui.horizontal(|ui| { ui.label("Tags:"); + #[expect(clippy::expect_used, reason = "tags are non-empty strings")] egui_chip::ChipEditBuilder::new(",") .expect("failed to create ChipEditBuilder") .texts(example.tags()) diff --git a/egui_plot/src/items/arrows.rs b/egui_plot/src/items/arrows.rs index eecaa09b..75954404 100644 --- a/egui_plot/src/items/arrows.rs +++ b/egui_plot/src/items/arrows.rs @@ -48,7 +48,7 @@ impl<'a> Arrows<'a> { /// losing the item's state. You should make sure the name passed to /// [`Self::new`] is unique and stable for each item, or set unique and /// stable ids explicitly via [`Self::id`]. - #[expect(clippy::needless_pass_by_value)] + #[expect(clippy::needless_pass_by_value, reason = "to allow various string types")] #[inline] pub fn name(mut self, name: impl ToString) -> Self { self.base_mut().name = name.to_string(); diff --git a/egui_plot/src/items/bar_chart.rs b/egui_plot/src/items/bar_chart.rs index a5182896..10dfc768 100644 --- a/egui_plot/src/items/bar_chart.rs +++ b/egui_plot/src/items/bar_chart.rs @@ -138,7 +138,7 @@ impl BarChart { /// losing the item's state. You should make sure the name passed to /// [`Self::new`] is unique and stable for each item, or set unique and /// stable ids explicitly via [`Self::id`]. - #[expect(clippy::needless_pass_by_value)] + #[expect(clippy::needless_pass_by_value, reason = "to allow various string types")] #[inline] pub fn name(mut self, name: impl ToString) -> Self { self.base_mut().name = name.to_string(); @@ -278,7 +278,7 @@ impl Bar { } /// Name of this bar chart element. - #[expect(clippy::needless_pass_by_value)] + #[expect(clippy::needless_pass_by_value, reason = "to allow various string types")] #[inline] pub fn name(mut self, name: impl ToString) -> Self { self.name = name.to_string(); diff --git a/egui_plot/src/items/box_plot.rs b/egui_plot/src/items/box_plot.rs index 3ad9cfe2..529fc05f 100644 --- a/egui_plot/src/items/box_plot.rs +++ b/egui_plot/src/items/box_plot.rs @@ -104,7 +104,7 @@ impl BoxPlot { /// losing the item's state. You should make sure the name passed to /// [`Self::new`] is unique and stable for each item, or set unique and /// stable ids explicitly via [`Self::id`]. - #[expect(clippy::needless_pass_by_value)] + #[expect(clippy::needless_pass_by_value, reason = "to allow various string types")] #[inline] pub fn name(mut self, name: impl ToString) -> Self { self.base_mut().name = name.to_string(); @@ -279,7 +279,7 @@ impl BoxElem { } /// Name of this box element. - #[expect(clippy::needless_pass_by_value)] + #[expect(clippy::needless_pass_by_value, reason = "to allow various string types")] #[inline] pub fn name(mut self, name: impl ToString) -> Self { self.name = name.to_string(); diff --git a/egui_plot/src/items/filled_area.rs b/egui_plot/src/items/filled_area.rs index 0ecf56d8..c4ec2593 100644 --- a/egui_plot/src/items/filled_area.rs +++ b/egui_plot/src/items/filled_area.rs @@ -94,7 +94,7 @@ impl FilledArea { /// Name of this plot item. /// /// This name will show up in the plot legend, if legends are turned on. - #[expect(clippy::needless_pass_by_value)] + #[expect(clippy::needless_pass_by_value, reason = "to allow various string types")] #[inline] pub fn name(mut self, name: impl ToString) -> Self { self.base_mut().name = name.to_string(); diff --git a/egui_plot/src/items/heatmap.rs b/egui_plot/src/items/heatmap.rs index 6af0776e..bf549478 100644 --- a/egui_plot/src/items/heatmap.rs +++ b/egui_plot/src/items/heatmap.rs @@ -207,7 +207,7 @@ impl Heatmap { let i_rel: f64 = i as f64 / (resolution - 1) as f64; if i_rel == 1.0 { // last element - *color = *base_colors.last().expect("Base colors should not be empty"); + *color = base_colors[base_colors.len() - 1]; } else { let base_index_float: f64 = i_rel * (base_colors.len() - 1) as f64; let base_index: usize = base_index_float as usize; @@ -277,7 +277,7 @@ impl Heatmap { /// This name will show up in the plot legend, if legends are turned on. /// Multiple heatmaps may share the same name, in which case they will /// also share an entry in the legend. - #[expect(clippy::needless_pass_by_value)] + #[expect(clippy::needless_pass_by_value, reason = "to allow various string types")] #[inline] pub fn name(mut self, name: impl ToString) -> Self { self.name = name.to_string(); diff --git a/egui_plot/src/items/line.rs b/egui_plot/src/items/line.rs index 55596aac..f1872272 100644 --- a/egui_plot/src/items/line.rs +++ b/egui_plot/src/items/line.rs @@ -74,7 +74,7 @@ impl HLine { /// losing the item's state. You should make sure the name passed to /// [`Self::new`] is unique and stable for each item, or set unique and /// stable ids explicitly via [`Self::id`]. - #[expect(clippy::needless_pass_by_value)] + #[expect(clippy::needless_pass_by_value, reason = "to allow various string types")] #[inline] pub fn name(mut self, name: impl ToString) -> Self { self.base_mut().name = name.to_string(); @@ -209,7 +209,7 @@ impl VLine { /// losing the item's state. You should make sure the name passed to /// [`Self::new`] is unique and stable for each item, or set unique and /// stable ids explicitly via [`Self::id`]. - #[expect(clippy::needless_pass_by_value)] + #[expect(clippy::needless_pass_by_value, reason = "to allow various string types")] #[inline] pub fn name(mut self, name: impl ToString) -> Self { self.base_mut().name = name.to_string(); diff --git a/egui_plot/src/items/mod.rs b/egui_plot/src/items/mod.rs index 0eb4ed83..140804ca 100644 --- a/egui_plot/src/items/mod.rs +++ b/egui_plot/src/items/mod.rs @@ -1,5 +1,8 @@ //! Contains items that can be added to a plot at some plot coordinates. -#![expect(clippy::type_complexity)] // TODO(#163): simplify some of the callback types with type aliases +#![expect( + clippy::type_complexity, + reason = "TODO(#163): simplify some of the callback types with type aliases" +)] use std::ops::RangeInclusive; @@ -234,7 +237,7 @@ fn add_rulers_and_text( } // Text - let text = text.unwrap_or({ + let text = text.unwrap_or_else(|| { let mut text = elem.name().to_owned(); // could be empty if show_values { diff --git a/egui_plot/src/items/plot_image.rs b/egui_plot/src/items/plot_image.rs index d189a8c1..1dc7a9b6 100644 --- a/egui_plot/src/items/plot_image.rs +++ b/egui_plot/src/items/plot_image.rs @@ -91,7 +91,7 @@ impl PlotImage { /// losing the item's state. You should make sure the name passed to /// [`Self::new`] is unique and stable for each item, or set unique and /// stable ids explicitly via [`Self::id`]. - #[expect(clippy::needless_pass_by_value)] + #[expect(clippy::needless_pass_by_value, reason = "to allow various string types")] #[inline] pub fn name(mut self, name: impl ToString) -> Self { self.base_mut().name = name.to_string(); diff --git a/egui_plot/src/items/points.rs b/egui_plot/src/items/points.rs index d2e63465..7644a03a 100644 --- a/egui_plot/src/items/points.rs +++ b/egui_plot/src/items/points.rs @@ -77,7 +77,7 @@ impl<'a> Points<'a> { /// losing the item's state. You should make sure the name passed to /// [`Self::new`] is unique and stable for each item, or set unique and /// stable ids explicitly via [`Self::id`]. - #[expect(clippy::needless_pass_by_value)] + #[expect(clippy::needless_pass_by_value, reason = "to allow various string types")] #[inline] pub fn name(mut self, name: impl ToString) -> Self { self.base_mut().name = name.to_string(); diff --git a/egui_plot/src/items/polygon.rs b/egui_plot/src/items/polygon.rs index 71de8fd3..f80e0510 100644 --- a/egui_plot/src/items/polygon.rs +++ b/egui_plot/src/items/polygon.rs @@ -73,7 +73,7 @@ impl<'a> Polygon<'a> { /// losing the item's state. You should make sure the name passed to /// [`Self::new`] is unique and stable for each item, or set unique and /// stable ids explicitly via [`Self::id`]. - #[expect(clippy::needless_pass_by_value)] + #[expect(clippy::needless_pass_by_value, reason = "to allow various string types")] #[inline] pub fn name(mut self, name: impl ToString) -> Self { self.base_mut().name = name.to_string(); diff --git a/egui_plot/src/items/series.rs b/egui_plot/src/items/series.rs index 6f2be18e..95ade02e 100644 --- a/egui_plot/src/items/series.rs +++ b/egui_plot/src/items/series.rs @@ -122,7 +122,7 @@ impl<'a> Line<'a> { /// losing the item's state. You should make sure the name passed to /// [`Self::new`] is unique and stable for each item, or set unique and /// stable ids explicitly via [`Self::id`]. - #[expect(clippy::needless_pass_by_value)] + #[expect(clippy::needless_pass_by_value, reason = "to allow various string types")] #[inline] pub fn name(mut self, name: impl ToString) -> Self { self.base_mut().name = name.to_string(); @@ -201,16 +201,11 @@ impl PlotItem for Line<'_> { let default_fill_color = Rgba::from(stroke.color).to_opaque().multiply(fill_alpha).into(); let fill_color_for_point = |pos| { - if *gradient_fill && self.gradient_color.is_some() { - Rgba::from(self - .gradient_color - .clone() - .expect("Could not find gradient color callback")( - transform.value_from_position(pos), - )) - .to_opaque() - .multiply(fill_alpha) - .into() + if *gradient_fill && let Some(gradient_fallback) = &self.gradient_color { + Rgba::from(gradient_fallback(transform.value_from_position(pos))) + .to_opaque() + .multiply(fill_alpha) + .into() } else { default_fill_color } diff --git a/egui_plot/src/items/text.rs b/egui_plot/src/items/text.rs index 546f1c74..c506104a 100644 --- a/egui_plot/src/items/text.rs +++ b/egui_plot/src/items/text.rs @@ -51,7 +51,7 @@ impl Text { /// losing the item's state. You should make sure the name passed to /// [`Self::new`] is unique and stable for each item, or set unique and /// stable ids explicitly via [`Self::id`]. - #[expect(clippy::needless_pass_by_value)] + #[expect(clippy::needless_pass_by_value, reason = "to allow various string types")] #[inline] pub fn name(mut self, name: impl ToString) -> Self { self.base_mut().name = name.to_string(); diff --git a/egui_plot/src/overlays/legend.rs b/egui_plot/src/overlays/legend.rs index e393373b..ef8c0b6a 100644 --- a/egui_plot/src/overlays/legend.rs +++ b/egui_plot/src/overlays/legend.rs @@ -320,6 +320,10 @@ impl Widget for &mut LegendWidget { } let mut focus_on_item = None; + #[expect( + clippy::expect_used, + reason = "we checked that entries is not empty when creating the legend" + )] let response_union = entries .iter_mut() .map(|entry| { diff --git a/examples/borrow_points/src/app.rs b/examples/borrow_points/src/app.rs index db2ce878..0f10dbdb 100644 --- a/examples/borrow_points/src/app.rs +++ b/examples/borrow_points/src/app.rs @@ -28,7 +28,7 @@ impl BorrowPointsExample { .response } - #[expect(clippy::unused_self)] + #[expect(clippy::unused_self, reason = "required by the example template")] pub fn show_controls(&self, ui: &mut egui::Ui) -> Response { ui.scope(|_ui| {}).response } diff --git a/examples/custom_axes/src/app.rs b/examples/custom_axes/src/app.rs index 834bb4f2..24a5eecb 100644 --- a/examples/custom_axes/src/app.rs +++ b/examples/custom_axes/src/app.rs @@ -30,7 +30,7 @@ impl CustomAxesExample { Line::new("logistic fn", values) } - #[expect(clippy::needless_pass_by_value)] + #[expect(clippy::needless_pass_by_value, reason = "to allow various range types")] fn x_grid(input: GridInput) -> Vec { let mut marks = vec![]; @@ -58,7 +58,7 @@ impl CustomAxesExample { marks } - #[expect(clippy::unused_self)] + #[expect(clippy::unused_self, reason = "required by the example template")] pub fn show_plot(&self, ui: &mut egui::Ui) -> Response { const MINS_PER_DAY: f64 = CustomAxesExample::MINS_PER_DAY; const MINS_PER_H: f64 = CustomAxesExample::MINS_PER_H; @@ -137,7 +137,7 @@ impl CustomAxesExample { .response } - #[expect(clippy::unused_self)] + #[expect(clippy::unused_self, reason = "required by the example template")] pub fn show_controls(&self, ui: &mut egui::Ui) -> Response { ui.label("Zoom in on the X-axis to see hours and minutes") } diff --git a/examples/heatmap/src/app.rs b/examples/heatmap/src/app.rs index 71c39ee6..fa871d04 100644 --- a/examples/heatmap/src/app.rs +++ b/examples/heatmap/src/app.rs @@ -66,8 +66,10 @@ impl HeatmapDemo { self.palette.pop(); } }); - if ui.button("Push color").clicked() { - self.palette.push(*self.palette.last().expect("Palette is empty")); + if ui.button("Push color").clicked() + && let Some(last) = self.palette.last() + { + self.palette.push(*last); } }); ui.horizontal(|ui| { @@ -80,7 +82,7 @@ impl HeatmapDemo { .response } - #[expect(clippy::needless_pass_by_ref_mut)] + #[expect(clippy::needless_pass_by_ref_mut, reason = "to allow mutation of self")] pub fn show_plot(&mut self, ui: &mut egui::Ui) -> Response { let mut values = Vec::new(); for y in 0..self.rows { diff --git a/examples/items/src/app.rs b/examples/items/src/app.rs index c4b57847..e5617361 100644 --- a/examples/items/src/app.rs +++ b/examples/items/src/app.rs @@ -88,7 +88,7 @@ impl ItemsExample { .response } - #[expect(clippy::unused_self)] + #[expect(clippy::unused_self, reason = "required by the example template")] pub fn show_controls(&self, ui: &mut egui::Ui) -> Response { // No controls for this example ui.scope(|_ui| {}).response diff --git a/examples/plot_span/src/app.rs b/examples/plot_span/src/app.rs index dbb54844..dff9c91e 100644 --- a/examples/plot_span/src/app.rs +++ b/examples/plot_span/src/app.rs @@ -23,7 +23,7 @@ impl PlotSpanDemo { .response } - #[expect(clippy::needless_pass_by_ref_mut)] + #[expect(clippy::needless_pass_by_ref_mut, reason = "to allow mutation of self")] pub fn show_plot(&mut self, ui: &mut egui::Ui) -> Response { let mut plot = Plot::new("Span Demo"); if self.show_legend { diff --git a/examples/save_plot/src/app.rs b/examples/save_plot/src/app.rs index ac8139ef..6d5988ad 100644 --- a/examples/save_plot/src/app.rs +++ b/examples/save_plot/src/app.rs @@ -66,7 +66,7 @@ impl SavePlotExample { inner.response } - #[expect(clippy::unused_self)] + #[expect(clippy::unused_self, reason = "required by the example template")] pub fn show_controls(&self, ui: &mut egui::Ui) -> Response { let response = ui.button("Save Plot"); if response.clicked() { diff --git a/examples/save_plot/src/lib.rs b/examples/save_plot/src/lib.rs index 0750c40c..944da127 100644 --- a/examples/save_plot/src/lib.rs +++ b/examples/save_plot/src/lib.rs @@ -1,4 +1,4 @@ -#![expect(clippy::print_stderr)] +#![expect(clippy::print_stderr, reason = "example template")] #![doc = include_str!("../README.md")] use eframe::egui;