diff --git a/src/api/build_type.rs b/src/api/build_type.rs index 3700888d..af0e0ca8 100644 --- a/src/api/build_type.rs +++ b/src/api/build_type.rs @@ -88,6 +88,7 @@ impl Engine { /// /// To define a pretty-print name, call [`with_name`][`TypeBuilder::with_name`], /// to use [`Engine::register_type_with_name`] instead. +#[must_use] pub struct TypeBuilder<'a, T: Variant + Clone> { engine: &'a mut Engine, name: Option<&'static str>, diff --git a/src/api/call_fn.rs b/src/api/call_fn.rs index 616e7d09..a1f0ef7c 100644 --- a/src/api/call_fn.rs +++ b/src/api/call_fn.rs @@ -254,7 +254,7 @@ impl Engine { // Check for data race. #[cfg(not(feature = "no_closure"))] - crate::func::ensure_no_data_race(name, args, false).map(|_| Dynamic::UNIT)?; + crate::func::ensure_no_data_race(name, args, false)?; ast.shared_lib() .get_script_fn(name, args.len()) diff --git a/src/api/definitions/mod.rs b/src/api/definitions/mod.rs index 39b27a71..312b561d 100644 --- a/src/api/definitions/mod.rs +++ b/src/api/definitions/mod.rs @@ -29,6 +29,7 @@ impl Engine { /// # } /// ``` #[inline(always)] + #[must_use] pub fn definitions(&self) -> Definitions { Definitions { engine: self, @@ -55,6 +56,7 @@ impl Engine { /// # } /// ``` #[inline(always)] + #[must_use] pub fn definitions_with_scope<'e>(&'e self, scope: &'e Scope<'e>) -> Definitions<'e> { Definitions { engine: self, @@ -67,7 +69,6 @@ impl Engine { /// Internal configuration for module generation. #[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)] #[non_exhaustive] -#[must_use] pub struct DefinitionsConfig { /// Write `module ...` headers in definition files (default `false`). pub write_headers: bool, @@ -77,6 +78,7 @@ pub struct DefinitionsConfig { impl Default for DefinitionsConfig { #[inline(always)] + #[must_use] fn default() -> Self { Self { write_headers: false, @@ -89,7 +91,6 @@ impl Default for DefinitionsConfig { /// contents of an [`Engine`]. /// Exported under the `internals` and `metadata` feature only. #[derive(Debug, Clone)] -#[must_use] pub struct Definitions<'e> { /// The [`Engine`]. engine: &'e Engine, @@ -104,12 +105,14 @@ impl Definitions<'_> { /// Headers are always present in content that is expected to be written to a file /// (i.e. `write_to*` and `*_file` methods). #[inline(always)] + #[must_use] pub const fn with_headers(mut self, headers: bool) -> Self { self.config.write_headers = headers; self } /// Include standard packages when writing definition files. #[inline(always)] + #[must_use] pub const fn include_standard_packages(mut self, include_standard_packages: bool) -> Self { self.config.include_standard_packages = include_standard_packages; self @@ -128,6 +131,7 @@ impl Definitions<'_> { } /// Get the configuration. #[inline(always)] + #[must_use] pub(crate) const fn config(&self) -> &DefinitionsConfig { &self.config } @@ -392,6 +396,7 @@ impl Definitions<'_> { impl Module { /// Return definitions for all items inside the [`Module`]. #[cfg(not(feature = "no_module"))] + #[must_use] fn definition(&self, def: &Definitions) -> String { let mut s = String::new(); self.write_definition(&mut s, def).unwrap(); @@ -537,6 +542,7 @@ impl FuncInfo { /// It tries to flatten types, removing `&` and `&mut`, and paths, while keeping generics. /// /// Associated generic types are also rewritten into regular generic type parameters. +#[must_use] fn def_type_name<'a>(ty: &'a str, engine: &'a Engine) -> Cow<'a, str> { let ty = engine.format_type_name(ty).replace("crate::", ""); let ty = ty.strip_prefix("&mut").unwrap_or(&*ty).trim(); diff --git a/src/eval/chaining.rs b/src/eval/chaining.rs index 9c19bb3b..9f130dbf 100644 --- a/src/eval/chaining.rs +++ b/src/eval/chaining.rs @@ -599,13 +599,15 @@ impl Engine { // Try to call index setter if value is changed let idx = &mut idx_val_for_setter; let new_val = &mut new_val; - self.call_indexer_set( - global, caches, target, idx, new_val, is_ref_mut, op_pos, - ) - .or_else(|e| match *e { - ERR::ErrorIndexingType(..) => Ok((Dynamic::UNIT, false)), - _ => Err(e), - })?; + // The return value of a indexer setter (usually `()`) is thrown away and not used. + let _ = self + .call_indexer_set( + global, caches, target, idx, new_val, is_ref_mut, op_pos, + ) + .or_else(|e| match *e { + ERR::ErrorIndexingType(..) => Ok((Dynamic::UNIT, false)), + _ => Err(e), + })?; } Ok(result) @@ -659,8 +661,8 @@ impl Engine { // Try to call index setter let new_val = &mut new_val; - - self.call_indexer_set( + // The return value of a indexer setter (usually `()`) is thrown away and not used. + let _ = self.call_indexer_set( global, caches, target, idx_val, new_val, is_ref_mut, op_pos, )?; } @@ -981,18 +983,19 @@ impl Engine { // Re-use args because the first &mut parameter will not be consumed let mut arg_values = [target.as_mut(), val.as_mut()]; let args = &mut arg_values; - self.exec_native_fn_call( - global, - caches, - setter, - Token::NonToken, - *hash_set, - args, - is_ref_mut, - pos, - ) - .or_else( - |err| match *err { + // The return value is thrown away and not used. + let _ = self + .exec_native_fn_call( + global, + caches, + setter, + Token::NonToken, + *hash_set, + args, + is_ref_mut, + pos, + ) + .or_else(|err| match *err { // Try an indexer if property does not exist ERR::ErrorDotExpr(..) => { let idx = &mut name.into(); @@ -1011,8 +1014,7 @@ impl Engine { }) } _ => Err(err), - }, - )?; + })?; } Ok((result, may_be_changed)) diff --git a/src/eval/target.rs b/src/eval/target.rs index 59a89411..8ee2024e 100644 --- a/src/eval/target.rs +++ b/src/eval/target.rs @@ -81,6 +81,7 @@ pub fn calc_index( /// A type that encapsulates a mutation target for an expression with side effects. #[derive(Debug)] +#[must_use] pub enum Target<'a> { /// The target is a mutable reference to a [`Dynamic`]. RefMut(&'a mut Dynamic), @@ -195,7 +196,6 @@ impl<'a> Target<'a> { } /// Get the value of the [`Target`] as a [`Dynamic`], cloning a referenced value if necessary. #[inline] - #[must_use] pub fn take_or_clone(self) -> Dynamic { match self { Self::RefMut(r) => r.clone(), // Referenced value is cloned @@ -223,7 +223,6 @@ impl<'a> Target<'a> { } /// Convert a shared or reference [`Target`] into a target with an owned value. #[inline(always)] - #[must_use] pub fn into_owned(self) -> Self { match self { Self::RefMut(r) => Self::TempValue(r.clone()), @@ -437,7 +436,6 @@ impl AsMut for Target<'_> { impl> From for Target<'_> { #[inline(always)] - #[must_use] fn from(value: T) -> Self { Self::TempValue(value.into()) } diff --git a/src/module/mod.rs b/src/module/mod.rs index 35c01c7d..d540947d 100644 --- a/src/module/mod.rs +++ b/src/module/mod.rs @@ -2105,7 +2105,8 @@ impl Module { global.source = orig_source; - result?; + // The return value is thrown away and not used + let _ = result?; // Variables with an alias left in the scope become module variables for (_name, value, mut aliases) in scope { diff --git a/src/types/custom_types.rs b/src/types/custom_types.rs index 8135a506..460a4e94 100644 --- a/src/types/custom_types.rs +++ b/src/types/custom_types.rs @@ -65,6 +65,7 @@ impl CustomTypesCollection { } /// Find a custom type. #[inline(always)] + #[must_use] pub fn get(&self, key: &str) -> Option<&CustomTypeInfo> { self.0.get(key) } diff --git a/src/types/dynamic.rs b/src/types/dynamic.rs index 47fa5c22..a5335651 100644 --- a/src/types/dynamic.rs +++ b/src/types/dynamic.rs @@ -49,11 +49,13 @@ pub type Tag = i16; const DEFAULT_TAG_VALUE: Tag = 0; /// Dynamic type containing any value. +#[must_use] pub struct Dynamic(pub(crate) Union); /// Internal [`Dynamic`] representation. /// /// Most variants are boxed to reduce the size. +#[must_use] pub enum Union { /// An error value which should not exist. Null, @@ -107,10 +109,12 @@ pub enum Union { /// This type provides transparent interoperability between normal [`Dynamic`] and shared /// [`Dynamic`] values. #[derive(Debug)] +#[must_use] pub struct DynamicReadLock<'d, T: Clone>(DynamicReadLockInner<'d, T>); /// Different types of read guards for [`DynamicReadLock`]. #[derive(Debug)] +#[must_use] enum DynamicReadLockInner<'d, T: Clone> { /// A simple reference to a non-shared value. Reference(&'d T), @@ -139,10 +143,12 @@ impl<'d, T: Any + Clone> Deref for DynamicReadLock<'d, T> { /// This type provides transparent interoperability between normal [`Dynamic`] and shared /// [`Dynamic`] values. #[derive(Debug)] +#[must_use] pub struct DynamicWriteLock<'d, T: Clone>(DynamicWriteLockInner<'d, T>); /// Different types of write guards for [`DynamicReadLock`]. #[derive(Debug)] +#[must_use] enum DynamicWriteLockInner<'d, T: Clone> { /// A simple mutable reference to a non-shared value. Reference(&'d mut T), @@ -686,7 +692,6 @@ impl Clone for Dynamic { impl Default for Dynamic { #[inline(always)] - #[must_use] fn default() -> Self { Self::UNIT } @@ -852,19 +857,16 @@ impl Dynamic { /// Create a new [`Dynamic`] from a [`bool`]. #[inline(always)] - #[must_use] pub const fn from_bool(value: bool) -> Self { Self(Union::Bool(value, DEFAULT_TAG_VALUE, ReadWrite)) } /// Create a new [`Dynamic`] from an [`INT`]. #[inline(always)] - #[must_use] pub const fn from_int(value: INT) -> Self { Self(Union::Int(value, DEFAULT_TAG_VALUE, ReadWrite)) } /// Create a new [`Dynamic`] from a [`char`]. #[inline(always)] - #[must_use] pub const fn from_char(value: char) -> Self { Self(Union::Char(value, DEFAULT_TAG_VALUE, ReadWrite)) } @@ -873,7 +875,6 @@ impl Dynamic { /// Not available under `no_float`. #[cfg(not(feature = "no_float"))] #[inline(always)] - #[must_use] pub const fn from_float(value: crate::FLOAT) -> Self { Self(Union::Float( super::FloatWrapper::new(value), @@ -886,28 +887,24 @@ impl Dynamic { /// Exported under the `decimal` feature only. #[cfg(feature = "decimal")] #[inline(always)] - #[must_use] pub fn from_decimal(value: rust_decimal::Decimal) -> Self { Self(Union::Decimal(value.into(), DEFAULT_TAG_VALUE, ReadWrite)) } /// Create a [`Dynamic`] from an [`Array`][crate::Array]. #[cfg(not(feature = "no_index"))] #[inline(always)] - #[must_use] pub fn from_array(array: crate::Array) -> Self { Self(Union::Array(array.into(), DEFAULT_TAG_VALUE, ReadWrite)) } /// Create a [`Dynamic`] from a [`Blob`][crate::Blob]. #[cfg(not(feature = "no_index"))] #[inline(always)] - #[must_use] pub fn from_blob(blob: crate::Blob) -> Self { Self(Union::Blob(blob.into(), DEFAULT_TAG_VALUE, ReadWrite)) } /// Create a [`Dynamic`] from a [`Map`][crate::Map]. #[cfg(not(feature = "no_object"))] #[inline(always)] - #[must_use] pub fn from_map(map: crate::Map) -> Self { Self(Union::Map(map.into(), DEFAULT_TAG_VALUE, ReadWrite)) } @@ -916,7 +913,6 @@ impl Dynamic { /// Not available under `no-std` or `no_time`. #[cfg(not(feature = "no_time"))] #[inline(always)] - #[must_use] pub fn from_timestamp(value: Instant) -> Self { Self(Union::TimeStamp(value.into(), DEFAULT_TAG_VALUE, ReadWrite)) } @@ -991,7 +987,6 @@ impl Dynamic { } /// Make this [`Dynamic`] read-only (i.e. a constant). #[inline(always)] - #[must_use] pub fn into_read_only(self) -> Self { let mut value = self; value.set_access_mode(AccessMode::ReadOnly); @@ -1085,7 +1080,6 @@ impl Dynamic { /// assert_eq!(new_result.to_string(), "hello"); /// ``` #[inline] - #[must_use] pub fn from(value: T) -> Self { // Coded this way in order to maximally leverage potentials for dead-code removal. @@ -1143,7 +1137,6 @@ impl Dynamic { /// If the [`Dynamic`] value is already shared, this method returns itself. #[cfg(not(feature = "no_closure"))] #[inline] - #[must_use] pub fn into_shared(self) -> Self { let _access = self.access_mode(); @@ -1365,7 +1358,6 @@ impl Dynamic { /// /// If the [`Dynamic`] is a shared value, it returns a cloned copy of the shared value. #[inline] - #[must_use] pub fn flatten_clone(&self) -> Self { match self.0 { #[cfg(not(feature = "no_closure"))] @@ -1380,7 +1372,6 @@ impl Dynamic { /// If the [`Dynamic`] is a shared value, it returns the shared value if there are no /// outstanding references, or a cloned copy. #[inline] - #[must_use] pub fn flatten(self) -> Self { match self.0 { #[cfg(not(feature = "no_closure"))] @@ -1451,7 +1442,6 @@ impl Dynamic { /// Under the `sync` feature, this call may deadlock, or [panic](https://doc.rust-lang.org/std/sync/struct.RwLock.html#panics-1). /// Otherwise, this call panics if the data is currently borrowed for write. #[inline] - #[must_use] pub fn read_lock(&self) -> Option> { match self.0 { #[cfg(not(feature = "no_closure"))] @@ -1483,7 +1473,6 @@ impl Dynamic { /// Under the `sync` feature, this call may deadlock, or [panic](https://doc.rust-lang.org/std/sync/struct.RwLock.html#panics-1). /// Otherwise, this call panics if the data is currently borrowed for write. #[inline] - #[must_use] pub fn write_lock(&mut self) -> Option> { match self.0 { #[cfg(not(feature = "no_closure"))] diff --git a/src/types/float.rs b/src/types/float.rs index 8cfeed77..91af3a8d 100644 --- a/src/types/float.rs +++ b/src/types/float.rs @@ -15,6 +15,7 @@ use num_traits::float::FloatCore as Float; /// /// Not available under `no_float`. #[derive(Clone, Copy, Eq, PartialEq, PartialOrd)] +#[must_use] pub struct FloatWrapper(F); impl Hash for FloatWrapper { @@ -108,7 +109,6 @@ impl FloatWrapper { /// Create a new [`FloatWrapper`]. #[inline(always)] - #[must_use] pub const fn new(value: F) -> Self { Self(value) } diff --git a/src/types/interner.rs b/src/types/interner.rs index 430605e8..34fe3789 100644 --- a/src/types/interner.rs +++ b/src/types/interner.rs @@ -24,7 +24,6 @@ pub const MAX_STRING_LEN: usize = 24; /// _(internals)_ A cache for interned strings. /// Exported under the `internals` feature only. #[derive(Clone)] -#[must_use] pub struct StringsInterner { /// Cached strings. cache: StraightHashMap, @@ -34,6 +33,7 @@ pub struct StringsInterner { impl Default for StringsInterner { #[inline(always)] + #[must_use] fn default() -> Self { Self::new() } @@ -50,6 +50,7 @@ impl fmt::Debug for StringsInterner { impl StringsInterner { /// Create a new [`StringsInterner`]. #[inline(always)] + #[must_use] pub fn new() -> Self { Self { cache: StraightHashMap::default(), diff --git a/src/types/scope.rs b/src/types/scope.rs index 639195cb..c6320861 100644 --- a/src/types/scope.rs +++ b/src/types/scope.rs @@ -386,7 +386,7 @@ impl Scope<'_> { #[inline(always)] pub fn pop(&mut self) -> &mut Self { self.names.pop().expect("`Scope` must not be empty"); - self.values.pop().expect("`Scope` must not be empty"); + let _ = self.values.pop().expect("`Scope` must not be empty"); self.aliases.pop().expect("`Scope` must not be empty"); self }