diff --git a/examples/verify_tx.rs b/examples/verify_tx.rs
index 9a41fb309..e855ec19d 100644
--- a/examples/verify_tx.rs
+++ b/examples/verify_tx.rs
@@ -46,15 +46,14 @@ fn main() {
 
     for elem in interpreter.iter_assume_sigs() {
         // Don't bother checking signatures.
-        match elem.expect("no evaluation error") {
-            miniscript::interpreter::SatisfiedConstraint::PublicKey { key_sig } => {
-                let (key, sig) = key_sig
-                    .as_ecdsa()
-                    .expect("expected ecdsa sig, found schnorr sig");
-
-                println!("Signed with:\n key: {}\n sig: {}", key, sig);
-            }
-            _ => {}
+        if let miniscript::interpreter::SatisfiedConstraint::PublicKey { key_sig } =
+            elem.expect("no evaluation error")
+        {
+            let (key, sig) = key_sig
+                .as_ecdsa()
+                .expect("expected ecdsa sig, found schnorr sig");
+
+            println!("Signed with:\n key: {}\n sig: {}", key, sig);
         }
     }
 
@@ -71,12 +70,11 @@ fn main() {
     let prevouts = sighash::Prevouts::All::<bitcoin::TxOut>(&[]);
 
     for elem in interpreter.iter(&secp, &tx, 0, &prevouts) {
-        match elem.expect("no evaluation error") {
-            miniscript::interpreter::SatisfiedConstraint::PublicKey { key_sig } => {
-                let (key, sig) = key_sig.as_ecdsa().unwrap();
-                println!("Signed with:\n key: {}\n sig: {}", key, sig);
-            }
-            _ => {}
+        if let miniscript::interpreter::SatisfiedConstraint::PublicKey { key_sig } =
+            elem.expect("no evaluation error")
+        {
+            let (key, sig) = key_sig.as_ecdsa().unwrap();
+            println!("Signed with:\n key: {}\n sig: {}", key, sig);
         }
     }
 
diff --git a/examples/xpub_descriptors.rs b/examples/xpub_descriptors.rs
index 08f31ecee..90b0458f3 100644
--- a/examples/xpub_descriptors.rs
+++ b/examples/xpub_descriptors.rs
@@ -30,7 +30,7 @@ fn p2wsh<C: Verification>(secp: &Secp256k1<C>) -> Address {
 
     let address = Descriptor::<DefiniteDescriptorKey>::from_str(&s)
         .unwrap()
-        .derived_descriptor(&secp)
+        .derived_descriptor(secp)
         .unwrap()
         .address(Network::Bitcoin)
         .unwrap();
@@ -53,7 +53,7 @@ fn p2sh_p2wsh<C: Verification>(secp: &Secp256k1<C>) -> Address {
 
     let address = Descriptor::<DescriptorPublicKey>::from_str(&s)
         .unwrap()
-        .derived_descriptor(&secp, 5)
+        .derived_descriptor(secp, 5)
         .unwrap()
         .address(Network::Bitcoin)
         .unwrap();
diff --git a/src/descriptor/mod.rs b/src/descriptor/mod.rs
index c5d96016b..690b225fc 100644
--- a/src/descriptor/mod.rs
+++ b/src/descriptor/mod.rs
@@ -809,7 +809,7 @@ impl Descriptor<DescriptorPublicKey> {
     ///
     /// For multipath descriptors it will return as many descriptors as there is
     /// "parallel" paths. For regular descriptors it will just return itself.
-    #[allow(clippy::blocks_in_if_conditions)]
+    #[allow(clippy::blocks_in_conditions)]
     pub fn into_single_descriptors(self) -> Result<Vec<Descriptor<DescriptorPublicKey>>, Error> {
         // All single-path descriptors contained in this descriptor.
         let mut descriptors = Vec::new();
@@ -1114,7 +1114,7 @@ mod tests {
                 .push_opcode(opcodes::all::OP_DUP)
                 .push_opcode(opcodes::all::OP_HASH160)
                 .push_slice(
-                    &hash160::Hash::from_str("84e9ed95a38613f0527ff685a9928abe2d4754d4",)
+                    hash160::Hash::from_str("84e9ed95a38613f0527ff685a9928abe2d4754d4",)
                         .unwrap()
                         .to_byte_array()
                 )
@@ -1138,7 +1138,7 @@ mod tests {
             script::Builder::new()
                 .push_opcode(opcodes::all::OP_PUSHBYTES_0)
                 .push_slice(
-                    &hash160::Hash::from_str("84e9ed95a38613f0527ff685a9928abe2d4754d4",)
+                    hash160::Hash::from_str("84e9ed95a38613f0527ff685a9928abe2d4754d4",)
                         .unwrap()
                         .to_byte_array()
                 )
@@ -1160,7 +1160,7 @@ mod tests {
             script::Builder::new()
                 .push_opcode(opcodes::all::OP_HASH160)
                 .push_slice(
-                    &hash160::Hash::from_str("f1c3b9a431134cb90a500ec06e0067cfa9b8bba7",)
+                    hash160::Hash::from_str("f1c3b9a431134cb90a500ec06e0067cfa9b8bba7",)
                         .unwrap()
                         .to_byte_array()
                 )
@@ -1183,7 +1183,7 @@ mod tests {
             script::Builder::new()
                 .push_opcode(opcodes::all::OP_HASH160)
                 .push_slice(
-                    &hash160::Hash::from_str("aa5282151694d3f2f32ace7d00ad38f927a33ac8",)
+                    hash160::Hash::from_str("aa5282151694d3f2f32ace7d00ad38f927a33ac8",)
                         .unwrap()
                         .to_byte_array()
                 )
@@ -1206,7 +1206,7 @@ mod tests {
             script::Builder::new()
                 .push_opcode(opcodes::all::OP_PUSHBYTES_0)
                 .push_slice(
-                    &sha256::Hash::from_str(
+                    sha256::Hash::from_str(
                         "\
                          f9379edc8983152dc781747830075bd5\
                          3896e4b0ce5bff73777fd77d124ba085\
@@ -1233,7 +1233,7 @@ mod tests {
             script::Builder::new()
                 .push_opcode(opcodes::all::OP_HASH160)
                 .push_slice(
-                    &hash160::Hash::from_str("4bec5d7feeed99e1d0a23fe32a4afe126a7ff07e",)
+                    hash160::Hash::from_str("4bec5d7feeed99e1d0a23fe32a4afe126a7ff07e",)
                         .unwrap()
                         .to_byte_array()
                 )
@@ -1328,7 +1328,7 @@ mod tests {
                 previous_output: bitcoin::OutPoint::default(),
                 script_sig: bitcoin::ScriptBuf::new(),
                 sequence: Sequence::from_height(100),
-                witness: Witness::from_slice(&vec![sigser.clone(), pk.to_bytes(),]),
+                witness: Witness::from_slice(&[sigser.clone(), pk.to_bytes()]),
             }
         );
         assert_eq!(wpkh.unsigned_script_sig(), bitcoin::ScriptBuf::new());
@@ -1338,7 +1338,7 @@ mod tests {
         let redeem_script = script::Builder::new()
             .push_opcode(opcodes::all::OP_PUSHBYTES_0)
             .push_slice(
-                &hash160::Hash::from_str("d1b2a1faf62e73460af885c687dee3b7189cd8ab")
+                hash160::Hash::from_str("d1b2a1faf62e73460af885c687dee3b7189cd8ab")
                     .unwrap()
                     .to_byte_array(),
             )
@@ -1351,7 +1351,7 @@ mod tests {
                     .push_slice(<&PushBytes>::try_from(redeem_script.as_bytes()).unwrap())
                     .into_script(),
                 sequence: Sequence::from_height(100),
-                witness: Witness::from_slice(&vec![sigser.clone(), pk.to_bytes(),]),
+                witness: Witness::from_slice(&[sigser.clone(), pk.to_bytes()]),
             }
         );
         assert_eq!(
@@ -1388,7 +1388,7 @@ mod tests {
                 previous_output: bitcoin::OutPoint::default(),
                 script_sig: bitcoin::ScriptBuf::new(),
                 sequence: Sequence::from_height(100),
-                witness: Witness::from_slice(&vec![sigser.clone(), ms.encode().into_bytes(),]),
+                witness: Witness::from_slice(&[sigser.clone(), ms.encode().into_bytes()]),
             }
         );
         assert_eq!(wsh.unsigned_script_sig(), bitcoin::ScriptBuf::new());
@@ -1403,7 +1403,7 @@ mod tests {
                     .push_slice(<&PushBytes>::try_from(ms.encode().to_p2wsh().as_bytes()).unwrap())
                     .into_script(),
                 sequence: Sequence::from_height(100),
-                witness: Witness::from_slice(&vec![sigser.clone(), ms.encode().into_bytes(),]),
+                witness: Witness::from_slice(&[sigser.clone(), ms.encode().into_bytes()]),
             }
         );
         assert_eq!(
diff --git a/src/interpreter/inner.rs b/src/interpreter/inner.rs
index bae422b97..8383cb1e2 100644
--- a/src/interpreter/inner.rs
+++ b/src/interpreter/inner.rs
@@ -441,21 +441,21 @@ mod tests {
             KeyTestData {
                 pk_spk: bitcoin::ScriptBuf::new_p2pk(&key),
                 pkh_spk: bitcoin::ScriptBuf::new_p2pkh(&pkhash),
-                pk_sig: script::Builder::new().push_slice(&dummy_sig).into_script(),
+                pk_sig: script::Builder::new().push_slice(dummy_sig).into_script(),
                 pkh_sig: script::Builder::new()
-                    .push_slice(&dummy_sig)
+                    .push_slice(dummy_sig)
                     .push_key(&key)
                     .into_script(),
                 pkh_sig_justkey: script::Builder::new().push_key(&key).into_script(),
                 wpkh_spk: wpkh_spk.clone(),
-                wpkh_stack: Witness::from_slice(&vec![dummy_sig_vec.clone(), key.to_bytes()]),
-                wpkh_stack_justkey: Witness::from_slice(&vec![key.to_bytes()]),
+                wpkh_stack: Witness::from_slice(&[dummy_sig_vec.clone(), key.to_bytes()]),
+                wpkh_stack_justkey: Witness::from_slice(&[key.to_bytes()]),
                 sh_wpkh_spk: bitcoin::ScriptBuf::new_p2sh(&wpkh_scripthash),
                 sh_wpkh_sig: script::Builder::new()
                     .push_slice(<&PushBytes>::try_from(wpkh_spk[..].as_bytes()).unwrap())
                     .into_script(),
-                sh_wpkh_stack: Witness::from_slice(&vec![dummy_sig_vec, key.to_bytes()]),
-                sh_wpkh_stack_justkey: Witness::from_slice(&vec![key.to_bytes()]),
+                sh_wpkh_stack: Witness::from_slice(&[dummy_sig_vec, key.to_bytes()]),
+                sh_wpkh_stack_justkey: Witness::from_slice(&[key.to_bytes()]),
             }
         }
     }
@@ -534,7 +534,7 @@ mod tests {
         assert_eq!(&err.to_string()[0..12], "parse error:");
 
         // Witness is nonempty
-        let wit = Witness::from_slice(&vec![vec![]]);
+        let wit = Witness::from_slice(&[vec![]]);
         let err = from_txdata(&comp.pk_spk, &comp.pk_sig, &wit).unwrap_err();
         assert_eq!(err.to_string(), "legacy spend had nonempty witness");
     }
@@ -583,7 +583,7 @@ mod tests {
         assert_eq!(script_code, Some(uncomp.pkh_spk.clone()));
 
         // Witness is nonempty
-        let wit = Witness::from_slice(&vec![vec![]]);
+        let wit = Witness::from_slice(&[vec![]]);
         let err = from_txdata(&comp.pkh_spk, &comp.pkh_sig, &wit).unwrap_err();
         assert_eq!(err.to_string(), "legacy spend had nonempty witness");
     }
@@ -706,7 +706,7 @@ mod tests {
         assert_eq!(&err.to_string()[0..12], "parse error:");
 
         // nonempty witness
-        let wit = Witness::from_slice(&vec![vec![]]);
+        let wit = Witness::from_slice(&[vec![]]);
         let err = from_txdata(&spk, &blank_script, &wit).unwrap_err();
         assert_eq!(&err.to_string(), "legacy spend had nonempty witness");
     }
@@ -742,7 +742,7 @@ mod tests {
         assert_eq!(script_code, Some(redeem_script));
 
         // nonempty witness
-        let wit = Witness::from_slice(&vec![vec![]]);
+        let wit = Witness::from_slice(&[vec![]]);
         let err = from_txdata(&spk, &script_sig, &wit).unwrap_err();
         assert_eq!(&err.to_string(), "legacy spend had nonempty witness");
     }
@@ -753,7 +753,7 @@ mod tests {
         let hash = hash160::Hash::hash(&preimage[..]);
         let (miniscript, witness_script) = ms_inner_script(&format!("hash160({})", hash));
         let wit_hash = sha256::Hash::hash(witness_script.as_bytes()).into();
-        let wit_stack = Witness::from_slice(&vec![witness_script.to_bytes()]);
+        let wit_stack = Witness::from_slice(&[witness_script.to_bytes()]);
 
         let spk = ScriptBuf::new_p2wsh(&wit_hash);
         let blank_script = bitcoin::ScriptBuf::new();
@@ -763,7 +763,7 @@ mod tests {
         assert_eq!(&err.to_string(), "unexpected end of stack");
 
         // with incorrect witness
-        let wit = Witness::from_slice(&vec![spk.to_bytes()]);
+        let wit = Witness::from_slice(&[spk.to_bytes()]);
         let err = from_txdata(&spk, &blank_script, &wit).unwrap_err();
         assert_eq!(&err.to_string()[0..12], "parse error:");
 
@@ -788,7 +788,7 @@ mod tests {
         let hash = hash160::Hash::hash(&preimage[..]);
         let (miniscript, witness_script) = ms_inner_script(&format!("hash160({})", hash));
         let wit_hash = sha256::Hash::hash(witness_script.as_bytes()).into();
-        let wit_stack = Witness::from_slice(&vec![witness_script.to_bytes()]);
+        let wit_stack = Witness::from_slice(&[witness_script.to_bytes()]);
 
         let redeem_script = ScriptBuf::new_p2wsh(&wit_hash);
         let script_sig = script::Builder::new()
@@ -808,7 +808,7 @@ mod tests {
         assert_eq!(&err.to_string(), "unexpected end of stack");
 
         // with incorrect witness
-        let wit = Witness::from_slice(&vec![spk.to_bytes()]);
+        let wit = Witness::from_slice(&[spk.to_bytes()]);
         let err = from_txdata(&spk, &script_sig, &wit).unwrap_err();
         assert_eq!(&err.to_string()[0..12], "parse error:");
 
diff --git a/src/interpreter/mod.rs b/src/interpreter/mod.rs
index 446c7931b..02807251b 100644
--- a/src/interpreter/mod.rs
+++ b/src/interpreter/mod.rs
@@ -1033,6 +1033,7 @@ mod tests {
     use crate::miniscript::context::NoChecks;
     use crate::{Miniscript, ToPublicKey};
 
+    #[allow(clippy::type_complexity)]
     fn setup_keys_sigs(
         n: usize,
     ) -> (
diff --git a/src/plan.rs b/src/plan.rs
index 49b95c908..e26a8b365 100644
--- a/src/plan.rs
+++ b/src/plan.rs
@@ -742,6 +742,7 @@ mod test {
     use super::*;
     use crate::*;
 
+    #[allow(clippy::type_complexity)]
     fn test_inner(
         desc: &str,
         keys: Vec<DescriptorPublicKey>,
@@ -749,7 +750,7 @@ mod test {
         // [ (key_indexes, hash_indexes, older, after, expected) ]
         tests: Vec<(Vec<usize>, Vec<usize>, Option<Sequence>, Option<LockTime>, Option<usize>)>,
     ) {
-        let desc = Descriptor::<DefiniteDescriptorKey>::from_str(&desc).unwrap();
+        let desc = Descriptor::<DefiniteDescriptorKey>::from_str(desc).unwrap();
 
         for (key_indexes, hash_indexes, older, after, expected) in tests {
             let mut assets = Assets::new();
@@ -763,7 +764,7 @@ mod test {
                 assets = assets.add(keys[ki].clone());
             }
             for hi in hash_indexes {
-                assets = assets.add(hashes[hi].clone());
+                assets = assets.add(hashes[hi]);
             }
 
             let result = desc.clone().plan(&assets);
@@ -1027,7 +1028,7 @@ mod test {
             "02c2fd50ceae468857bb7eb32ae9cd4083e6c7e42fbbec179d81134b3e3830586c",
         )
         .unwrap()];
-        let hashes = vec![hash160::Hash::from_slice(&vec![0; 20]).unwrap()];
+        let hashes = vec![hash160::Hash::from_slice(&[0; 20]).unwrap()];
         let desc = format!("wsh(and_v(v:pk({}),hash160({})))", keys[0], hashes[0]);
 
         let tests = vec![
diff --git a/src/policy/semantic.rs b/src/policy/semantic.rs
index 0a2b015b7..cd5b49685 100644
--- a/src/policy/semantic.rs
+++ b/src/policy/semantic.rs
@@ -420,7 +420,7 @@ impl<Pk: MiniscriptKey> Policy<Pk> {
                     .count();
 
                 let n = subs.len() - unsatisfied_count - trivial_count; // remove all true/false
-                let m = k.checked_sub(trivial_count).unwrap_or(0); // satisfy all trivial
+                let m = k.saturating_sub(trivial_count); // satisfy all trivial
 
                 let is_and = m == n;
                 let is_or = m == 1;
@@ -597,10 +597,7 @@ impl<Pk: MiniscriptKey> Policy<Pk> {
     /// Duplicate keys will be double-counted.
     pub fn n_keys(&self) -> usize {
         self.pre_order_iter()
-            .filter(|policy| match policy {
-                Policy::Key(..) => true,
-                _ => false,
-            })
+            .filter(|policy| matches!(policy, Policy::Key(..)))
             .count()
     }
 
@@ -687,7 +684,7 @@ impl<'a, Pk: MiniscriptKey> TreeLike for &'a Policy<Pk> {
     }
 }
 
-impl<'a, Pk: MiniscriptKey> TreeLike for Arc<Policy<Pk>> {
+impl<Pk: MiniscriptKey> TreeLike for Arc<Policy<Pk>> {
     fn as_node(&self) -> Tree<Self> {
         use Policy::*;
 
diff --git a/src/psbt/mod.rs b/src/psbt/mod.rs
index d0ab79179..54c82d93d 100644
--- a/src/psbt/mod.rs
+++ b/src/psbt/mod.rs
@@ -343,32 +343,32 @@ impl<'psbt, Pk: MiniscriptKey + ToPublicKey> Satisfier<Pk> for PsbtInputSatisfie
         self.psbt.inputs[self.index]
             .hash160_preimages
             .get(&Pk::to_hash160(h))
-            .and_then(try_vec_as_preimage32)
+            .and_then(|x: &Vec<u8>| try_vec_as_preimage32(x))
     }
 
     fn lookup_sha256(&self, h: &Pk::Sha256) -> Option<Preimage32> {
         self.psbt.inputs[self.index]
             .sha256_preimages
             .get(&Pk::to_sha256(h))
-            .and_then(try_vec_as_preimage32)
+            .and_then(|x: &Vec<u8>| try_vec_as_preimage32(x))
     }
 
     fn lookup_hash256(&self, h: &Pk::Hash256) -> Option<Preimage32> {
         self.psbt.inputs[self.index]
             .hash256_preimages
             .get(&sha256d::Hash::from_byte_array(Pk::to_hash256(h).to_byte_array())) // upstream psbt operates on hash256
-            .and_then(try_vec_as_preimage32)
+            .and_then(|x: &Vec<u8>| try_vec_as_preimage32(x))
     }
 
     fn lookup_ripemd160(&self, h: &Pk::Ripemd160) -> Option<Preimage32> {
         self.psbt.inputs[self.index]
             .ripemd160_preimages
             .get(&Pk::to_ripemd160(h))
-            .and_then(try_vec_as_preimage32)
+            .and_then(|x: &Vec<u8>| try_vec_as_preimage32(x))
     }
 }
 
-fn try_vec_as_preimage32(vec: &Vec<u8>) -> Option<Preimage32> {
+fn try_vec_as_preimage32(vec: &[u8]) -> Option<Preimage32> {
     if vec.len() == 32 {
         let mut arr = [0u8; 32];
         arr.copy_from_slice(vec);
@@ -1590,7 +1590,7 @@ mod tests {
     #[test]
     fn test_update_input_checks() {
         let desc = "tr([73c5da0a/86'/0'/0']xpub6BgBgsespWvERF3LHQu6CnqdvfEvtMcQjYrcRzx53QJjSxarj2afYWcLteoGVky7D3UKDP9QyrLprQ3VCECoY49yfdDEHGCtMMj92pReUsQ/0/0)";
-        let desc = Descriptor::<DefiniteDescriptorKey>::from_str(&desc).unwrap();
+        let desc = Descriptor::<DefiniteDescriptorKey>::from_str(desc).unwrap();
 
         let mut non_witness_utxo = bitcoin::Transaction {
             version: transaction::Version::ONE,
@@ -1652,7 +1652,7 @@ mod tests {
     #[test]
     fn test_update_output_checks() {
         let desc = "tr([73c5da0a/86'/0'/0']xpub6BgBgsespWvERF3LHQu6CnqdvfEvtMcQjYrcRzx53QJjSxarj2afYWcLteoGVky7D3UKDP9QyrLprQ3VCECoY49yfdDEHGCtMMj92pReUsQ/0/0)";
-        let desc = Descriptor::<DefiniteDescriptorKey>::from_str(&desc).unwrap();
+        let desc = Descriptor::<DefiniteDescriptorKey>::from_str(desc).unwrap();
 
         let tx = bitcoin::Transaction {
             version: transaction::Version::ONE,
diff --git a/src/test_utils.rs b/src/test_utils.rs
index 086af7932..3cc1345ae 100644
--- a/src/test_utils.rs
+++ b/src/test_utils.rs
@@ -168,7 +168,7 @@ impl StrXOnlyKeyTranslator {
             .collect();
         let mut pk_map = HashMap::new();
         let mut pkh_map = HashMap::new();
-        for (i, c) in (b'A'..b'Z').enumerate() {
+        for (i, c) in (b'A'..=b'Z').enumerate() {
             let key = String::from_utf8(vec![c]).unwrap();
             pk_map.insert(key.clone(), pks[i]);
             pkh_map.insert(key, pks[i].to_pubkeyhash(SigType::Schnorr));