From 17e0264dfe2366013c43bcee8d7eb74e29f22ab9 Mon Sep 17 00:00:00 2001
From: Marijn Schouten <hkBst@users.noreply.github.com>
Date: Mon, 23 Dec 2024 18:08:38 +0100
Subject: [PATCH 1/2] simplify Iterator::next for PercentEncode

This reduces duplication including of an unsafe block...

Signed-off-by: Marijn Schouten <hkBst@users.noreply.github.com>
---
 percent_encoding/src/lib.rs | 21 +++++++++------------
 1 file changed, 9 insertions(+), 12 deletions(-)

diff --git a/percent_encoding/src/lib.rs b/percent_encoding/src/lib.rs
index 11b6296e6..efa04657a 100644
--- a/percent_encoding/src/lib.rs
+++ b/percent_encoding/src/lib.rs
@@ -153,18 +153,15 @@ impl<'a> Iterator for PercentEncode<'a> {
                 self.bytes = remaining;
                 Some(percent_encode_byte(first_byte))
             } else {
-                // The unsafe blocks here are appropriate because the bytes are
-                // confirmed as a subset of UTF-8 in should_percent_encode.
-                for (i, &byte) in remaining.iter().enumerate() {
-                    if self.ascii_set.should_percent_encode(byte) {
-                        // 1 for first_byte + i for previous iterations of this loop
-                        let (unchanged_slice, remaining) = self.bytes.split_at(1 + i);
-                        self.bytes = remaining;
-                        return Some(unsafe { str::from_utf8_unchecked(unchanged_slice) });
-                    }
-                }
-                let unchanged_slice = self.bytes;
-                self.bytes = &[][..];
+                let (unchanged_slice, remaining) = self.bytes.split_at(
+                    // 1 for the first byte + rest in remaining
+                    1 + remaining
+                        .iter()
+                        .position(|&byte| self.ascii_set.should_percent_encode(byte))
+                        .unwrap_or(remaining.len()),
+                );
+                self.bytes = remaining;
+                // SAFETY: bytes are confirmed as a subset of UTF-8 in should_percent_encode.
                 Some(unsafe { str::from_utf8_unchecked(unchanged_slice) })
             }
         } else {

From 155471c3d29b5b8badf5da664b1199d52d736a59 Mon Sep 17 00:00:00 2001
From: Marijn Schouten <mhkbst@gmail.com>
Date: Fri, 3 Jan 2025 13:50:28 +0100
Subject: [PATCH 2/2] elide explicit lifetimes to make clippy happy

---
 data-url/src/lib.rs         | 2 +-
 form_urlencoded/src/lib.rs  | 4 ++--
 idna/src/punycode.rs        | 4 ++--
 percent_encoding/src/lib.rs | 4 ++--
 url/src/host.rs             | 2 +-
 url/src/lib.rs              | 8 ++++----
 url/src/parser.rs           | 4 ++--
 url/src/path_segments.rs    | 4 ++--
 8 files changed, 16 insertions(+), 16 deletions(-)

diff --git a/data-url/src/lib.rs b/data-url/src/lib.rs
index d7ceeb111..f1adcc602 100644
--- a/data-url/src/lib.rs
+++ b/data-url/src/lib.rs
@@ -124,7 +124,7 @@ impl<'a> DataUrl<'a> {
 /// The URL’s fragment identifier (after `#`)
 pub struct FragmentIdentifier<'a>(&'a str);
 
-impl<'a> FragmentIdentifier<'a> {
+impl FragmentIdentifier<'_> {
     /// Like in a parsed URL
     pub fn to_percent_encoded(&self) -> String {
         let mut string = String::new();
diff --git a/form_urlencoded/src/lib.rs b/form_urlencoded/src/lib.rs
index 1d68579b7..1d9582249 100644
--- a/form_urlencoded/src/lib.rs
+++ b/form_urlencoded/src/lib.rs
@@ -104,7 +104,7 @@ pub struct ParseIntoOwned<'a> {
     inner: Parse<'a>,
 }
 
-impl<'a> Iterator for ParseIntoOwned<'a> {
+impl Iterator for ParseIntoOwned<'_> {
     type Item = (String, String);
 
     fn next(&mut self) -> Option<Self::Item> {
@@ -195,7 +195,7 @@ impl Target for String {
     type Finished = Self;
 }
 
-impl<'a> Target for &'a mut String {
+impl Target for &mut String {
     fn as_mut_string(&mut self) -> &mut String {
         self
     }
diff --git a/idna/src/punycode.rs b/idna/src/punycode.rs
index 842d81940..7194c32c6 100644
--- a/idna/src/punycode.rs
+++ b/idna/src/punycode.rs
@@ -277,7 +277,7 @@ where
     phantom: PhantomData<C>,
 }
 
-impl<'a, T: PunycodeCodeUnit + Copy, C: PunycodeCaller> Iterator for Decode<'a, T, C> {
+impl<T: PunycodeCodeUnit + Copy, C: PunycodeCaller> Iterator for Decode<'_, T, C> {
     type Item = char;
 
     fn next(&mut self) -> Option<Self::Item> {
@@ -309,7 +309,7 @@ impl<'a, T: PunycodeCodeUnit + Copy, C: PunycodeCaller> Iterator for Decode<'a,
     }
 }
 
-impl<'a, T: PunycodeCodeUnit + Copy, C: PunycodeCaller> ExactSizeIterator for Decode<'a, T, C> {
+impl<T: PunycodeCodeUnit + Copy, C: PunycodeCaller> ExactSizeIterator for Decode<'_, T, C> {
     fn len(&self) -> usize {
         self.len - self.position
     }
diff --git a/percent_encoding/src/lib.rs b/percent_encoding/src/lib.rs
index efa04657a..b62924024 100644
--- a/percent_encoding/src/lib.rs
+++ b/percent_encoding/src/lib.rs
@@ -178,7 +178,7 @@ impl<'a> Iterator for PercentEncode<'a> {
     }
 }
 
-impl<'a> fmt::Display for PercentEncode<'a> {
+impl fmt::Display for PercentEncode<'_> {
     fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
         for c in (*self).clone() {
             formatter.write_str(c)?
@@ -254,7 +254,7 @@ fn after_percent_sign(iter: &mut slice::Iter<'_, u8>) -> Option<u8> {
     Some(h as u8 * 0x10 + l as u8)
 }
 
-impl<'a> Iterator for PercentDecode<'a> {
+impl Iterator for PercentDecode<'_> {
     type Item = u8;
 
     fn next(&mut self) -> Option<u8> {
diff --git a/url/src/host.rs b/url/src/host.rs
index f21a253d5..f45232c5d 100644
--- a/url/src/host.rs
+++ b/url/src/host.rs
@@ -64,7 +64,7 @@ pub enum Host<S = String> {
     Ipv6(Ipv6Addr),
 }
 
-impl<'a> Host<&'a str> {
+impl Host<&str> {
     /// Return a copy of `self` that owns an allocated `String` but does not borrow an `&Url`.
     pub fn to_owned(&self) -> Host<String> {
         match *self {
diff --git a/url/src/lib.rs b/url/src/lib.rs
index e015acce7..4fac74382 100644
--- a/url/src/lib.rs
+++ b/url/src/lib.rs
@@ -448,7 +448,7 @@ impl Url {
     /// let base = Url::parse("https://alice.com/a")?;
     /// let url = base.join("http://eve.com/b")?;
     /// assert_eq!(url.as_str(), "http://eve.com/b");  // http instead of https
-
+    ///
     /// # Ok(())
     /// # }
     /// # run().unwrap();
@@ -1492,7 +1492,7 @@ impl Url {
     /// # }
     /// # run().unwrap();
     /// ```
-
+    ///
     #[inline]
     pub fn query_pairs(&self) -> form_urlencoded::Parse<'_> {
         form_urlencoded::parse(self.query().unwrap_or("").as_bytes())
@@ -1555,7 +1555,7 @@ impl Url {
     /// # fn run() -> Result<(), ParseError> {
     /// let mut url = Url::parse("https://example.com/data.csv")?;
     /// assert_eq!(url.as_str(), "https://example.com/data.csv");
-
+    ///
     /// url.set_fragment(Some("cell=4,1-6,2"));
     /// assert_eq!(url.as_str(), "https://example.com/data.csv#cell=4,1-6,2");
     /// assert_eq!(url.fragment(), Some("cell=4,1-6,2"));
@@ -3177,7 +3177,7 @@ impl<'a> form_urlencoded::Target for UrlQuery<'a> {
     type Finished = &'a mut Url;
 }
 
-impl<'a> Drop for UrlQuery<'a> {
+impl Drop for UrlQuery<'_> {
     fn drop(&mut self) {
         if let Some(url) = self.url.take() {
             url.restore_already_parsed_fragment(self.fragment.take())
diff --git a/url/src/parser.rs b/url/src/parser.rs
index e26b50281..416484f19 100644
--- a/url/src/parser.rs
+++ b/url/src/parser.rs
@@ -301,7 +301,7 @@ impl Pattern for char {
     }
 }
 
-impl<'a> Pattern for &'a str {
+impl Pattern for &str {
     fn split_prefix(self, input: &mut Input) -> bool {
         for c in self.chars() {
             if input.next() != Some(c) {
@@ -318,7 +318,7 @@ impl<F: FnMut(char) -> bool> Pattern for F {
     }
 }
 
-impl<'i> Iterator for Input<'i> {
+impl Iterator for Input<'_> {
     type Item = char;
     fn next(&mut self) -> Option<char> {
         self.chars
diff --git a/url/src/path_segments.rs b/url/src/path_segments.rs
index 5cc8e7758..e6363c5c8 100644
--- a/url/src/path_segments.rs
+++ b/url/src/path_segments.rs
@@ -67,14 +67,14 @@ pub fn new(url: &mut Url) -> PathSegmentsMut<'_> {
     }
 }
 
-impl<'a> Drop for PathSegmentsMut<'a> {
+impl Drop for PathSegmentsMut<'_> {
     fn drop(&mut self) {
         self.url
             .restore_after_path(self.old_after_path_position, &self.after_path)
     }
 }
 
-impl<'a> PathSegmentsMut<'a> {
+impl PathSegmentsMut<'_> {
     /// Remove all segments in the path, leaving the minimal `url.path() == "/"`.
     ///
     /// Returns `&mut Self` so that method calls can be chained.