diff --git a/core/embed/rust/rustfmt.toml b/core/embed/rust/rustfmt.toml index 859f26e7c1..c1d40dc854 100644 --- a/core/embed/rust/rustfmt.toml +++ b/core/embed/rust/rustfmt.toml @@ -1,2 +1,2 @@ wrap_comments = true - +imports_granularity = "Crate" diff --git a/core/embed/rust/src/error.rs b/core/embed/rust/src/error.rs index c64f4cd3e4..fcc0ac1372 100644 --- a/core/embed/rust/src/error.rs +++ b/core/embed/rust/src/error.rs @@ -1,10 +1,11 @@ use core::convert::{Infallible, TryInto}; + use cstr_core::CStr; use crate::micropython::{ffi, obj::Obj, qstr::Qstr}; +#[allow(clippy::enum_variant_names)] // We mimic the Python exception classnames here. #[derive(Debug)] -#[allow(clippy::enum_variant_names)] pub enum Error { TypeError, OutOfRange, @@ -44,7 +45,7 @@ impl Error { } Error::ValueErrorParam(msg, param) => { if let Ok(msg) = msg.try_into() { - let args: [Obj; 2] = [msg, param]; + let args = [msg, param]; ffi::mp_obj_new_exception_args(&ffi::mp_type_ValueError, 2, args.as_ptr()) } else { ffi::mp_obj_new_exception(&ffi::mp_type_ValueError) diff --git a/core/embed/rust/src/lib.rs b/core/embed/rust/src/lib.rs index 2ad40b7b8b..147d78ac20 100644 --- a/core/embed/rust/src/lib.rs +++ b/core/embed/rust/src/lib.rs @@ -1,5 +1,6 @@ #![cfg_attr(not(test), no_std)] #![deny(clippy::all)] +#![allow(clippy::new_without_default)] #![deny(unsafe_op_in_unsafe_fn)] #![allow(dead_code)] @@ -16,14 +17,11 @@ mod trezorhal; mod ui; mod util; -#[cfg(not(feature = "test"))] -use core::panic::PanicInfo; -#[cfg(not(feature = "test"))] -use cstr_core::CStr; - #[cfg(not(feature = "test"))] #[panic_handler] -fn panic(_info: &PanicInfo) -> ! { +fn panic(_info: &core::panic::PanicInfo) -> ! { + use cstr_core::CStr; + // Although it would be ideal to use the original error message, ignoring it // lets us avoid the `fmt` machinery and its code size and is also important for // security reasons, as we do not always controls the message contents. We diff --git a/core/embed/rust/src/micropython/iter.rs b/core/embed/rust/src/micropython/iter.rs index 61da51d3d7..51dc8ff10e 100644 --- a/core/embed/rust/src/micropython/iter.rs +++ b/core/embed/rust/src/micropython/iter.rs @@ -1,10 +1,8 @@ use core::ptr; -use crate::error::Error; -use crate::micropython::obj::Obj; +use crate::{error::Error, micropython::obj::Obj}; -use super::ffi; -use super::runtime::catch_exception; +use super::{ffi, runtime::catch_exception}; pub struct IterBuf { iter_buf: ffi::mp_obj_iter_buf_t, diff --git a/core/embed/rust/src/micropython/map.rs b/core/embed/rust/src/micropython/map.rs index 81ae02d71e..ab3c13884a 100644 --- a/core/embed/rust/src/micropython/map.rs +++ b/core/embed/rust/src/micropython/map.rs @@ -121,7 +121,7 @@ impl Map { ) })? .as_mut() - .unwrap(); + .unwrap(); // `MP_MAP_LOOKUP_ADD_IF_NOT_FOUND` should always return a non-null pointer. elem.value = value; } Ok(()) diff --git a/core/embed/rust/src/micropython/obj.rs b/core/embed/rust/src/micropython/obj.rs index 28b8654705..1fe61e763e 100644 --- a/core/embed/rust/src/micropython/obj.rs +++ b/core/embed/rust/src/micropython/obj.rs @@ -1,12 +1,13 @@ -use core::convert::{TryFrom, TryInto}; -use core::num::TryFromIntError; +use core::{ + convert::{TryFrom, TryInto}, + num::TryFromIntError, +}; use cstr_core::CStr; use crate::error::Error; -use super::ffi; -use super::runtime::catch_exception; +use super::{ffi, runtime::catch_exception}; pub type Obj = ffi::mp_obj_t; pub type ObjBase = ffi::mp_obj_base_t; @@ -129,12 +130,8 @@ impl TryFrom for bool { // SAFETY: // - `obj` can be anything uPy understands. // EXCEPTION: Can call Python code (on custom instances) and therefore raise. - let result = catch_exception(|| unsafe { ffi::mp_obj_is_true(obj) })?; - if result { - Ok(true) - } else { - Ok(false) - } + let is_true = catch_exception(|| unsafe { ffi::mp_obj_is_true(obj) })?; + Ok(is_true) } } @@ -298,14 +295,14 @@ impl TryFrom<&'static CStr> for Obj { impl From for Obj { fn from(val: u8) -> Self { - // u8 will fit into smallint so no error should happen here + // `u8` will fit into smallint so no error should happen here. u32::from(val).try_into().unwrap() } } impl From for Obj { fn from(val: u16) -> Self { - // u16 will fit into smallint so no error should happen here + // `u16` will fit into smallint so no error should happen here. u32::from(val).try_into().unwrap() } } @@ -371,6 +368,18 @@ impl TryFrom for usize { } } +impl From> for Obj +where + T: Into, +{ + fn from(val: Option) -> Self { + match val { + Some(v) => v.into(), + None => Self::const_none(), + } + } +} + impl From for Error { fn from(_: TryFromIntError) -> Self { Self::OutOfRange diff --git a/core/embed/rust/src/micropython/typ.rs b/core/embed/rust/src/micropython/typ.rs index 79c7dc455d..700cf71a50 100644 --- a/core/embed/rust/src/micropython/typ.rs +++ b/core/embed/rust/src/micropython/typ.rs @@ -19,7 +19,7 @@ impl Type { } } - pub fn as_base(&'static self) -> ObjBase { + pub const fn as_base(&'static self) -> ObjBase { ObjBase { type_: self } } } diff --git a/core/embed/rust/src/protobuf/decode.rs b/core/embed/rust/src/protobuf/decode.rs index f4c65b7fd0..5419cec203 100644 --- a/core/embed/rust/src/protobuf/decode.rs +++ b/core/embed/rust/src/protobuf/decode.rs @@ -1,5 +1,7 @@ -use core::convert::{TryFrom, TryInto}; -use core::str; +use core::{ + convert::{TryFrom, TryInto}, + str, +}; use crate::{ error::Error, diff --git a/core/embed/rust/src/protobuf/defs.rs b/core/embed/rust/src/protobuf/defs.rs index f48e4fd74a..cdae0d22f2 100644 --- a/core/embed/rust/src/protobuf/defs.rs +++ b/core/embed/rust/src/protobuf/defs.rs @@ -135,19 +135,17 @@ static MSG_DEFS: &[u8] = include_bytes!(proto_def_path!("proto_msgs.data")); static NAME_DEFS: &[u8] = include_bytes!(proto_def_path!("proto_names.data")); static WIRE_DEFS: &[u8] = include_bytes!(proto_def_path!("proto_wire.data")); -pub fn find_name_by_msg_offset(msg_offset: u16) -> Result { +pub fn find_name_by_msg_offset(msg_offset: u16) -> Option { let name_defs: &[NameDef] = unsafe { slice::from_raw_parts( NAME_DEFS.as_ptr().cast(), NAME_DEFS.len() / mem::size_of::(), ) }; - name_defs .iter() .find(|def| def.msg_offset == msg_offset) .map(|def| def.msg_name) - .ok_or_else(|| Error::KeyError(msg_offset.into())) } fn find_msg_offset_by_name(msg_name: u16) -> Option { diff --git a/core/embed/rust/src/protobuf/encode.rs b/core/embed/rust/src/protobuf/encode.rs index 28f162bd5c..a1330802e9 100644 --- a/core/embed/rust/src/protobuf/encode.rs +++ b/core/embed/rust/src/protobuf/encode.rs @@ -24,11 +24,8 @@ use super::{ pub extern "C" fn protobuf_len(obj: Obj) -> Obj { let block = || { let obj = Gc::::try_from(obj)?; - let stream = &mut CounterStream { len: 0 }; - Encoder.encode_message(stream, &obj.def(), &obj)?; - stream.len.try_into() }; unsafe { util::try_or_raise(block) } diff --git a/core/embed/rust/src/protobuf/error.rs b/core/embed/rust/src/protobuf/error.rs index 1e8625e65a..68d8950d32 100644 --- a/core/embed/rust/src/protobuf/error.rs +++ b/core/embed/rust/src/protobuf/error.rs @@ -1,9 +1,8 @@ use cstr_core::CStr; -use crate::error::Error; -use crate::micropython::qstr::Qstr; +use crate::{error::Error, micropython::qstr::Qstr}; -/* XXX const version of from_bytes_with_nul_unchecked is nightly-only */ +// XXX const version of `from_bytes_with_nul_unchecked` is nightly-only. pub fn experimental_not_enabled() -> Error { let msg = diff --git a/core/embed/rust/src/protobuf/obj.rs b/core/embed/rust/src/protobuf/obj.rs index 21483eb859..d3451011bc 100644 --- a/core/embed/rust/src/protobuf/obj.rs +++ b/core/embed/rust/src/protobuf/obj.rs @@ -14,8 +14,10 @@ use crate::{ util, }; -use super::decode::Decoder; -use super::defs::{find_name_by_msg_offset, get_msg, MsgDef}; +use super::{ + decode::Decoder, + defs::{find_name_by_msg_offset, get_msg, MsgDef}, +}; #[repr(C)] pub struct MsgObj { @@ -70,8 +72,12 @@ impl MsgObj { Ok(self.msg_wire_id.map_or_else(Obj::const_none, Into::into)) } Qstr::MP_QSTR_MESSAGE_NAME => { - // Return the qstr name of this message def - Ok(Qstr::from_u16(find_name_by_msg_offset(self.msg_offset)?).into()) + // Return the QSTR name of this message def. + let name = Qstr::from_u16( + find_name_by_msg_offset(self.msg_offset) + .ok_or_else(|| Error::KeyError(self.msg_offset.into()))?, + ); + Ok(name.into()) } Qstr::MP_QSTR___dict__ => { // Conversion to dict. Allocate a new dict object with a copy of our map @@ -130,11 +136,11 @@ unsafe extern "C" fn msg_obj_attr(self_in: Obj, attr: ffi::qstr, dest: *mut Obj) unsafe { if dest.read().is_null() { - // Load attribute + // Load attribute. dest.write(this.getattr(attr)?); } else { let value = dest.offset(1).read(); - // Store attribute + // Store attribute. Gc::as_mut(&mut this).setattr(attr, value)?; dest.write(Obj::const_null()); } @@ -212,17 +218,14 @@ unsafe extern "C" fn msg_def_obj_attr(self_in: Obj, attr: ffi::qstr, dest: *mut match attr { Qstr::MP_QSTR_MESSAGE_NAME => { // Return the QSTR name of this message def. - let name = Qstr::from_u16(find_name_by_msg_offset(this.def.offset)?); + let name = Qstr::from_u16(find_name_by_msg_offset(this.def.offset).unwrap()); unsafe { dest.write(name.into()); }; } Qstr::MP_QSTR_MESSAGE_WIRE_TYPE => { // Return the wire type of this message def. - let wire_id_obj = this - .def - .wire_id - .map_or_else(Obj::const_none, |wire_id| wire_id.into()); + let wire_id_obj = this.def.wire_id.map_or_else(Obj::const_none, Into::into); unsafe { dest.write(wire_id_obj); }; diff --git a/core/embed/rust/src/util.rs b/core/embed/rust/src/util.rs index a23cad0445..caa2ae2d3d 100644 --- a/core/embed/rust/src/util.rs +++ b/core/embed/rust/src/util.rs @@ -9,9 +9,9 @@ use crate::{ }, }; -/// Perform a call and convert errors into a raised micropython exception. -/// Should only called when returning from Rust to C. -/// See `raise_exception` for details. +/// Perform a call and convert errors into a raised MicroPython exception. +/// Should only called when returning from Rust to C. See `raise_exception` for +/// details. pub unsafe fn try_or_raise(func: impl FnOnce() -> Result) -> T { func().unwrap_or_else(|err| unsafe { raise_exception(err); @@ -19,10 +19,8 @@ pub unsafe fn try_or_raise(func: impl FnOnce() -> Result) -> T { } /// Extract kwargs from a C call and pass them into Rust. Raise exception if an -/// error occurs. -/// TODO when does uPy call this? -/// Should only called when returning from Rust to C. -/// See `raise_exception` for details. +/// error occurs. Should only called when returning from Rust to C. See +/// `raise_exception` for details. pub unsafe fn try_with_kwargs( kwargs: *const Map, func: impl FnOnce(&Map) -> Result, @@ -36,10 +34,8 @@ pub unsafe fn try_with_kwargs( } /// Extract args and kwargs from a C call and pass them into Rust. Raise -/// exception if an error occurs. -/// TODO when would uPy call this? -/// Should only called when returning from Rust to C. -/// See `raise_exception` for details. +/// exception if an error occurs. Should only called when returning from Rust to +/// C. See `raise_exception` for details. pub unsafe fn try_with_args_and_kwargs( n_args: usize, args: *const Obj, @@ -60,9 +56,8 @@ pub unsafe fn try_with_args_and_kwargs( } /// Extract args and kwargs from a C call where args and kwargs are inlined, and -/// pass them into Rust. Raise exception if an error occurs. -/// Should only called when returning from Rust to C. -/// See `raise_exception` for details. +/// pass them into Rust. Raise exception if an error occurs. Should only called +/// when returning from Rust to C. See `raise_exception` for details. pub unsafe fn try_with_args_and_kwargs_inline( n_args: usize, n_kw: usize,