1
0
mirror of https://github.com/emilk/egui.git synced 2026-08-30 13:20:05 -04:00

Forbid uses of unwrap() in the code (#7795)

This commit is contained in:
Emil Ernerfeldt
2025-12-19 20:34:18 +01:00
committed by GitHub
parent 646fea2133
commit 7fe58bbfd4
44 changed files with 120 additions and 64 deletions

View File

@@ -28,6 +28,7 @@ pub struct CacheStorage {
impl CacheStorage {
pub fn cache<Cache: CacheTrait + Default>(&mut self) -> &mut Cache {
#[expect(clippy::unwrap_used)]
self.caches
.entry(std::any::TypeId::of::<Cache>())
.or_insert_with(|| Box::<Cache>::default())

View File

@@ -722,6 +722,7 @@ fn automatic_area_position(ctx: &Context, constrain_rect: Rect, layer_id: LayerI
let mut column_bbs = vec![existing[0]];
for &rect in &existing {
#[expect(clippy::unwrap_used)]
let current_column_bb = column_bbs.last_mut().unwrap();
if rect.left() < current_column_bb.right() {
// same column
@@ -752,6 +753,7 @@ fn automatic_area_position(ctx: &Context, constrain_rect: Rect, layer_id: LayerI
}
// Maybe we can fit a new column?
#[expect(clippy::unwrap_used)]
let rightmost = column_bbs.last().unwrap().right();
if rightmost + 200.0 < constrain_rect.right() {
return pos2(rightmost + spacing, top);

View File

@@ -444,11 +444,8 @@ impl SubMenu {
let mut menu_config = self.config.unwrap_or_else(|| parent_config.clone());
menu_config.bar = false;
let menu_root_response = ui
.ctx()
.read_response(menu_id)
// Since we are a child of that ui, this should always exist
.unwrap();
#[expect(clippy::unwrap_used)] // Since we are a child of that ui, this should always exist
let menu_root_response = ui.ctx().read_response(menu_id).unwrap();
let hover_pos = ui.ctx().pointer_hover_pos();

View File

@@ -584,8 +584,8 @@ impl ContextImpl {
}
}
fn accesskit_node_builder(&mut self, id: Id) -> &mut accesskit::Node {
let state = self.viewport().this_pass.accesskit_state.as_mut().unwrap();
fn accesskit_node_builder(&mut self, id: Id) -> Option<&mut accesskit::Node> {
let state = self.viewport().this_pass.accesskit_state.as_mut()?;
let builders = &mut state.nodes;
if let std::collections::hash_map::Entry::Vacant(entry) = builders.entry(id) {
@@ -611,11 +611,11 @@ impl ContextImpl {
let parent_id = find_accesskit_parent(&state.parent_map, builders, id)
.unwrap_or_else(crate::accesskit_root_id);
let parent_builder = builders.get_mut(&parent_id).unwrap();
let parent_builder = builders.get_mut(&parent_id)?;
parent_builder.push_child(id.accesskit_id());
}
builders.get_mut(&id).unwrap()
builders.get_mut(&id)
}
fn pixels_per_point(&mut self) -> f32 {
@@ -3639,14 +3639,7 @@ impl Context {
id: Id,
writer: impl FnOnce(&mut accesskit::Node) -> R,
) -> Option<R> {
self.write(|ctx| {
ctx.viewport()
.this_pass
.accesskit_state
.is_some()
.then(|| ctx.accesskit_node_builder(id))
.map(writer)
})
self.write(|ctx| ctx.accesskit_node_builder(id).map(writer))
}
pub(crate) fn register_accesskit_parent(&self, id: Id, parent_id: Id) {

View File

@@ -361,7 +361,10 @@ fn hit_test_on_close(close: &[WidgetRect], pos: Pos2) -> WidgetHits {
(Some(hit_click), Some(hit_drag)) => {
// We have a perfect hit on both click and drag. Which is the topmost?
#[expect(clippy::unwrap_used)]
let click_idx = close.iter().position(|w| *w == hit_click).unwrap();
#[expect(clippy::unwrap_used)]
let drag_idx = close.iter().position(|w| *w == hit_drag).unwrap();
let click_is_on_top_of_drag = drag_idx < click_idx;

View File

@@ -1551,11 +1551,9 @@ impl InputState {
options: _,
} = self;
ui.style_mut()
.text_styles
.get_mut(&crate::TextStyle::Body)
.unwrap()
.family = crate::FontFamily::Monospace;
if let Some(style) = ui.style_mut().text_styles.get_mut(&crate::TextStyle::Body) {
style.family = crate::FontFamily::Monospace;
}
ui.collapsing("Raw Input", |ui| raw.ui(ui));

View File

@@ -288,6 +288,7 @@ impl TouchState {
// touch individually, and then calculate the average of all individual changes in
// direction. But this approach cannot be implemented locally in this method, making
// everything a bit more complicated.
#[expect(clippy::unwrap_used)] // guarded against already
let first_touch = self.active_touches.values().next().unwrap();
state.heading = (state.avg_pos - first_touch.pos).angle();
@@ -323,13 +324,14 @@ enum PinchType {
impl PinchType {
fn classify(touches: &BTreeMap<TouchId, ActiveTouch>) -> Self {
#![expect(clippy::unwrap_used)]
// For non-proportional 2d zooming:
// If the user is pinching with two fingers that have roughly the same Y coord,
// then the Y zoom is unstable and should be 1.
// Similarly, if the fingers are directly above/below each other,
// we should only zoom on the Y axis.
// If the fingers are roughly on a diagonal, we revert to the proportional zooming.
if touches.len() == 2 {
let mut touches = touches.values();
let t0 = touches.next().unwrap().pos;

View File

@@ -306,6 +306,8 @@ impl Default for Options {
zoom_with_keyboard: true,
tessellation_options: Default::default(),
repaint_on_widget_change: false,
#[expect(clippy::unwrap_used)]
max_passes: NonZeroUsize::new(2).unwrap(),
screen_reader: false,
warn_on_id_clash: cfg!(debug_assertions),

View File

@@ -142,7 +142,9 @@ impl Element {
Self::Value {
value: Box::new(t),
clone_fn: |x| {
let x = x.downcast_ref::<T>().unwrap(); // This unwrap will never panic, because we always construct this type using this `new` function and because we return &mut reference only with this type `T`, so type cannot change.
// This unwrap will never panic, because we always construct this type using this `new` function and because we return &mut reference only with this type `T`, so type cannot change.
#[expect(clippy::unwrap_used)]
let x = x.downcast_ref::<T>().unwrap();
Box::new(x.clone())
},
#[cfg(feature = "persistence")]
@@ -156,12 +158,16 @@ impl Element {
Self::Value {
value: Box::new(t),
clone_fn: |x| {
let x = x.downcast_ref::<T>().unwrap(); // This unwrap will never panic, because we always construct this type using this `new` function and because we return &mut reference only with this type `T`, so type cannot change.
// This unwrap will never panic, because we always construct this type using this `new` function and because we return &mut reference only with this type `T`, so type cannot change.
#[expect(clippy::unwrap_used)]
let x = x.downcast_ref::<T>().unwrap();
Box::new(x.clone())
},
#[cfg(feature = "persistence")]
serialize_fn: Some(|x| {
let x = x.downcast_ref::<T>().unwrap(); // This will never panic too, for same reason.
// This will never panic too, for same reason.
#[expect(clippy::unwrap_used)]
let x = x.downcast_ref::<T>().unwrap();
ron::to_string(x).ok()
}),
}
@@ -209,7 +215,9 @@ impl Element {
}
match self {
Self::Value { value, .. } => value.downcast_mut().unwrap(), // This unwrap will never panic because we already converted object to required type
// This unwrap will never panic because we already converted object to required type
#[expect(clippy::unwrap_used)]
Self::Value { value, .. } => value.downcast_mut().unwrap(),
Self::Serialized(_) => unreachable!(),
}
}
@@ -238,7 +246,9 @@ impl Element {
}
match self {
Self::Value { value, .. } => value.downcast_mut().unwrap(), // This unwrap will never panic because we already converted object to required type
// This unwrap will never panic because we already converted object to required type
#[expect(clippy::unwrap_used)]
Self::Value { value, .. } => value.downcast_mut().unwrap(),
Self::Serialized(_) => unreachable!(),
}
}
@@ -436,10 +446,14 @@ impl IdTypeMap {
let hash = hash(TypeId::of::<T>(), id);
use std::collections::hash_map::Entry;
match self.map.entry(hash) {
Entry::Vacant(vacant) => vacant
.insert(Element::new_temp(insert_with()))
.get_mut_temp()
.unwrap(), // this unwrap will never panic, because we insert correct type right now
Entry::Vacant(vacant) => {
// this unwrap will never panic, because we insert correct type right now
#[expect(clippy::unwrap_used)]
vacant
.insert(Element::new_temp(insert_with()))
.get_mut_temp()
.unwrap()
}
Entry::Occupied(occupied) => {
occupied.into_mut().get_temp_mut_or_insert_with(insert_with)
}
@@ -454,10 +468,14 @@ impl IdTypeMap {
let hash = hash(TypeId::of::<T>(), id);
use std::collections::hash_map::Entry;
match self.map.entry(hash) {
Entry::Vacant(vacant) => vacant
.insert(Element::new_persisted(insert_with()))
.get_mut_persisted()
.unwrap(), // this unwrap will never panic, because we insert correct type right now
Entry::Vacant(vacant) => {
// this unwrap will never panic, because we insert correct type right now
#[expect(clippy::unwrap_used)]
vacant
.insert(Element::new_persisted(insert_with()))
.get_mut_persisted()
.unwrap()
}
Entry::Occupied(occupied) => occupied
.into_mut()
.get_persisted_mut_or_insert_with(insert_with),

View File

@@ -135,6 +135,7 @@ where
self.flux = None;
if self.undos.back() == Some(current_state) {
#[expect(clippy::unwrap_used)] // we just checked that undos is not empty
self.redos.push(self.undos.pop_back().unwrap());
} else {
self.redos.push(current_state.clone());

View File

@@ -827,8 +827,7 @@ impl TextEdit<'_> {
hint_text_str.as_str(),
)
});
} else if selection_changed {
let cursor_range = cursor_range.unwrap();
} else if selection_changed && let Some(cursor_range) = cursor_range {
let char_range = cursor_range.primary.index..=cursor_range.secondary.index;
let info = WidgetInfo::text_selection_changed(
ui.is_enabled(),