about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--library/alloc/src/str.rs4
-rw-r--r--library/alloc/src/string.rs27
-rw-r--r--library/alloc/tests/str.rs14
-rw-r--r--library/core/src/str/iter.rs90
-rw-r--r--library/core/src/str/mod.rs75
-rw-r--r--library/core/src/str/pattern.rs132
-rw-r--r--tests/ui/suggestions/issue-104961.fixed4
-rw-r--r--tests/ui/suggestions/issue-104961.rs4
-rw-r--r--tests/ui/suggestions/issue-104961.stderr12
-rw-r--r--tests/ui/suggestions/issue-62843.stderr6
-rw-r--r--tests/ui/traits/bound/assoc-fn-bound-root-obligation.rs12
-rw-r--r--tests/ui/traits/bound/assoc-fn-bound-root-obligation.stderr15
-rw-r--r--tests/ui/traits/suggest-dereferences/root-obligation.fixed2
-rw-r--r--tests/ui/traits/suggest-dereferences/root-obligation.rs2
-rw-r--r--tests/ui/traits/suggest-dereferences/root-obligation.stderr6
15 files changed, 207 insertions, 198 deletions
diff --git a/library/alloc/src/str.rs b/library/alloc/src/str.rs
index 3bb808a6c73..94053ef83a0 100644
--- a/library/alloc/src/str.rs
+++ b/library/alloc/src/str.rs
@@ -269,7 +269,7 @@ impl str {
                   without modifying the original"]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
-    pub fn replace<'a, P: Pattern<'a>>(&'a self, from: P, to: &str) -> String {
+    pub fn replace<P: Pattern>(&self, from: P, to: &str) -> String {
         let mut result = String::new();
         let mut last_end = 0;
         for (start, part) in self.match_indices(from) {
@@ -309,7 +309,7 @@ impl str {
     #[must_use = "this returns the replaced string as a new allocation, \
                   without modifying the original"]
     #[stable(feature = "str_replacen", since = "1.16.0")]
-    pub fn replacen<'a, P: Pattern<'a>>(&'a self, pat: P, to: &str, count: usize) -> String {
+    pub fn replacen<P: Pattern>(&self, pat: P, to: &str, count: usize) -> String {
         // Hope to reduce the times of re-allocation
         let mut result = String::with_capacity(32);
         let mut last_end = 0;
diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs
index 07ffd3e1519..0ff66167a46 100644
--- a/library/alloc/src/string.rs
+++ b/library/alloc/src/string.rs
@@ -1497,10 +1497,7 @@ impl String {
     /// ```
     #[cfg(not(no_global_oom_handling))]
     #[unstable(feature = "string_remove_matches", reason = "new API", issue = "72826")]
-    pub fn remove_matches<'a, P>(&'a mut self, pat: P)
-    where
-        P: for<'x> Pattern<'x>,
-    {
+    pub fn remove_matches<P: Pattern>(&mut self, pat: P) {
         use core::str::pattern::Searcher;
 
         let rejections = {
@@ -2288,35 +2285,41 @@ impl<'a> Extend<Cow<'a, str>> for String {
     reason = "API not fully fleshed out and ready to be stabilized",
     issue = "27721"
 )]
-impl<'a, 'b> Pattern<'a> for &'b String {
-    type Searcher = <&'b str as Pattern<'a>>::Searcher;
+impl<'b> Pattern for &'b String {
+    type Searcher<'a> = <&'b str as Pattern>::Searcher<'a>;
 
-    fn into_searcher(self, haystack: &'a str) -> <&'b str as Pattern<'a>>::Searcher {
+    fn into_searcher(self, haystack: &str) -> <&'b str as Pattern>::Searcher<'_> {
         self[..].into_searcher(haystack)
     }
 
     #[inline]
-    fn is_contained_in(self, haystack: &'a str) -> bool {
+    fn is_contained_in(self, haystack: &str) -> bool {
         self[..].is_contained_in(haystack)
     }
 
     #[inline]
-    fn is_prefix_of(self, haystack: &'a str) -> bool {
+    fn is_prefix_of(self, haystack: &str) -> bool {
         self[..].is_prefix_of(haystack)
     }
 
     #[inline]
-    fn strip_prefix_of(self, haystack: &'a str) -> Option<&'a str> {
+    fn strip_prefix_of(self, haystack: &str) -> Option<&str> {
         self[..].strip_prefix_of(haystack)
     }
 
     #[inline]
-    fn is_suffix_of(self, haystack: &'a str) -> bool {
+    fn is_suffix_of<'a>(self, haystack: &'a str) -> bool
+    where
+        Self::Searcher<'a>: core::str::pattern::ReverseSearcher<'a>,
+    {
         self[..].is_suffix_of(haystack)
     }
 
     #[inline]
-    fn strip_suffix_of(self, haystack: &'a str) -> Option<&'a str> {
+    fn strip_suffix_of<'a>(self, haystack: &'a str) -> Option<&str>
+    where
+        Self::Searcher<'a>: core::str::pattern::ReverseSearcher<'a>,
+    {
         self[..].strip_suffix_of(haystack)
     }
 }
diff --git a/library/alloc/tests/str.rs b/library/alloc/tests/str.rs
index 0078f5eaa3d..de5d3991c91 100644
--- a/library/alloc/tests/str.rs
+++ b/library/alloc/tests/str.rs
@@ -1927,12 +1927,10 @@ mod pattern {
         }
     }
 
-    fn cmp_search_to_vec<'a>(
-        rev: bool,
-        pat: impl Pattern<'a, Searcher: ReverseSearcher<'a>>,
-        haystack: &'a str,
-        right: Vec<SearchStep>,
-    ) {
+    fn cmp_search_to_vec<P>(rev: bool, pat: P, haystack: &str, right: Vec<SearchStep>)
+    where
+        P: for<'a> Pattern<Searcher<'a>: ReverseSearcher<'a>>,
+    {
         let mut searcher = pat.into_searcher(haystack);
         let mut v = vec![];
         loop {
@@ -2191,9 +2189,9 @@ generate_iterator_test! {
 fn different_str_pattern_forwarding_lifetimes() {
     use std::str::pattern::Pattern;
 
-    fn foo<'a, P>(p: P)
+    fn foo<P>(p: P)
     where
-        for<'b> &'b P: Pattern<'a>,
+        for<'b> &'b P: Pattern,
     {
         for _ in 0..3 {
             "asdf".find(&p);
diff --git a/library/core/src/str/iter.rs b/library/core/src/str/iter.rs
index 19627f28e64..5845e3b5481 100644
--- a/library/core/src/str/iter.rs
+++ b/library/core/src/str/iter.rs
@@ -411,7 +411,7 @@ macro_rules! derive_pattern_clone {
     (clone $t:ident with |$s:ident| $e:expr) => {
         impl<'a, P> Clone for $t<'a, P>
         where
-            P: Pattern<'a, Searcher: Clone>,
+            P: Pattern<Searcher<'a>: Clone>,
         {
             fn clone(&self) -> Self {
                 let $s = self;
@@ -424,7 +424,7 @@ macro_rules! derive_pattern_clone {
 /// This macro generates two public iterator structs
 /// wrapping a private internal one that makes use of the `Pattern` API.
 ///
-/// For all patterns `P: Pattern<'a>` the following items will be
+/// For all patterns `P: Pattern` the following items will be
 /// generated (generics omitted):
 ///
 /// struct $forward_iterator($internal_iterator);
@@ -484,12 +484,12 @@ macro_rules! generate_pattern_iterators {
     } => {
         $(#[$forward_iterator_attribute])*
         $(#[$common_stability_attribute])*
-        pub struct $forward_iterator<'a, P: Pattern<'a>>(pub(super) $internal_iterator<'a, P>);
+        pub struct $forward_iterator<'a, P: Pattern>(pub(super) $internal_iterator<'a, P>);
 
         $(#[$common_stability_attribute])*
         impl<'a, P> fmt::Debug for $forward_iterator<'a, P>
         where
-            P: Pattern<'a, Searcher: fmt::Debug>,
+            P: Pattern<Searcher<'a>: fmt::Debug>,
         {
             fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
                 f.debug_tuple(stringify!($forward_iterator))
@@ -499,7 +499,7 @@ macro_rules! generate_pattern_iterators {
         }
 
         $(#[$common_stability_attribute])*
-        impl<'a, P: Pattern<'a>> Iterator for $forward_iterator<'a, P> {
+        impl<'a, P: Pattern> Iterator for $forward_iterator<'a, P> {
             type Item = $iterty;
 
             #[inline]
@@ -511,7 +511,7 @@ macro_rules! generate_pattern_iterators {
         $(#[$common_stability_attribute])*
         impl<'a, P> Clone for $forward_iterator<'a, P>
         where
-            P: Pattern<'a, Searcher: Clone>,
+            P: Pattern<Searcher<'a>: Clone>,
         {
             fn clone(&self) -> Self {
                 $forward_iterator(self.0.clone())
@@ -520,12 +520,12 @@ macro_rules! generate_pattern_iterators {
 
         $(#[$reverse_iterator_attribute])*
         $(#[$common_stability_attribute])*
-        pub struct $reverse_iterator<'a, P: Pattern<'a>>(pub(super) $internal_iterator<'a, P>);
+        pub struct $reverse_iterator<'a, P: Pattern>(pub(super) $internal_iterator<'a, P>);
 
         $(#[$common_stability_attribute])*
         impl<'a, P> fmt::Debug for $reverse_iterator<'a, P>
         where
-            P: Pattern<'a, Searcher: fmt::Debug>,
+            P: Pattern<Searcher<'a>: fmt::Debug>,
         {
             fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
                 f.debug_tuple(stringify!($reverse_iterator))
@@ -537,7 +537,7 @@ macro_rules! generate_pattern_iterators {
         $(#[$common_stability_attribute])*
         impl<'a, P> Iterator for $reverse_iterator<'a, P>
         where
-            P: Pattern<'a, Searcher: ReverseSearcher<'a>>,
+            P: Pattern<Searcher<'a>: ReverseSearcher<'a>>,
         {
             type Item = $iterty;
 
@@ -550,7 +550,7 @@ macro_rules! generate_pattern_iterators {
         $(#[$common_stability_attribute])*
         impl<'a, P> Clone for $reverse_iterator<'a, P>
         where
-            P: Pattern<'a, Searcher: Clone>,
+            P: Pattern<Searcher<'a>: Clone>,
         {
             fn clone(&self) -> Self {
                 $reverse_iterator(self.0.clone())
@@ -558,12 +558,12 @@ macro_rules! generate_pattern_iterators {
         }
 
         #[stable(feature = "fused", since = "1.26.0")]
-        impl<'a, P: Pattern<'a>> FusedIterator for $forward_iterator<'a, P> {}
+        impl<'a, P: Pattern> FusedIterator for $forward_iterator<'a, P> {}
 
         #[stable(feature = "fused", since = "1.26.0")]
         impl<'a, P> FusedIterator for $reverse_iterator<'a, P>
         where
-            P: Pattern<'a, Searcher: ReverseSearcher<'a>>,
+            P: Pattern<Searcher<'a>: ReverseSearcher<'a>>,
         {}
 
         generate_pattern_iterators!($($t)* with $(#[$common_stability_attribute])*,
@@ -578,7 +578,7 @@ macro_rules! generate_pattern_iterators {
         $(#[$common_stability_attribute])*
         impl<'a, P> DoubleEndedIterator for $forward_iterator<'a, P>
         where
-            P: Pattern<'a, Searcher: DoubleEndedSearcher<'a>>,
+            P: Pattern<Searcher<'a>: DoubleEndedSearcher<'a>>,
         {
             #[inline]
             fn next_back(&mut self) -> Option<$iterty> {
@@ -589,7 +589,7 @@ macro_rules! generate_pattern_iterators {
         $(#[$common_stability_attribute])*
         impl<'a, P> DoubleEndedIterator for $reverse_iterator<'a, P>
         where
-            P: Pattern<'a, Searcher: DoubleEndedSearcher<'a>>,
+            P: Pattern<Searcher<'a>: DoubleEndedSearcher<'a>>,
         {
             #[inline]
             fn next_back(&mut self) -> Option<$iterty> {
@@ -609,17 +609,17 @@ derive_pattern_clone! {
     with |s| SplitInternal { matcher: s.matcher.clone(), ..*s }
 }
 
-pub(super) struct SplitInternal<'a, P: Pattern<'a>> {
+pub(super) struct SplitInternal<'a, P: Pattern> {
     pub(super) start: usize,
     pub(super) end: usize,
-    pub(super) matcher: P::Searcher,
+    pub(super) matcher: P::Searcher<'a>,
     pub(super) allow_trailing_empty: bool,
     pub(super) finished: bool,
 }
 
 impl<'a, P> fmt::Debug for SplitInternal<'a, P>
 where
-    P: Pattern<'a, Searcher: fmt::Debug>,
+    P: Pattern<Searcher<'a>: fmt::Debug>,
 {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         f.debug_struct("SplitInternal")
@@ -632,7 +632,7 @@ where
     }
 }
 
-impl<'a, P: Pattern<'a>> SplitInternal<'a, P> {
+impl<'a, P: Pattern> SplitInternal<'a, P> {
     #[inline]
     fn get_end(&mut self) -> Option<&'a str> {
         if !self.finished {
@@ -689,7 +689,7 @@ impl<'a, P: Pattern<'a>> SplitInternal<'a, P> {
     #[inline]
     fn next_back(&mut self) -> Option<&'a str>
     where
-        P::Searcher: ReverseSearcher<'a>,
+        P::Searcher<'a>: ReverseSearcher<'a>,
     {
         if self.finished {
             return None;
@@ -726,7 +726,7 @@ impl<'a, P: Pattern<'a>> SplitInternal<'a, P> {
     #[inline]
     fn next_back_inclusive(&mut self) -> Option<&'a str>
     where
-        P::Searcher: ReverseSearcher<'a>,
+        P::Searcher<'a>: ReverseSearcher<'a>,
     {
         if self.finished {
             return None;
@@ -796,7 +796,7 @@ generate_pattern_iterators! {
     delegate double ended;
 }
 
-impl<'a, P: Pattern<'a>> Split<'a, P> {
+impl<'a, P: Pattern> Split<'a, P> {
     /// Returns remainder of the split string.
     ///
     /// If the iterator is empty, returns `None`.
@@ -819,7 +819,7 @@ impl<'a, P: Pattern<'a>> Split<'a, P> {
     }
 }
 
-impl<'a, P: Pattern<'a>> RSplit<'a, P> {
+impl<'a, P: Pattern> RSplit<'a, P> {
     /// Returns remainder of the split string.
     ///
     /// If the iterator is empty, returns `None`.
@@ -860,7 +860,7 @@ generate_pattern_iterators! {
     delegate double ended;
 }
 
-impl<'a, P: Pattern<'a>> SplitTerminator<'a, P> {
+impl<'a, P: Pattern> SplitTerminator<'a, P> {
     /// Returns remainder of the split string.
     ///
     /// If the iterator is empty, returns `None`.
@@ -883,7 +883,7 @@ impl<'a, P: Pattern<'a>> SplitTerminator<'a, P> {
     }
 }
 
-impl<'a, P: Pattern<'a>> RSplitTerminator<'a, P> {
+impl<'a, P: Pattern> RSplitTerminator<'a, P> {
     /// Returns remainder of the split string.
     ///
     /// If the iterator is empty, returns `None`.
@@ -911,7 +911,7 @@ derive_pattern_clone! {
     with |s| SplitNInternal { iter: s.iter.clone(), ..*s }
 }
 
-pub(super) struct SplitNInternal<'a, P: Pattern<'a>> {
+pub(super) struct SplitNInternal<'a, P: Pattern> {
     pub(super) iter: SplitInternal<'a, P>,
     /// The number of splits remaining
     pub(super) count: usize,
@@ -919,7 +919,7 @@ pub(super) struct SplitNInternal<'a, P: Pattern<'a>> {
 
 impl<'a, P> fmt::Debug for SplitNInternal<'a, P>
 where
-    P: Pattern<'a, Searcher: fmt::Debug>,
+    P: Pattern<Searcher<'a>: fmt::Debug>,
 {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         f.debug_struct("SplitNInternal")
@@ -929,7 +929,7 @@ where
     }
 }
 
-impl<'a, P: Pattern<'a>> SplitNInternal<'a, P> {
+impl<'a, P: Pattern> SplitNInternal<'a, P> {
     #[inline]
     fn next(&mut self) -> Option<&'a str> {
         match self.count {
@@ -948,7 +948,7 @@ impl<'a, P: Pattern<'a>> SplitNInternal<'a, P> {
     #[inline]
     fn next_back(&mut self) -> Option<&'a str>
     where
-        P::Searcher: ReverseSearcher<'a>,
+        P::Searcher<'a>: ReverseSearcher<'a>,
     {
         match self.count {
             0 => None,
@@ -987,7 +987,7 @@ generate_pattern_iterators! {
     delegate single ended;
 }
 
-impl<'a, P: Pattern<'a>> SplitN<'a, P> {
+impl<'a, P: Pattern> SplitN<'a, P> {
     /// Returns remainder of the split string.
     ///
     /// If the iterator is empty, returns `None`.
@@ -1010,7 +1010,7 @@ impl<'a, P: Pattern<'a>> SplitN<'a, P> {
     }
 }
 
-impl<'a, P: Pattern<'a>> RSplitN<'a, P> {
+impl<'a, P: Pattern> RSplitN<'a, P> {
     /// Returns remainder of the split string.
     ///
     /// If the iterator is empty, returns `None`.
@@ -1038,18 +1038,18 @@ derive_pattern_clone! {
     with |s| MatchIndicesInternal(s.0.clone())
 }
 
-pub(super) struct MatchIndicesInternal<'a, P: Pattern<'a>>(pub(super) P::Searcher);
+pub(super) struct MatchIndicesInternal<'a, P: Pattern>(pub(super) P::Searcher<'a>);
 
 impl<'a, P> fmt::Debug for MatchIndicesInternal<'a, P>
 where
-    P: Pattern<'a, Searcher: fmt::Debug>,
+    P: Pattern<Searcher<'a>: fmt::Debug>,
 {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         f.debug_tuple("MatchIndicesInternal").field(&self.0).finish()
     }
 }
 
-impl<'a, P: Pattern<'a>> MatchIndicesInternal<'a, P> {
+impl<'a, P: Pattern> MatchIndicesInternal<'a, P> {
     #[inline]
     fn next(&mut self) -> Option<(usize, &'a str)> {
         self.0
@@ -1061,7 +1061,7 @@ impl<'a, P: Pattern<'a>> MatchIndicesInternal<'a, P> {
     #[inline]
     fn next_back(&mut self) -> Option<(usize, &'a str)>
     where
-        P::Searcher: ReverseSearcher<'a>,
+        P::Searcher<'a>: ReverseSearcher<'a>,
     {
         self.0
             .next_match_back()
@@ -1093,18 +1093,18 @@ derive_pattern_clone! {
     with |s| MatchesInternal(s.0.clone())
 }
 
-pub(super) struct MatchesInternal<'a, P: Pattern<'a>>(pub(super) P::Searcher);
+pub(super) struct MatchesInternal<'a, P: Pattern>(pub(super) P::Searcher<'a>);
 
 impl<'a, P> fmt::Debug for MatchesInternal<'a, P>
 where
-    P: Pattern<'a, Searcher: fmt::Debug>,
+    P: Pattern<Searcher<'a>: fmt::Debug>,
 {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         f.debug_tuple("MatchesInternal").field(&self.0).finish()
     }
 }
 
-impl<'a, P: Pattern<'a>> MatchesInternal<'a, P> {
+impl<'a, P: Pattern> MatchesInternal<'a, P> {
     #[inline]
     fn next(&mut self) -> Option<&'a str> {
         // SAFETY: `Searcher` guarantees that `start` and `end` lie on unicode boundaries.
@@ -1117,7 +1117,7 @@ impl<'a, P: Pattern<'a>> MatchesInternal<'a, P> {
     #[inline]
     fn next_back(&mut self) -> Option<&'a str>
     where
-        P::Searcher: ReverseSearcher<'a>,
+        P::Searcher<'a>: ReverseSearcher<'a>,
     {
         // SAFETY: `Searcher` guarantees that `start` and `end` lie on unicode boundaries.
         self.0.next_match_back().map(|(a, b)| unsafe {
@@ -1288,7 +1288,7 @@ pub struct SplitAsciiWhitespace<'a> {
 ///
 /// [`split_inclusive`]: str::split_inclusive
 #[stable(feature = "split_inclusive", since = "1.51.0")]
-pub struct SplitInclusive<'a, P: Pattern<'a>>(pub(super) SplitInternal<'a, P>);
+pub struct SplitInclusive<'a, P: Pattern>(pub(super) SplitInternal<'a, P>);
 
 #[stable(feature = "split_whitespace", since = "1.1.0")]
 impl<'a> Iterator for SplitWhitespace<'a> {
@@ -1410,7 +1410,7 @@ impl<'a> SplitAsciiWhitespace<'a> {
 }
 
 #[stable(feature = "split_inclusive", since = "1.51.0")]
-impl<'a, P: Pattern<'a>> Iterator for SplitInclusive<'a, P> {
+impl<'a, P: Pattern> Iterator for SplitInclusive<'a, P> {
     type Item = &'a str;
 
     #[inline]
@@ -1420,7 +1420,7 @@ impl<'a, P: Pattern<'a>> Iterator for SplitInclusive<'a, P> {
 }
 
 #[stable(feature = "split_inclusive", since = "1.51.0")]
-impl<'a, P: Pattern<'a, Searcher: fmt::Debug>> fmt::Debug for SplitInclusive<'a, P> {
+impl<'a, P: Pattern<Searcher<'a>: fmt::Debug>> fmt::Debug for SplitInclusive<'a, P> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         f.debug_struct("SplitInclusive").field("0", &self.0).finish()
     }
@@ -1428,14 +1428,14 @@ impl<'a, P: Pattern<'a, Searcher: fmt::Debug>> fmt::Debug for SplitInclusive<'a,
 
 // FIXME(#26925) Remove in favor of `#[derive(Clone)]`
 #[stable(feature = "split_inclusive", since = "1.51.0")]
-impl<'a, P: Pattern<'a, Searcher: Clone>> Clone for SplitInclusive<'a, P> {
+impl<'a, P: Pattern<Searcher<'a>: Clone>> Clone for SplitInclusive<'a, P> {
     fn clone(&self) -> Self {
         SplitInclusive(self.0.clone())
     }
 }
 
 #[stable(feature = "split_inclusive", since = "1.51.0")]
-impl<'a, P: Pattern<'a, Searcher: DoubleEndedSearcher<'a>>> DoubleEndedIterator
+impl<'a, P: Pattern<Searcher<'a>: DoubleEndedSearcher<'a>>> DoubleEndedIterator
     for SplitInclusive<'a, P>
 {
     #[inline]
@@ -1445,9 +1445,9 @@ impl<'a, P: Pattern<'a, Searcher: DoubleEndedSearcher<'a>>> DoubleEndedIterator
 }
 
 #[stable(feature = "split_inclusive", since = "1.51.0")]
-impl<'a, P: Pattern<'a>> FusedIterator for SplitInclusive<'a, P> {}
+impl<'a, P: Pattern> FusedIterator for SplitInclusive<'a, P> {}
 
-impl<'a, P: Pattern<'a>> SplitInclusive<'a, P> {
+impl<'a, P: Pattern> SplitInclusive<'a, P> {
     /// Returns remainder of the split string.
     ///
     /// If the iterator is empty, returns `None`.
diff --git a/library/core/src/str/mod.rs b/library/core/src/str/mod.rs
index 1392fd7e7cd..6cd029f7436 100644
--- a/library/core/src/str/mod.rs
+++ b/library/core/src/str/mod.rs
@@ -1138,7 +1138,7 @@ impl str {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
-    pub fn contains<'a, P: Pattern<'a>>(&'a self, pat: P) -> bool {
+    pub fn contains<P: Pattern>(&self, pat: P) -> bool {
         pat.is_contained_in(self)
     }
 
@@ -1175,7 +1175,7 @@ impl str {
     /// assert!(bananas.starts_with(&['a', 'b', 'c', 'd']));
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn starts_with<'a, P: Pattern<'a>>(&'a self, pat: P) -> bool {
+    pub fn starts_with<P: Pattern>(&self, pat: P) -> bool {
         pat.is_prefix_of(self)
     }
 
@@ -1199,9 +1199,9 @@ impl str {
     /// assert!(!bananas.ends_with("nana"));
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn ends_with<'a, P>(&'a self, pat: P) -> bool
+    pub fn ends_with<P: Pattern>(&self, pat: P) -> bool
     where
-        P: Pattern<'a, Searcher: ReverseSearcher<'a>>,
+        for<'a> P::Searcher<'a>: ReverseSearcher<'a>,
     {
         pat.is_suffix_of(self)
     }
@@ -1250,7 +1250,7 @@ impl str {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
-    pub fn find<'a, P: Pattern<'a>>(&'a self, pat: P) -> Option<usize> {
+    pub fn find<P: Pattern>(&self, pat: P) -> Option<usize> {
         pat.into_searcher(self).next_match().map(|(i, _)| i)
     }
 
@@ -1296,9 +1296,9 @@ impl str {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
-    pub fn rfind<'a, P>(&'a self, pat: P) -> Option<usize>
+    pub fn rfind<P: Pattern>(&self, pat: P) -> Option<usize>
     where
-        P: Pattern<'a, Searcher: ReverseSearcher<'a>>,
+        for<'a> P::Searcher<'a>: ReverseSearcher<'a>,
     {
         pat.into_searcher(self).next_match_back().map(|(i, _)| i)
     }
@@ -1418,7 +1418,7 @@ impl str {
     /// [`split_whitespace`]: str::split_whitespace
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
-    pub fn split<'a, P: Pattern<'a>>(&'a self, pat: P) -> Split<'a, P> {
+    pub fn split<P: Pattern>(&self, pat: P) -> Split<'_, P> {
         Split(SplitInternal {
             start: 0,
             end: self.len(),
@@ -1458,7 +1458,7 @@ impl str {
     /// ```
     #[stable(feature = "split_inclusive", since = "1.51.0")]
     #[inline]
-    pub fn split_inclusive<'a, P: Pattern<'a>>(&'a self, pat: P) -> SplitInclusive<'a, P> {
+    pub fn split_inclusive<P: Pattern>(&self, pat: P) -> SplitInclusive<'_, P> {
         SplitInclusive(SplitInternal {
             start: 0,
             end: self.len(),
@@ -1513,9 +1513,9 @@ impl str {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
-    pub fn rsplit<'a, P>(&'a self, pat: P) -> RSplit<'a, P>
+    pub fn rsplit<P: Pattern>(&self, pat: P) -> RSplit<'_, P>
     where
-        P: Pattern<'a, Searcher: ReverseSearcher<'a>>,
+        for<'a> P::Searcher<'a>: ReverseSearcher<'a>,
     {
         RSplit(self.split(pat).0)
     }
@@ -1562,7 +1562,7 @@ impl str {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
-    pub fn split_terminator<'a, P: Pattern<'a>>(&'a self, pat: P) -> SplitTerminator<'a, P> {
+    pub fn split_terminator<P: Pattern>(&self, pat: P) -> SplitTerminator<'_, P> {
         SplitTerminator(SplitInternal { allow_trailing_empty: false, ..self.split(pat).0 })
     }
 
@@ -1608,9 +1608,9 @@ impl str {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
-    pub fn rsplit_terminator<'a, P>(&'a self, pat: P) -> RSplitTerminator<'a, P>
+    pub fn rsplit_terminator<P: Pattern>(&self, pat: P) -> RSplitTerminator<'_, P>
     where
-        P: Pattern<'a, Searcher: ReverseSearcher<'a>>,
+        for<'a> P::Searcher<'a>: ReverseSearcher<'a>,
     {
         RSplitTerminator(self.split_terminator(pat).0)
     }
@@ -1663,7 +1663,7 @@ impl str {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
-    pub fn splitn<'a, P: Pattern<'a>>(&'a self, n: usize, pat: P) -> SplitN<'a, P> {
+    pub fn splitn<P: Pattern>(&self, n: usize, pat: P) -> SplitN<'_, P> {
         SplitN(SplitNInternal { iter: self.split(pat).0, count: n })
     }
 
@@ -1712,9 +1712,9 @@ impl str {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
-    pub fn rsplitn<'a, P>(&'a self, n: usize, pat: P) -> RSplitN<'a, P>
+    pub fn rsplitn<P: Pattern>(&self, n: usize, pat: P) -> RSplitN<'_, P>
     where
-        P: Pattern<'a, Searcher: ReverseSearcher<'a>>,
+        for<'a> P::Searcher<'a>: ReverseSearcher<'a>,
     {
         RSplitN(self.splitn(n, pat).0)
     }
@@ -1732,7 +1732,7 @@ impl str {
     /// ```
     #[stable(feature = "str_split_once", since = "1.52.0")]
     #[inline]
-    pub fn split_once<'a, P: Pattern<'a>>(&'a self, delimiter: P) -> Option<(&'a str, &'a str)> {
+    pub fn split_once<P: Pattern>(&self, delimiter: P) -> Option<(&'_ str, &'_ str)> {
         let (start, end) = delimiter.into_searcher(self).next_match()?;
         // SAFETY: `Searcher` is known to return valid indices.
         unsafe { Some((self.get_unchecked(..start), self.get_unchecked(end..))) }
@@ -1750,9 +1750,9 @@ impl str {
     /// ```
     #[stable(feature = "str_split_once", since = "1.52.0")]
     #[inline]
-    pub fn rsplit_once<'a, P>(&'a self, delimiter: P) -> Option<(&'a str, &'a str)>
+    pub fn rsplit_once<P: Pattern>(&self, delimiter: P) -> Option<(&'_ str, &'_ str)>
     where
-        P: Pattern<'a, Searcher: ReverseSearcher<'a>>,
+        for<'a> P::Searcher<'a>: ReverseSearcher<'a>,
     {
         let (start, end) = delimiter.into_searcher(self).next_match_back()?;
         // SAFETY: `Searcher` is known to return valid indices.
@@ -1790,7 +1790,7 @@ impl str {
     /// ```
     #[stable(feature = "str_matches", since = "1.2.0")]
     #[inline]
-    pub fn matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> Matches<'a, P> {
+    pub fn matches<P: Pattern>(&self, pat: P) -> Matches<'_, P> {
         Matches(MatchesInternal(pat.into_searcher(self)))
     }
 
@@ -1824,9 +1824,9 @@ impl str {
     /// ```
     #[stable(feature = "str_matches", since = "1.2.0")]
     #[inline]
-    pub fn rmatches<'a, P>(&'a self, pat: P) -> RMatches<'a, P>
+    pub fn rmatches<P: Pattern>(&self, pat: P) -> RMatches<'_, P>
     where
-        P: Pattern<'a, Searcher: ReverseSearcher<'a>>,
+        for<'a> P::Searcher<'a>: ReverseSearcher<'a>,
     {
         RMatches(self.matches(pat).0)
     }
@@ -1868,7 +1868,7 @@ impl str {
     /// ```
     #[stable(feature = "str_match_indices", since = "1.5.0")]
     #[inline]
-    pub fn match_indices<'a, P: Pattern<'a>>(&'a self, pat: P) -> MatchIndices<'a, P> {
+    pub fn match_indices<P: Pattern>(&self, pat: P) -> MatchIndices<'_, P> {
         MatchIndices(MatchIndicesInternal(pat.into_searcher(self)))
     }
 
@@ -1908,9 +1908,9 @@ impl str {
     /// ```
     #[stable(feature = "str_match_indices", since = "1.5.0")]
     #[inline]
-    pub fn rmatch_indices<'a, P>(&'a self, pat: P) -> RMatchIndices<'a, P>
+    pub fn rmatch_indices<P: Pattern>(&self, pat: P) -> RMatchIndices<'_, P>
     where
-        P: Pattern<'a, Searcher: ReverseSearcher<'a>>,
+        for<'a> P::Searcher<'a>: ReverseSearcher<'a>,
     {
         RMatchIndices(self.match_indices(pat).0)
     }
@@ -2123,9 +2123,9 @@ impl str {
     #[must_use = "this returns the trimmed string as a new slice, \
                   without modifying the original"]
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn trim_matches<'a, P>(&'a self, pat: P) -> &'a str
+    pub fn trim_matches<P: Pattern>(&self, pat: P) -> &str
     where
-        P: Pattern<'a, Searcher: DoubleEndedSearcher<'a>>,
+        for<'a> P::Searcher<'a>: DoubleEndedSearcher<'a>,
     {
         let mut i = 0;
         let mut j = 0;
@@ -2170,7 +2170,7 @@ impl str {
     #[must_use = "this returns the trimmed string as a new slice, \
                   without modifying the original"]
     #[stable(feature = "trim_direction", since = "1.30.0")]
-    pub fn trim_start_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str {
+    pub fn trim_start_matches<P: Pattern>(&self, pat: P) -> &str {
         let mut i = self.len();
         let mut matcher = pat.into_searcher(self);
         if let Some((a, _)) = matcher.next_reject() {
@@ -2203,7 +2203,7 @@ impl str {
     #[must_use = "this returns the remaining substring as a new slice, \
                   without modifying the original"]
     #[stable(feature = "str_strip", since = "1.45.0")]
-    pub fn strip_prefix<'a, P: Pattern<'a>>(&'a self, prefix: P) -> Option<&'a str> {
+    pub fn strip_prefix<P: Pattern>(&self, prefix: P) -> Option<&str> {
         prefix.strip_prefix_of(self)
     }
 
@@ -2230,10 +2230,9 @@ impl str {
     #[must_use = "this returns the remaining substring as a new slice, \
                   without modifying the original"]
     #[stable(feature = "str_strip", since = "1.45.0")]
-    pub fn strip_suffix<'a, P>(&'a self, suffix: P) -> Option<&'a str>
+    pub fn strip_suffix<P: Pattern>(&self, suffix: P) -> Option<&str>
     where
-        P: Pattern<'a>,
-        <P as Pattern<'a>>::Searcher: ReverseSearcher<'a>,
+        for<'a> P::Searcher<'a>: ReverseSearcher<'a>,
     {
         suffix.strip_suffix_of(self)
     }
@@ -2274,9 +2273,9 @@ impl str {
     #[must_use = "this returns the trimmed string as a new slice, \
                   without modifying the original"]
     #[stable(feature = "trim_direction", since = "1.30.0")]
-    pub fn trim_end_matches<'a, P>(&'a self, pat: P) -> &'a str
+    pub fn trim_end_matches<P: Pattern>(&self, pat: P) -> &str
     where
-        P: Pattern<'a, Searcher: ReverseSearcher<'a>>,
+        for<'a> P::Searcher<'a>: ReverseSearcher<'a>,
     {
         let mut j = 0;
         let mut matcher = pat.into_searcher(self);
@@ -2318,7 +2317,7 @@ impl str {
         note = "superseded by `trim_start_matches`",
         suggestion = "trim_start_matches"
     )]
-    pub fn trim_left_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str {
+    pub fn trim_left_matches<P: Pattern>(&self, pat: P) -> &str {
         self.trim_start_matches(pat)
     }
 
@@ -2361,9 +2360,9 @@ impl str {
         note = "superseded by `trim_end_matches`",
         suggestion = "trim_end_matches"
     )]
-    pub fn trim_right_matches<'a, P>(&'a self, pat: P) -> &'a str
+    pub fn trim_right_matches<P: Pattern>(&self, pat: P) -> &str
     where
-        P: Pattern<'a, Searcher: ReverseSearcher<'a>>,
+        for<'a> P::Searcher<'a>: ReverseSearcher<'a>,
     {
         self.trim_end_matches(pat)
     }
diff --git a/library/core/src/str/pattern.rs b/library/core/src/str/pattern.rs
index 8988229be2e..33a5d45e445 100644
--- a/library/core/src/str/pattern.rs
+++ b/library/core/src/str/pattern.rs
@@ -48,8 +48,8 @@ use crate::slice::memchr;
 
 /// A string pattern.
 ///
-/// A `Pattern<'a>` expresses that the implementing type
-/// can be used as a string pattern for searching in a [`&'a str`][str].
+/// A `Pattern` expresses that the implementing type
+/// can be used as a string pattern for searching in a [`&str`][str].
 ///
 /// For example, both `'a'` and `"aa"` are patterns that
 /// would match at index `1` in the string `"baaaab"`.
@@ -97,38 +97,38 @@ use crate::slice::memchr;
 /// assert_eq!("abcdef_z".find(|ch| ch > 'd' && ch < 'y'), Some(4));
 /// assert_eq!("abcddd_z".find(|ch| ch > 'd' && ch < 'y'), None);
 /// ```
-pub trait Pattern<'a>: Sized {
+pub trait Pattern: Sized {
     /// Associated searcher for this pattern
-    type Searcher: Searcher<'a>;
+    type Searcher<'a>: Searcher<'a>;
 
     /// Constructs the associated searcher from
     /// `self` and the `haystack` to search in.
-    fn into_searcher(self, haystack: &'a str) -> Self::Searcher;
+    fn into_searcher(self, haystack: &str) -> Self::Searcher<'_>;
 
     /// Checks whether the pattern matches anywhere in the haystack
     #[inline]
-    fn is_contained_in(self, haystack: &'a str) -> bool {
+    fn is_contained_in(self, haystack: &str) -> bool {
         self.into_searcher(haystack).next_match().is_some()
     }
 
     /// Checks whether the pattern matches at the front of the haystack
     #[inline]
-    fn is_prefix_of(self, haystack: &'a str) -> bool {
+    fn is_prefix_of(self, haystack: &str) -> bool {
         matches!(self.into_searcher(haystack).next(), SearchStep::Match(0, _))
     }
 
     /// Checks whether the pattern matches at the back of the haystack
     #[inline]
-    fn is_suffix_of(self, haystack: &'a str) -> bool
+    fn is_suffix_of<'a>(self, haystack: &'a str) -> bool
     where
-        Self::Searcher: ReverseSearcher<'a>,
+        Self::Searcher<'a>: ReverseSearcher<'a>,
     {
         matches!(self.into_searcher(haystack).next_back(), SearchStep::Match(_, j) if haystack.len() == j)
     }
 
     /// Removes the pattern from the front of haystack, if it matches.
     #[inline]
-    fn strip_prefix_of(self, haystack: &'a str) -> Option<&'a str> {
+    fn strip_prefix_of(self, haystack: &str) -> Option<&str> {
         if let SearchStep::Match(start, len) = self.into_searcher(haystack).next() {
             debug_assert_eq!(
                 start, 0,
@@ -144,9 +144,9 @@ pub trait Pattern<'a>: Sized {
 
     /// Removes the pattern from the back of haystack, if it matches.
     #[inline]
-    fn strip_suffix_of(self, haystack: &'a str) -> Option<&'a str>
+    fn strip_suffix_of<'a>(self, haystack: &'a str) -> Option<&'a str>
     where
-        Self::Searcher: ReverseSearcher<'a>,
+        Self::Searcher<'a>: ReverseSearcher<'a>,
     {
         if let SearchStep::Match(start, end) = self.into_searcher(haystack).next_back() {
             debug_assert_eq!(
@@ -349,7 +349,7 @@ pub trait DoubleEndedSearcher<'a>: ReverseSearcher<'a> {}
 // Impl for char
 /////////////////////////////////////////////////////////////////////////////
 
-/// Associated type for `<char as Pattern<'a>>::Searcher`.
+/// Associated type for `<char as Pattern>::Searcher<'a>`.
 #[derive(Clone, Debug)]
 pub struct CharSearcher<'a> {
     haystack: &'a str,
@@ -543,11 +543,11 @@ impl<'a> DoubleEndedSearcher<'a> for CharSearcher<'a> {}
 /// ```
 /// assert_eq!("Hello world".find('o'), Some(4));
 /// ```
-impl<'a> Pattern<'a> for char {
-    type Searcher = CharSearcher<'a>;
+impl Pattern for char {
+    type Searcher<'a> = CharSearcher<'a>;
 
     #[inline]
-    fn into_searcher(self, haystack: &'a str) -> Self::Searcher {
+    fn into_searcher(self, haystack: &str) -> Self::Searcher<'_> {
         let mut utf8_encoded = [0; 4];
         let utf8_size = self
             .encode_utf8(&mut utf8_encoded)
@@ -566,7 +566,7 @@ impl<'a> Pattern<'a> for char {
     }
 
     #[inline]
-    fn is_contained_in(self, haystack: &'a str) -> bool {
+    fn is_contained_in(self, haystack: &str) -> bool {
         if (self as u32) < 128 {
             haystack.as_bytes().contains(&(self as u8))
         } else {
@@ -576,27 +576,27 @@ impl<'a> Pattern<'a> for char {
     }
 
     #[inline]
-    fn is_prefix_of(self, haystack: &'a str) -> bool {
+    fn is_prefix_of(self, haystack: &str) -> bool {
         self.encode_utf8(&mut [0u8; 4]).is_prefix_of(haystack)
     }
 
     #[inline]
-    fn strip_prefix_of(self, haystack: &'a str) -> Option<&'a str> {
+    fn strip_prefix_of(self, haystack: &str) -> Option<&str> {
         self.encode_utf8(&mut [0u8; 4]).strip_prefix_of(haystack)
     }
 
     #[inline]
-    fn is_suffix_of(self, haystack: &'a str) -> bool
+    fn is_suffix_of<'a>(self, haystack: &'a str) -> bool
     where
-        Self::Searcher: ReverseSearcher<'a>,
+        Self::Searcher<'a>: ReverseSearcher<'a>,
     {
         self.encode_utf8(&mut [0u8; 4]).is_suffix_of(haystack)
     }
 
     #[inline]
-    fn strip_suffix_of(self, haystack: &'a str) -> Option<&'a str>
+    fn strip_suffix_of<'a>(self, haystack: &'a str) -> Option<&'a str>
     where
-        Self::Searcher: ReverseSearcher<'a>,
+        Self::Searcher<'a>: ReverseSearcher<'a>,
     {
         self.encode_utf8(&mut [0u8; 4]).strip_suffix_of(haystack)
     }
@@ -651,11 +651,11 @@ struct MultiCharEqSearcher<'a, C: MultiCharEq> {
     char_indices: super::CharIndices<'a>,
 }
 
-impl<'a, C: MultiCharEq> Pattern<'a> for MultiCharEqPattern<C> {
-    type Searcher = MultiCharEqSearcher<'a, C>;
+impl<C: MultiCharEq> Pattern for MultiCharEqPattern<C> {
+    type Searcher<'a> = MultiCharEqSearcher<'a, C>;
 
     #[inline]
-    fn into_searcher(self, haystack: &'a str) -> MultiCharEqSearcher<'a, C> {
+    fn into_searcher(self, haystack: &str) -> MultiCharEqSearcher<'_, C> {
         MultiCharEqSearcher { haystack, char_eq: self.0, char_indices: haystack.char_indices() }
     }
 }
@@ -710,41 +710,41 @@ impl<'a, C: MultiCharEq> DoubleEndedSearcher<'a> for MultiCharEqSearcher<'a, C>
 /////////////////////////////////////////////////////////////////////////////
 
 macro_rules! pattern_methods {
-    ($t:ty, $pmap:expr, $smap:expr) => {
-        type Searcher = $t;
+    ($a:lifetime, $t:ty, $pmap:expr, $smap:expr) => {
+        type Searcher<$a> = $t;
 
         #[inline]
-        fn into_searcher(self, haystack: &'a str) -> $t {
+        fn into_searcher<$a>(self, haystack: &$a str) -> $t {
             ($smap)(($pmap)(self).into_searcher(haystack))
         }
 
         #[inline]
-        fn is_contained_in(self, haystack: &'a str) -> bool {
+        fn is_contained_in<$a>(self, haystack: &$a str) -> bool {
             ($pmap)(self).is_contained_in(haystack)
         }
 
         #[inline]
-        fn is_prefix_of(self, haystack: &'a str) -> bool {
+        fn is_prefix_of<$a>(self, haystack: &$a str) -> bool {
             ($pmap)(self).is_prefix_of(haystack)
         }
 
         #[inline]
-        fn strip_prefix_of(self, haystack: &'a str) -> Option<&'a str> {
+        fn strip_prefix_of<$a>(self, haystack: &$a str) -> Option<&$a str> {
             ($pmap)(self).strip_prefix_of(haystack)
         }
 
         #[inline]
-        fn is_suffix_of(self, haystack: &'a str) -> bool
+        fn is_suffix_of<$a>(self, haystack: &$a str) -> bool
         where
-            $t: ReverseSearcher<'a>,
+            $t: ReverseSearcher<$a>,
         {
             ($pmap)(self).is_suffix_of(haystack)
         }
 
         #[inline]
-        fn strip_suffix_of(self, haystack: &'a str) -> Option<&'a str>
+        fn strip_suffix_of<$a>(self, haystack: &$a str) -> Option<&$a str>
         where
-            $t: ReverseSearcher<'a>,
+            $t: ReverseSearcher<$a>,
         {
             ($pmap)(self).strip_suffix_of(haystack)
         }
@@ -786,16 +786,16 @@ macro_rules! searcher_methods {
     };
 }
 
-/// Associated type for `<[char; N] as Pattern<'a>>::Searcher`.
+/// Associated type for `<[char; N] as Pattern>::Searcher<'a>`.
 #[derive(Clone, Debug)]
 pub struct CharArraySearcher<'a, const N: usize>(
-    <MultiCharEqPattern<[char; N]> as Pattern<'a>>::Searcher,
+    <MultiCharEqPattern<[char; N]> as Pattern>::Searcher<'a>,
 );
 
-/// Associated type for `<&[char; N] as Pattern<'a>>::Searcher`.
+/// Associated type for `<&[char; N] as Pattern>::Searcher<'a>`.
 #[derive(Clone, Debug)]
 pub struct CharArrayRefSearcher<'a, 'b, const N: usize>(
-    <MultiCharEqPattern<&'b [char; N]> as Pattern<'a>>::Searcher,
+    <MultiCharEqPattern<&'b [char; N]> as Pattern>::Searcher<'a>,
 );
 
 /// Searches for chars that are equal to any of the [`char`]s in the array.
@@ -806,8 +806,8 @@ pub struct CharArrayRefSearcher<'a, 'b, const N: usize>(
 /// assert_eq!("Hello world".find(['o', 'l']), Some(2));
 /// assert_eq!("Hello world".find(['h', 'w']), Some(6));
 /// ```
-impl<'a, const N: usize> Pattern<'a> for [char; N] {
-    pattern_methods!(CharArraySearcher<'a, N>, MultiCharEqPattern, CharArraySearcher);
+impl<const N: usize> Pattern for [char; N] {
+    pattern_methods!('a, CharArraySearcher<'a, N>, MultiCharEqPattern, CharArraySearcher);
 }
 
 unsafe impl<'a, const N: usize> Searcher<'a> for CharArraySearcher<'a, N> {
@@ -828,8 +828,8 @@ impl<'a, const N: usize> DoubleEndedSearcher<'a> for CharArraySearcher<'a, N> {}
 /// assert_eq!("Hello world".find(&['o', 'l']), Some(2));
 /// assert_eq!("Hello world".find(&['h', 'w']), Some(6));
 /// ```
-impl<'a, 'b, const N: usize> Pattern<'a> for &'b [char; N] {
-    pattern_methods!(CharArrayRefSearcher<'a, 'b, N>, MultiCharEqPattern, CharArrayRefSearcher);
+impl<'b, const N: usize> Pattern for &'b [char; N] {
+    pattern_methods!('a, CharArrayRefSearcher<'a, 'b, N>, MultiCharEqPattern, CharArrayRefSearcher);
 }
 
 unsafe impl<'a, 'b, const N: usize> Searcher<'a> for CharArrayRefSearcher<'a, 'b, N> {
@@ -848,9 +848,9 @@ impl<'a, 'b, const N: usize> DoubleEndedSearcher<'a> for CharArrayRefSearcher<'a
 
 // Todo: Change / Remove due to ambiguity in meaning.
 
-/// Associated type for `<&[char] as Pattern<'a>>::Searcher`.
+/// Associated type for `<&[char] as Pattern>::Searcher<'a>`.
 #[derive(Clone, Debug)]
-pub struct CharSliceSearcher<'a, 'b>(<MultiCharEqPattern<&'b [char]> as Pattern<'a>>::Searcher);
+pub struct CharSliceSearcher<'a, 'b>(<MultiCharEqPattern<&'b [char]> as Pattern>::Searcher<'a>);
 
 unsafe impl<'a, 'b> Searcher<'a> for CharSliceSearcher<'a, 'b> {
     searcher_methods!(forward);
@@ -870,17 +870,17 @@ impl<'a, 'b> DoubleEndedSearcher<'a> for CharSliceSearcher<'a, 'b> {}
 /// assert_eq!("Hello world".find(&['l', 'l'] as &[_]), Some(2));
 /// assert_eq!("Hello world".find(&['l', 'l'][..]), Some(2));
 /// ```
-impl<'a, 'b> Pattern<'a> for &'b [char] {
-    pattern_methods!(CharSliceSearcher<'a, 'b>, MultiCharEqPattern, CharSliceSearcher);
+impl<'b> Pattern for &'b [char] {
+    pattern_methods!('a, CharSliceSearcher<'a, 'b>, MultiCharEqPattern, CharSliceSearcher);
 }
 
 /////////////////////////////////////////////////////////////////////////////
 // Impl for F: FnMut(char) -> bool
 /////////////////////////////////////////////////////////////////////////////
 
-/// Associated type for `<F as Pattern<'a>>::Searcher`.
+/// Associated type for `<F as Pattern>::Searcher<'a>`.
 #[derive(Clone)]
-pub struct CharPredicateSearcher<'a, F>(<MultiCharEqPattern<F> as Pattern<'a>>::Searcher)
+pub struct CharPredicateSearcher<'a, F>(<MultiCharEqPattern<F> as Pattern>::Searcher<'a>)
 where
     F: FnMut(char) -> bool;
 
@@ -919,11 +919,11 @@ impl<'a, F> DoubleEndedSearcher<'a> for CharPredicateSearcher<'a, F> where F: Fn
 /// assert_eq!("Hello world".find(char::is_uppercase), Some(0));
 /// assert_eq!("Hello world".find(|c| "aeiou".contains(c)), Some(1));
 /// ```
-impl<'a, F> Pattern<'a> for F
+impl<F> Pattern for F
 where
     F: FnMut(char) -> bool,
 {
-    pattern_methods!(CharPredicateSearcher<'a, F>, MultiCharEqPattern, CharPredicateSearcher);
+    pattern_methods!('a, CharPredicateSearcher<'a, F>, MultiCharEqPattern, CharPredicateSearcher);
 }
 
 /////////////////////////////////////////////////////////////////////////////
@@ -931,8 +931,8 @@ where
 /////////////////////////////////////////////////////////////////////////////
 
 /// Delegates to the `&str` impl.
-impl<'a, 'b, 'c> Pattern<'a> for &'c &'b str {
-    pattern_methods!(StrSearcher<'a, 'b>, |&s| s, |s| s);
+impl<'b, 'c> Pattern for &'c &'b str {
+    pattern_methods!('a, StrSearcher<'a, 'b>, |&s| s, |s| s);
 }
 
 /////////////////////////////////////////////////////////////////////////////
@@ -949,23 +949,23 @@ impl<'a, 'b, 'c> Pattern<'a> for &'c &'b str {
 /// ```
 /// assert_eq!("Hello world".find("world"), Some(6));
 /// ```
-impl<'a, 'b> Pattern<'a> for &'b str {
-    type Searcher = StrSearcher<'a, 'b>;
+impl<'b> Pattern for &'b str {
+    type Searcher<'a> = StrSearcher<'a, 'b>;
 
     #[inline]
-    fn into_searcher(self, haystack: &'a str) -> StrSearcher<'a, 'b> {
+    fn into_searcher(self, haystack: &str) -> StrSearcher<'_, 'b> {
         StrSearcher::new(haystack, self)
     }
 
     /// Checks whether the pattern matches at the front of the haystack.
     #[inline]
-    fn is_prefix_of(self, haystack: &'a str) -> bool {
+    fn is_prefix_of(self, haystack: &str) -> bool {
         haystack.as_bytes().starts_with(self.as_bytes())
     }
 
     /// Checks whether the pattern matches anywhere in the haystack
     #[inline]
-    fn is_contained_in(self, haystack: &'a str) -> bool {
+    fn is_contained_in(self, haystack: &str) -> bool {
         if self.len() == 0 {
             return true;
         }
@@ -991,7 +991,7 @@ impl<'a, 'b> Pattern<'a> for &'b str {
 
     /// Removes the pattern from the front of haystack, if it matches.
     #[inline]
-    fn strip_prefix_of(self, haystack: &'a str) -> Option<&'a str> {
+    fn strip_prefix_of(self, haystack: &str) -> Option<&str> {
         if self.is_prefix_of(haystack) {
             // SAFETY: prefix was just verified to exist.
             unsafe { Some(haystack.get_unchecked(self.as_bytes().len()..)) }
@@ -1002,13 +1002,19 @@ impl<'a, 'b> Pattern<'a> for &'b str {
 
     /// Checks whether the pattern matches at the back of the haystack.
     #[inline]
-    fn is_suffix_of(self, haystack: &'a str) -> bool {
+    fn is_suffix_of<'a>(self, haystack: &'a str) -> bool
+    where
+        Self::Searcher<'a>: ReverseSearcher<'a>,
+    {
         haystack.as_bytes().ends_with(self.as_bytes())
     }
 
     /// Removes the pattern from the back of haystack, if it matches.
     #[inline]
-    fn strip_suffix_of(self, haystack: &'a str) -> Option<&'a str> {
+    fn strip_suffix_of<'a>(self, haystack: &'a str) -> Option<&'a str>
+    where
+        Self::Searcher<'a>: ReverseSearcher<'a>,
+    {
         if self.is_suffix_of(haystack) {
             let i = haystack.len() - self.as_bytes().len();
             // SAFETY: suffix was just verified to exist.
@@ -1024,7 +1030,7 @@ impl<'a, 'b> Pattern<'a> for &'b str {
 /////////////////////////////////////////////////////////////////////////////
 
 #[derive(Clone, Debug)]
-/// Associated type for `<&str as Pattern<'a>>::Searcher`.
+/// Associated type for `<&str as Pattern>::Searcher<'a>`.
 pub struct StrSearcher<'a, 'b> {
     haystack: &'a str,
     needle: &'b str,
diff --git a/tests/ui/suggestions/issue-104961.fixed b/tests/ui/suggestions/issue-104961.fixed
index 5def21b506e..3019242880f 100644
--- a/tests/ui/suggestions/issue-104961.fixed
+++ b/tests/ui/suggestions/issue-104961.fixed
@@ -2,12 +2,12 @@
 
 fn foo(x: &str) -> bool {
     x.starts_with(&("hi".to_string() + " you"))
-    //~^ ERROR the trait bound `String: Pattern<'_>` is not satisfied [E0277]
+    //~^ ERROR the trait bound `String: Pattern` is not satisfied [E0277]
 }
 
 fn foo2(x: &str) -> bool {
     x.starts_with(&"hi".to_string())
-    //~^ ERROR the trait bound `String: Pattern<'_>` is not satisfied [E0277]
+    //~^ ERROR the trait bound `String: Pattern` is not satisfied [E0277]
 }
 
 fn main() {
diff --git a/tests/ui/suggestions/issue-104961.rs b/tests/ui/suggestions/issue-104961.rs
index a09b8a88711..b315e9bab0d 100644
--- a/tests/ui/suggestions/issue-104961.rs
+++ b/tests/ui/suggestions/issue-104961.rs
@@ -2,12 +2,12 @@
 
 fn foo(x: &str) -> bool {
     x.starts_with("hi".to_string() + " you")
-    //~^ ERROR the trait bound `String: Pattern<'_>` is not satisfied [E0277]
+    //~^ ERROR the trait bound `String: Pattern` is not satisfied [E0277]
 }
 
 fn foo2(x: &str) -> bool {
     x.starts_with("hi".to_string())
-    //~^ ERROR the trait bound `String: Pattern<'_>` is not satisfied [E0277]
+    //~^ ERROR the trait bound `String: Pattern` is not satisfied [E0277]
 }
 
 fn main() {
diff --git a/tests/ui/suggestions/issue-104961.stderr b/tests/ui/suggestions/issue-104961.stderr
index 3c5f86817f3..0d229e6dada 100644
--- a/tests/ui/suggestions/issue-104961.stderr
+++ b/tests/ui/suggestions/issue-104961.stderr
@@ -1,12 +1,12 @@
-error[E0277]: the trait bound `String: Pattern<'_>` is not satisfied
+error[E0277]: the trait bound `String: Pattern` is not satisfied
   --> $DIR/issue-104961.rs:4:19
    |
 LL |     x.starts_with("hi".to_string() + " you")
-   |       ----------- ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Pattern<'_>` is not implemented for `String`
+   |       ----------- ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Pattern` is not implemented for `String`
    |       |
    |       required by a bound introduced by this call
    |
-   = note: required for `String` to implement `Pattern<'_>`
+   = note: required for `String` to implement `Pattern`
 note: required by a bound in `core::str::<impl str>::starts_with`
   --> $SRC_DIR/core/src/str/mod.rs:LL:COL
 help: consider borrowing here
@@ -14,15 +14,15 @@ help: consider borrowing here
 LL |     x.starts_with(&("hi".to_string() + " you"))
    |                   ++                         +
 
-error[E0277]: the trait bound `String: Pattern<'_>` is not satisfied
+error[E0277]: the trait bound `String: Pattern` is not satisfied
   --> $DIR/issue-104961.rs:9:19
    |
 LL |     x.starts_with("hi".to_string())
-   |       ----------- ^^^^^^^^^^^^^^^^ the trait `Pattern<'_>` is not implemented for `String`
+   |       ----------- ^^^^^^^^^^^^^^^^ the trait `Pattern` is not implemented for `String`
    |       |
    |       required by a bound introduced by this call
    |
-   = note: required for `String` to implement `Pattern<'_>`
+   = note: required for `String` to implement `Pattern`
 note: required by a bound in `core::str::<impl str>::starts_with`
   --> $SRC_DIR/core/src/str/mod.rs:LL:COL
 help: consider borrowing here
diff --git a/tests/ui/suggestions/issue-62843.stderr b/tests/ui/suggestions/issue-62843.stderr
index 84ab4a0edd3..c3c0360b3a9 100644
--- a/tests/ui/suggestions/issue-62843.stderr
+++ b/tests/ui/suggestions/issue-62843.stderr
@@ -1,12 +1,12 @@
-error[E0277]: the trait bound `String: Pattern<'_>` is not satisfied
+error[E0277]: the trait bound `String: Pattern` is not satisfied
   --> $DIR/issue-62843.rs:4:32
    |
 LL |     println!("{:?}", line.find(pattern));
-   |                           ---- ^^^^^^^ the trait `Pattern<'_>` is not implemented for `String`
+   |                           ---- ^^^^^^^ the trait `Pattern` is not implemented for `String`
    |                           |
    |                           required by a bound introduced by this call
    |
-   = note: required for `String` to implement `Pattern<'_>`
+   = note: required for `String` to implement `Pattern`
 note: required by a bound in `core::str::<impl str>::find`
   --> $SRC_DIR/core/src/str/mod.rs:LL:COL
 help: consider borrowing here
diff --git a/tests/ui/traits/bound/assoc-fn-bound-root-obligation.rs b/tests/ui/traits/bound/assoc-fn-bound-root-obligation.rs
index 98825bd536e..dc2de5bb715 100644
--- a/tests/ui/traits/bound/assoc-fn-bound-root-obligation.rs
+++ b/tests/ui/traits/bound/assoc-fn-bound-root-obligation.rs
@@ -1,11 +1,11 @@
 fn strip_lf(s: &str) -> &str {
     s.strip_suffix(b'\n').unwrap_or(s)
-    //~^ ERROR expected a `FnMut(char)` closure, found `u8`
-    //~| NOTE expected an `FnMut(char)` closure, found `u8`
-    //~| HELP the trait `FnMut(char)` is not implemented for `u8`
-    //~| HELP the following other types implement trait `Pattern<'a>`:
-    //~| NOTE required for `u8` to implement `Pattern<'_>`
-
+    //~^ ERROR the trait bound `u8: Pattern` is not satisfied
+    //~| NOTE required by a bound introduced by this call
+    //~| NOTE the trait `FnMut(char)` is not implemented for `u8`, which is required by `u8: Pattern`
+    //~| HELP the following other types implement trait `Pattern`:
+    //~| NOTE required for `u8` to implement `Pattern`
+    //~| NOTE required by a bound in `core::str::<impl str>::strip_suffix`
 }
 
 fn main() {}
diff --git a/tests/ui/traits/bound/assoc-fn-bound-root-obligation.stderr b/tests/ui/traits/bound/assoc-fn-bound-root-obligation.stderr
index 49272e7d357..8351d15fdf3 100644
--- a/tests/ui/traits/bound/assoc-fn-bound-root-obligation.stderr
+++ b/tests/ui/traits/bound/assoc-fn-bound-root-obligation.stderr
@@ -1,11 +1,12 @@
-error[E0277]: expected a `FnMut(char)` closure, found `u8`
-  --> $DIR/assoc-fn-bound-root-obligation.rs:2:7
+error[E0277]: the trait bound `u8: Pattern` is not satisfied
+  --> $DIR/assoc-fn-bound-root-obligation.rs:2:20
    |
 LL |     s.strip_suffix(b'\n').unwrap_or(s)
-   |       ^^^^^^^^^^^^ expected an `FnMut(char)` closure, found `u8`
+   |       ------------ ^^^^^ the trait `FnMut(char)` is not implemented for `u8`, which is required by `u8: Pattern`
+   |       |
+   |       required by a bound introduced by this call
    |
-   = help: the trait `FnMut(char)` is not implemented for `u8`, which is required by `u8: Pattern<'_>`
-   = help: the following other types implement trait `Pattern<'a>`:
+   = help: the following other types implement trait `Pattern`:
              &'b String
              &'b [char; N]
              &'b [char]
@@ -13,7 +14,9 @@ LL |     s.strip_suffix(b'\n').unwrap_or(s)
              &'c &'b str
              [char; N]
              char
-   = note: required for `u8` to implement `Pattern<'_>`
+   = note: required for `u8` to implement `Pattern`
+note: required by a bound in `core::str::<impl str>::strip_suffix`
+  --> $SRC_DIR/core/src/str/mod.rs:LL:COL
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/traits/suggest-dereferences/root-obligation.fixed b/tests/ui/traits/suggest-dereferences/root-obligation.fixed
index 072296c6b15..ad0f184dc9a 100644
--- a/tests/ui/traits/suggest-dereferences/root-obligation.fixed
+++ b/tests/ui/traits/suggest-dereferences/root-obligation.fixed
@@ -4,7 +4,7 @@ fn get_vowel_count(string: &str) -> usize {
     string
         .chars()
         .filter(|c| "aeiou".contains(*c))
-        //~^ ERROR the trait bound `&char: Pattern<'_>` is not satisfied
+        //~^ ERROR the trait bound `&char: Pattern` is not satisfied
         .count()
 }
 
diff --git a/tests/ui/traits/suggest-dereferences/root-obligation.rs b/tests/ui/traits/suggest-dereferences/root-obligation.rs
index e7025fe0825..a31a9955d31 100644
--- a/tests/ui/traits/suggest-dereferences/root-obligation.rs
+++ b/tests/ui/traits/suggest-dereferences/root-obligation.rs
@@ -4,7 +4,7 @@ fn get_vowel_count(string: &str) -> usize {
     string
         .chars()
         .filter(|c| "aeiou".contains(c))
-        //~^ ERROR the trait bound `&char: Pattern<'_>` is not satisfied
+        //~^ ERROR the trait bound `&char: Pattern` is not satisfied
         .count()
 }
 
diff --git a/tests/ui/traits/suggest-dereferences/root-obligation.stderr b/tests/ui/traits/suggest-dereferences/root-obligation.stderr
index bbfbb98fba7..2f5e1c5b537 100644
--- a/tests/ui/traits/suggest-dereferences/root-obligation.stderr
+++ b/tests/ui/traits/suggest-dereferences/root-obligation.stderr
@@ -1,13 +1,13 @@
-error[E0277]: the trait bound `&char: Pattern<'_>` is not satisfied
+error[E0277]: the trait bound `&char: Pattern` is not satisfied
   --> $DIR/root-obligation.rs:6:38
    |
 LL |         .filter(|c| "aeiou".contains(c))
-   |                             -------- ^ the trait `Fn(char)` is not implemented for `char`, which is required by `&char: Pattern<'_>`
+   |                             -------- ^ the trait `Fn(char)` is not implemented for `char`, which is required by `&char: Pattern`
    |                             |
    |                             required by a bound introduced by this call
    |
    = note: required for `&char` to implement `FnOnce(char)`
-   = note: required for `&char` to implement `Pattern<'_>`
+   = note: required for `&char` to implement `Pattern`
 note: required by a bound in `core::str::<impl str>::contains`
   --> $SRC_DIR/core/src/str/mod.rs:LL:COL
 help: consider dereferencing here