1
0
mirror of https://github.com/emilk/egui.git synced 2026-08-29 04:40:03 -04:00

Enable the clippy::pedantic lint group (#8429)

Instead of opting in to pedantic lints one by one, enable the whole
group and opt out of the noisy ones.

64% of the pedantic lints were already listed individually. This deletes
90 explicit lint lines, enables 51 pedantic lints we never listed, and
picks up new pedantic lints for free. Each opt-out carries its hit
count, so the cost of turning one back on is visible.

`restriction` and `nursery` stay opt-in per lint.

Stacked on top of #8430, which fixes the one real bug the new lints
found.

* [x] I have followed the instructions in the PR template

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Emil Ernerfeldt
2026-08-17 21:55:53 -07:00
committed by GitHub
parent 9bb36b0ac2
commit 34b39d564b
12 changed files with 97 additions and 159 deletions

View File

@@ -180,138 +180,62 @@ all = "warn"
# See also clippy.toml # See also clippy.toml
[workspace.lints.clippy] [workspace.lints.clippy]
all = { level = "warn", priority = -1 } all = { level = "warn", priority = -1 }
pedantic = { level = "warn", priority = -1 }
allow_attributes = "warn" allow_attributes = "warn"
as_ptr_cast_mut = "warn" as_ptr_cast_mut = "warn"
bool_to_int_with_if = "warn"
branches_sharing_code = "warn" branches_sharing_code = "warn"
checked_conversions = "warn"
clear_with_drain = "warn" clear_with_drain = "warn"
clone_on_ref_ptr = "warn" clone_on_ref_ptr = "warn"
cloned_instead_of_copied = "warn"
coerce_container_to_any = "warn" coerce_container_to_any = "warn"
dbg_macro = "warn" dbg_macro = "warn"
debug_assert_with_mut_call = "warn" debug_assert_with_mut_call = "warn"
decimal_bitwise_operands = "warn"
default_union_representation = "warn" default_union_representation = "warn"
derive_partial_eq_without_eq = "warn" derive_partial_eq_without_eq = "warn"
disallowed_script_idents = "warn" # See clippy.toml disallowed_script_idents = "warn" # See clippy.toml
doc_broken_link = "warn"
doc_comment_double_space_linebreaks = "warn"
doc_include_without_cfg = "warn" doc_include_without_cfg = "warn"
doc_link_with_quotes = "warn"
doc_markdown = "warn"
duration_suboptimal_units = "warn"
elidable_lifetime_names = "warn"
empty_enum_variants_with_brackets = "warn" empty_enum_variants_with_brackets = "warn"
empty_enums = "warn"
enum_glob_use = "warn"
equatable_if_let = "warn" equatable_if_let = "warn"
exit = "warn" exit = "warn"
expl_impl_clone_on_copy = "warn"
explicit_deref_methods = "warn"
explicit_into_iter_loop = "warn"
explicit_iter_loop = "warn"
fallible_impl_from = "warn" fallible_impl_from = "warn"
filter_map_next = "warn"
flat_map_option = "warn"
float_cmp_const = "warn" float_cmp_const = "warn"
fn_params_excessive_bools = "warn"
fn_to_numeric_cast_any = "warn" fn_to_numeric_cast_any = "warn"
format_push_string = "warn"
from_iter_instead_of_collect = "warn"
get_unwrap = "warn" get_unwrap = "warn"
ignore_without_reason = "warn"
ignored_unit_patterns = "warn"
implicit_clone = "warn"
imprecise_flops = "warn" imprecise_flops = "warn"
inconsistent_struct_constructor = "warn"
index_refutable_slice = "warn"
inefficient_to_string = "warn"
infinite_loop = "warn" infinite_loop = "warn"
into_iter_without_iter = "warn"
invalid_upcast_comparisons = "warn"
ip_constant = "warn"
iter_filter_is_ok = "warn"
iter_filter_is_some = "warn"
iter_not_returning_iterator = "warn"
iter_on_empty_collections = "warn" iter_on_empty_collections = "warn"
iter_on_single_items = "warn" iter_on_single_items = "warn"
iter_over_hash_type = "warn" iter_over_hash_type = "warn"
iter_without_into_iter = "warn"
large_digit_groups = "warn"
large_futures = "warn"
large_include_file = "warn" large_include_file = "warn"
large_stack_arrays = "warn"
large_stack_frames = "warn" large_stack_frames = "warn"
large_types_passed_by_value = "warn"
linkedlist = "warn"
literal_string_with_formatting_args = "warn" literal_string_with_formatting_args = "warn"
lossy_float_literal = "warn" lossy_float_literal = "warn"
macro_use_imports = "warn"
manual_assert = "warn"
manual_ilog2 = "warn"
manual_instant_elapsed = "warn"
manual_is_power_of_two = "warn"
manual_is_variant_and = "warn"
manual_let_else = "warn"
manual_midpoint = "warn" # NOTE `midpoint` is often a lot slower for floats, so we have our own `emath::fast_midpoint` function.
manual_string_new = "warn"
map_err_ignore = "warn" map_err_ignore = "warn"
match_bool = "warn"
match_same_arms = "warn"
match_wild_err_arm = "warn"
match_wildcard_for_single_variants = "warn"
mem_forget = "warn" mem_forget = "warn"
mismatching_type_param_order = "warn"
missing_assert_message = "warn" missing_assert_message = "warn"
missing_errors_doc = "warn"
missing_fields_in_debug = "warn"
mut_mut = "warn"
mutex_integer = "warn" mutex_integer = "warn"
needless_continue = "warn"
needless_for_each = "warn"
needless_pass_by_ref_mut = "warn" needless_pass_by_ref_mut = "warn"
needless_pass_by_value = "warn"
needless_raw_string_hashes = "warn"
needless_type_cast = "warn" needless_type_cast = "warn"
negative_feature_names = "warn" negative_feature_names = "warn"
non_std_lazy_statics = "warn"
non_zero_suggestions = "warn" non_zero_suggestions = "warn"
nonstandard_macro_braces = "warn" nonstandard_macro_braces = "warn"
option_as_ref_cloned = "warn"
option_option = "warn"
or_fun_call = "warn" or_fun_call = "warn"
path_buf_push_overwrite = "warn" path_buf_push_overwrite = "warn"
pathbuf_init_then_push = "warn" pathbuf_init_then_push = "warn"
precedence_bits = "warn" precedence_bits = "warn"
print_stderr = "warn" print_stderr = "warn"
print_stdout = "warn" print_stdout = "warn"
ptr_as_ptr = "warn"
ptr_cast_constness = "warn"
pub_underscore_fields = "warn"
pub_without_shorthand = "warn" pub_without_shorthand = "warn"
rc_mutex = "warn" rc_mutex = "warn"
redundant_type_annotations = "warn" redundant_type_annotations = "warn"
ref_as_ptr = "warn"
ref_option = "warn"
ref_option_ref = "warn"
ref_patterns = "warn" ref_patterns = "warn"
rest_pat_in_fully_bound_structs = "warn" rest_pat_in_fully_bound_structs = "warn"
return_and_then = "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" set_contains_or_insert = "warn"
single_char_pattern = "warn"
single_match_else = "warn"
single_option_map = "warn" single_option_map = "warn"
std_instead_of_core = "warn" std_instead_of_core = "warn"
str_split_at_newline = "warn"
str_to_string = "warn" str_to_string = "warn"
string_add = "warn" string_add = "warn"
string_add_assign = "warn"
string_lit_as_bytes = "warn" string_lit_as_bytes = "warn"
string_lit_chars_any = "warn" string_lit_chars_any = "warn"
suspicious_xor_used_as_pow = "warn" suspicious_xor_used_as_pow = "warn"
@@ -319,52 +243,58 @@ todo = "warn"
too_long_first_doc_paragraph = "warn" too_long_first_doc_paragraph = "warn"
trailing_empty_array = "warn" trailing_empty_array = "warn"
trait_duplication_in_bounds = "warn" trait_duplication_in_bounds = "warn"
transmute_ptr_to_ptr = "warn"
tuple_array_conversions = "warn" tuple_array_conversions = "warn"
unchecked_time_subtraction = "warn"
undocumented_unsafe_blocks = "warn" undocumented_unsafe_blocks = "warn"
unimplemented = "warn" unimplemented = "warn"
uninhabited_references = "warn" uninhabited_references = "warn"
uninlined_format_args = "warn"
unnecessary_box_returns = "warn"
unnecessary_debug_formatting = "warn"
unnecessary_literal_bound = "warn"
unnecessary_safety_comment = "warn" unnecessary_safety_comment = "warn"
unnecessary_safety_doc = "warn" unnecessary_safety_doc = "warn"
unnecessary_self_imports = "warn" unnecessary_self_imports = "warn"
unnecessary_semicolon = "warn"
unnecessary_struct_initialization = "warn" unnecessary_struct_initialization = "warn"
unnecessary_trailing_comma = "warn"
unnecessary_wraps = "warn"
unnested_or_patterns = "warn"
unused_async = "warn"
unused_peekable = "warn" unused_peekable = "warn"
unused_rounding = "warn" unused_rounding = "warn"
unused_self = "warn"
unused_trait_names = "warn" unused_trait_names = "warn"
unwrap_used = "warn" unwrap_used = "warn"
use_self = "warn" use_self = "warn"
useless_let_if_seq = "warn" useless_let_if_seq = "warn"
verbose_file_reads = "warn" verbose_file_reads = "warn"
wildcard_dependencies = "warn" wildcard_dependencies = "warn"
zero_sized_map_values = "warn"
# TODO(emilk): maybe enable more of these lints? # Pedantic lints we opt out of, with the number of hits at the time we enabled `pedantic`:
# NOTE: these are all in `pedantic`/`restriction`/`nursery`, so the `allow` is a no-op today. cast_lossless = "allow" # 204 hits
# We keep them to record our intent in case we ever enable those groups. cast_possible_truncation = "allow" # 287 hits
cast_possible_wrap = "allow" cast_possible_wrap = "allow" # 43 hits
cast_precision_loss = "allow" # 200 hits
cast_sign_loss = "allow" # 98 hits
comparison_chain = "allow" comparison_chain = "allow"
default_trait_access = "allow" # 278 hits
float_cmp = "allow" # exact float comparisons are usually intentional (`float_cmp_const` is still on)
inline_always = "allow" # 271 hits; we know what we are doing
items_after_statements = "allow" # 82 hits
many_single_char_names = "allow" # `r, g, b, a` and `h, s, v` are fine
missing_panics_doc = "allow" # 68 hits
must_use_candidate = "allow" # 1169 hits
redundant_closure_for_method_calls = "allow" # 89 hits
return_self_not_must_use = "allow" # 246 hits
should_panic_without_expect = "allow" should_panic_without_expect = "allow"
similar_names = "allow" # too many false positives, e.g. `encoder`/`encoded`
struct_excessive_bools = "allow" # 32 hits
struct_field_names = "allow" # 23 hits
too_many_lines = "allow" too_many_lines = "allow"
trivially_copy_pass_by_ref = "allow" # 119 hits
unreadable_literal = "allow" # 513 hits
used_underscore_binding = "allow" # 25 hits
# These are meh: # These are meh:
assigning_clones = "allow" # No please assigning_clones = "allow" # No please
cast_possible_truncation = "allow" # too many hits
let_underscore_must_use = "allow"
let_underscore_untyped = "allow"
manual_range_contains = "allow" # this one is just worse imho manual_range_contains = "allow" # this one is just worse imho
map_unwrap_or = "allow" # so is this one map_unwrap_or = "allow" # so is this one
wildcard_imports = "allow" # `use crate::*` is useful to avoid merge conflicts when adding/removing imports
# NOTE: these are in `restriction`/`nursery`, so the `allow` is a no-op today.
# We keep them to record our intent in case we ever enable those groups.
let_underscore_must_use = "allow"
let_underscore_untyped = "allow"
self_named_module_files = "allow" # Disabled waiting on https://github.com/rust-lang/rust-clippy/issues/9602 self_named_module_files = "allow" # Disabled waiting on https://github.com/rust-lang/rust-clippy/issues/9602
significant_drop_tightening = "allow" # Too many false positives significant_drop_tightening = "allow" # Too many false positives
wildcard_imports = "allow" # `use crate::*` is useful to avoid merge conflicts when adding/removing imports

View File

@@ -41,7 +41,6 @@ impl Hsva {
/// From linear RGBA with premultiplied alpha /// From linear RGBA with premultiplied alpha
#[inline] #[inline]
pub fn from_rgba_premultiplied(r: f32, g: f32, b: f32, a: f32) -> Self { pub fn from_rgba_premultiplied(r: f32, g: f32, b: f32, a: f32) -> Self {
#![expect(clippy::many_single_char_names)]
if a <= 0.0 { if a <= 0.0 {
if r == 0.0 && b == 0.0 && a == 0.0 { if r == 0.0 && b == 0.0 && a == 0.0 {
Self::default() Self::default()
@@ -57,7 +56,6 @@ impl Hsva {
/// From linear RGBA without premultiplied alpha /// From linear RGBA without premultiplied alpha
#[inline] #[inline]
pub fn from_rgba_unmultiplied(r: f32, g: f32, b: f32, a: f32) -> Self { pub fn from_rgba_unmultiplied(r: f32, g: f32, b: f32, a: f32) -> Self {
#![expect(clippy::many_single_char_names)]
let (h, s, v) = hsv_from_rgb([r, g, b]); let (h, s, v) = hsv_from_rgb([r, g, b]);
Self { h, s, v, a } Self { h, s, v, a }
} }
@@ -189,7 +187,6 @@ impl From<Color32> for Hsva {
/// All ranges in 0-1, rgb is linear. /// All ranges in 0-1, rgb is linear.
#[inline] #[inline]
pub fn hsv_from_rgb([r, g, b]: [f32; 3]) -> (f32, f32, f32) { pub fn hsv_from_rgb([r, g, b]: [f32; 3]) -> (f32, f32, f32) {
#![expect(clippy::many_single_char_names)]
let min = r.min(g.min(b)); let min = r.min(g.min(b));
let max = r.max(g.max(b)); // value let max = r.max(g.max(b)); // value
@@ -213,7 +210,6 @@ pub fn hsv_from_rgb([r, g, b]: [f32; 3]) -> (f32, f32, f32) {
/// All ranges in 0-1, rgb is linear. /// All ranges in 0-1, rgb is linear.
#[inline] #[inline]
pub fn rgb_from_hsv((h, s, v): (f32, f32, f32)) -> [f32; 3] { pub fn rgb_from_hsv((h, s, v): (f32, f32, f32)) -> [f32; 3] {
#![expect(clippy::many_single_char_names)]
let h = (h.fract() + 1.0).fract(); // wrap let h = (h.fract() + 1.0).fract(); // wrap
let s = s.clamp(0.0, 1.0); let s = s.clamp(0.0, 1.0);

View File

@@ -161,7 +161,8 @@ fn set_app_icon_windows(icon_data: &IconData) -> AppIconStatus {
if icon_big.is_null() { if icon_big.is_null() {
log::warn!("Failed to create HICON (for big icon) from embedded png data."); log::warn!("Failed to create HICON (for big icon) from embedded png data.");
return AppIconStatus::NotSetIgnored; // We could try independently with the small icon but what's the point, it would look bad! return AppIconStatus::NotSetIgnored; // We could try independently with the small icon but what's the point, it would look bad!
} else { }
// SAFETY: Unsafe WinApi function, takes objects previously created with WinAPI, all checked for null prior. // SAFETY: Unsafe WinApi function, takes objects previously created with WinAPI, all checked for null prior.
unsafe { unsafe {
SendMessageW( SendMessageW(
@@ -172,7 +173,6 @@ fn set_app_icon_windows(icon_data: &IconData) -> AppIconStatus {
); );
} }
} }
}
{ {
// SAFETY: WinAPI getter function with no known side effects. // SAFETY: WinAPI getter function with no known side effects.
let icon_size_small = unsafe { GetSystemMetrics(SM_CXSMICON) }; let icon_size_small = unsafe { GetSystemMetrics(SM_CXSMICON) };
@@ -180,7 +180,8 @@ fn set_app_icon_windows(icon_data: &IconData) -> AppIconStatus {
if icon_small.is_null() { if icon_small.is_null() {
log::warn!("Failed to create HICON (for small icon) from embedded png data."); log::warn!("Failed to create HICON (for small icon) from embedded png data.");
return AppIconStatus::NotSetIgnored; return AppIconStatus::NotSetIgnored;
} else { }
// SAFETY: Unsafe WinApi function, takes objects previously created with WinAPI, all checked for null prior. // SAFETY: Unsafe WinApi function, takes objects previously created with WinAPI, all checked for null prior.
unsafe { unsafe {
SendMessageW( SendMessageW(
@@ -191,7 +192,6 @@ fn set_app_icon_windows(icon_data: &IconData) -> AppIconStatus {
); );
} }
} }
}
// It _probably_ worked out. // It _probably_ worked out.
AppIconStatus::Set AppIconStatus::Set

View File

@@ -67,7 +67,7 @@ fn roaming_appdata() -> Option<PathBuf> {
&FOLDERID_RoamingAppData, &FOLDERID_RoamingAppData,
KF_FLAG_DONT_VERIFY as u32, KF_FLAG_DONT_VERIFY as u32,
core::ptr::null_mut(), core::ptr::null_mut(),
&mut path_raw, &raw mut path_raw,
) )
}; };

View File

@@ -1761,11 +1761,11 @@ impl Context {
.get(&id) .get(&id)
.map(|v| v.repaint.cumulative_frame_nr) .map(|v| v.repaint.cumulative_frame_nr)
.unwrap_or_else(|| { .unwrap_or_else(|| {
if cfg!(debug_assertions) { debug_assert!(
panic!("cumulative_frame_nr_for failed to find the viewport {id:?}"); false,
} else { "cumulative_frame_nr_for failed to find the viewport {id:?}"
);
0 0
}
}) })
}) })
} }

View File

@@ -41,6 +41,13 @@ impl<T: core::hash::Hash + core::fmt::Debug> AsId for T {}
/// This is niche-optimized to that `Option<Id>` is the same size as `Id`. /// This is niche-optimized to that `Option<Id>` is the same size as `Id`.
#[derive(Clone, Copy, Hash, Eq, PartialEq)] #[derive(Clone, Copy, Hash, Eq, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
#[cfg_attr(
feature = "serde",
expect(
clippy::unsafe_derive_deserialize,
reason = "`from_high_entropy_bits` is only `unsafe` about entropy, not memory safety"
)
)]
pub struct Id(NonZeroU64); pub struct Id(NonZeroU64);
impl nohash_hasher::IsEnabled for Id {} impl nohash_hasher::IsEnabled for Id {}

View File

@@ -118,15 +118,15 @@ impl<'a> Parser<'a> {
{ {
let language = &language_start[..newline]; let language = &language_start[..newline];
let code_start = &language_start[newline + 1..]; let code_start = &language_start[newline + 1..];
if let Some(end) = code_start.find("\n```") { return if let Some(end) = code_start.find("\n```") {
let code = &code_start[..end].trim(); let code = &code_start[..end].trim();
self.s = &code_start[end + 4..]; self.s = &code_start[end + 4..];
self.start_of_line = false; self.start_of_line = false;
return Some(Item::CodeBlock(language, code)); Some(Item::CodeBlock(language, code))
} else { } else {
self.s = ""; self.s = "";
return Some(Item::CodeBlock(language, code_start)); Some(Item::CodeBlock(language, code_start))
} };
} }
None None
} }
@@ -138,18 +138,18 @@ impl<'a> Parser<'a> {
self.start_of_line = false; self.start_of_line = false;
self.style.code = true; self.style.code = true;
let rest_of_line = &self.s[..self.s.find('\n').unwrap_or(self.s.len())]; let rest_of_line = &self.s[..self.s.find('\n').unwrap_or(self.s.len())];
if let Some(end) = rest_of_line.find('`') { return if let Some(end) = rest_of_line.find('`') {
let item = Item::Text(self.style, &self.s[..end]); let item = Item::Text(self.style, &self.s[..end]);
self.s = &self.s[end + 1..]; self.s = &self.s[end + 1..];
self.style.code = false; self.style.code = false;
return Some(item); Some(item)
} else { } else {
let end = rest_of_line.len(); let end = rest_of_line.len();
let item = Item::Text(self.style, rest_of_line); let item = Item::Text(self.style, rest_of_line);
self.s = &self.s[end..]; self.s = &self.s[end..];
self.style.code = false; self.style.code = false;
return Some(item); Some(item)
} };
} }
None None
} }

View File

@@ -210,6 +210,13 @@ impl SyntectTheme {
derive(serde::Deserialize, serde::Serialize), derive(serde::Deserialize, serde::Serialize),
serde(default) serde(default)
)] )]
#[cfg_attr(
all(feature = "serde", not(feature = "syntect")),
expect(
clippy::unsafe_derive_deserialize,
reason = "the `enum_map!` macro expands to `unsafe` code"
)
)]
pub struct CodeTheme { pub struct CodeTheme {
dark_mode: bool, dark_mode: bool,

View File

@@ -247,16 +247,16 @@ impl<'a, State> Harness<'a, State> {
pub fn step(&mut self) { pub fn step(&mut self) {
let events = core::mem::take(&mut *self.queued_events.lock()); let events = core::mem::take(&mut *self.queued_events.lock());
if events.is_empty() { if events.is_empty() {
self._step(false); self.step_impl(false);
} }
for event in events { for event in events {
self.input.events.push(event); self.input.events.push(event);
self._step(false); self.step_impl(false);
} }
} }
/// Run a single step. This will not process any events. /// Run a single step. This will not process any events.
fn _step(&mut self, sizing_pass: bool) { fn step_impl(&mut self, sizing_pass: bool) {
self.input.predicted_dt = self.step_dt; self.input.predicted_dt = self.step_dt;
let mut output = self.ctx.run_ui(self.input.take(), |ui| { let mut output = self.ctx.run_ui(self.input.take(), |ui| {
@@ -297,7 +297,7 @@ impl<'a, State> Harness<'a, State> {
/// [`Harness::new_ui`] / [`Harness::new_ui_state`] or /// [`Harness::new_ui`] / [`Harness::new_ui_state`] or
/// [`HarnessBuilder::build_ui`] / [`HarnessBuilder::build_ui_state`]. /// [`HarnessBuilder::build_ui`] / [`HarnessBuilder::build_ui_state`].
pub fn fit_contents(&mut self) { pub fn fit_contents(&mut self) {
self._step(true); self.step_impl(true);
// Calculate size including all content (main UI + popups + tooltips) // Calculate size including all content (main UI + popups + tooltips)
if let Some(rect) = self.compute_total_rect_with_popups() { if let Some(rect) = self.compute_total_rect_with_popups() {
@@ -333,7 +333,7 @@ impl<'a, State> Harness<'a, State> {
} }
} }
fn _try_run(&mut self, sleep: bool) -> Result<u64, ExceededMaxStepsError> { fn try_run_impl(&mut self, sleep: bool) -> Result<u64, ExceededMaxStepsError> {
let mut steps = 0; let mut steps = 0;
loop { loop {
steps += 1; steps += 1;
@@ -374,7 +374,7 @@ impl<'a, State> Harness<'a, State> {
/// - [`Harness::run_steps`]. /// - [`Harness::run_steps`].
/// - [`Harness::try_run_realtime`]. /// - [`Harness::try_run_realtime`].
pub fn try_run(&mut self) -> Result<u64, ExceededMaxStepsError> { pub fn try_run(&mut self) -> Result<u64, ExceededMaxStepsError> {
self._try_run(false) self.try_run_impl(false)
} }
/// Run until /// Run until
@@ -414,7 +414,7 @@ impl<'a, State> Harness<'a, State> {
/// - [`Harness::run_steps`]. /// - [`Harness::run_steps`].
/// - [`Harness::try_run`]. /// - [`Harness::try_run`].
pub fn try_run_realtime(&mut self) -> Result<u64, ExceededMaxStepsError> { pub fn try_run_realtime(&mut self) -> Result<u64, ExceededMaxStepsError> {
self._try_run(true) self.try_run_impl(true)
} }
/// Run a number of steps. /// Run a number of steps.

View File

@@ -535,31 +535,31 @@ fn try_image_snapshot_options_impl(
Ok(image) => image.to_rgba8(), Ok(image) => image.to_rgba8(),
Err(err) => { Err(err) => {
// No previous snapshot - probably a new test. // No previous snapshot - probably a new test.
if mode.is_update() { return if mode.is_update() {
return update_snapshot(); update_snapshot()
} else { } else {
write_new_png()?; write_new_png()?;
return Err(SnapshotError::OpenSnapshot { Err(SnapshotError::OpenSnapshot {
path: snapshot_path.clone(), path: snapshot_path.clone(),
err, err,
}); })
} };
} }
}; };
if previous.dimensions() != new.dimensions() { if previous.dimensions() != new.dimensions() {
if mode.is_update() { return if mode.is_update() {
return update_snapshot(); update_snapshot()
} else { } else {
write_new_png()?; write_new_png()?;
return Err(SnapshotError::SizeMismatch { Err(SnapshotError::SizeMismatch {
name, name,
expected: previous.dimensions(), expected: previous.dimensions(),
actual: new.dimensions(), actual: new.dimensions(),
}); })
} };
} }
// Compare existing image to the new one: // Compare existing image to the new one:

View File

@@ -1,5 +1,3 @@
#![expect(clippy::many_single_char_names)]
use core::ops::Range; use core::ops::Range;
use crate::{Color32, PathShape, PathStroke, Shape}; use crate::{Color32, PathShape, PathStroke, Shape};

View File

@@ -1519,14 +1519,14 @@ impl Tessellator {
if stroke.is_empty() { if stroke.is_empty() {
return; // we are done return; // we are done
} else { }
// we still need to do the stroke // we still need to do the stroke
fill = Color32::TRANSPARENT; // don't fill again below fill = Color32::TRANSPARENT; // don't fill again below
break; break;
} }
} }
} }
}
let path_stroke = PathStroke::from(stroke).outside(); let path_stroke = PathStroke::from(stroke).outside();
self.scratchpad_path.clear(); self.scratchpad_path.clear();