nebius/SWE-rebench-V2-PRs huggingface dataset:
Repository: GREsau/schemars
Pull request #72 (2021-02-15 09:16:07)

add optional smol_str support

novacrazy: Can we get this merged? Almost two years. 

Patch:
diff --git a/schemars/Cargo.toml b/schemars/Cargo.toml
index 51fd64c..bf5d6b9 100644
--- a/schemars/Cargo.toml
+++ b/schemars/Cargo.toml
@@ -31,6 +31,7 @@ bytes = { version = "1.0", optional = true }
 rust_decimal = { version = "1", default-features = false, optional = true }
 bigdecimal = { version = "0.3", default-features = false, optional = true }
 enumset = { version = "1.0", optional = true }
+smol_str = { version = "0.1.17", optional = true }
 
 [dev-dependencies]
 pretty_assertions = "1.2.1"
@@ -102,5 +103,9 @@ required-features = ["url"]
 name = "enumset"
 required-features = ["enumset"]
 
+[[test]]
+name = "smol_str"
+required-features = ["smol_str"]
+
 [package.metadata.docs.rs]
 all-features = true
diff --git a/schemars/src/json_schema_impls/mod.rs b/schemars/src/json_schema_impls/mod.rs
index 9925442..490a544 100644
--- a/schemars/src/json_schema_impls/mod.rs
+++ b/schemars/src/json_schema_impls/mod.rs
@@ -64,6 +64,8 @@ mod sequences;
 mod serdejson;
 #[cfg(feature = "smallvec")]
 mod smallvec;
+#[cfg(feature = "smol_str")]
+mod smol_str;
 mod time;
 mod tuple;
 #[cfg(feature = "url")]
diff --git a/schemars/src/json_schema_impls/smol_str.rs b/schemars/src/json_schema_impls/smol_str.rs
new file mode 100644
index 0000000..cbca4a1
--- /dev/null
+++ b/schemars/src/json_schema_impls/smol_str.rs
@@ -0,0 +1,6 @@
+use crate::gen::SchemaGenerator;
+use crate::schema::*;
+use crate::JsonSchema;
+use smol_str::SmolStr;
+
+forward_impl!(SmolStr => String);


Test patch:
diff --git a/schemars/tests/expected/smol_str.json b/schemars/tests/expected/smol_str.json
new file mode 100644
index 0000000..42f099a
--- /dev/null
+++ b/schemars/tests/expected/smol_str.json
@@ -0,0 +1,5 @@
+{
+  "$schema": "http://json-schema.org/draft-07/schema#",
+  "title": "String",
+  "type": "string"
+}
\ No newline at end of file
diff --git a/schemars/tests/smol_str.rs b/schemars/tests/smol_str.rs
new file mode 100644
index 0000000..1e48196
--- /dev/null
+++ b/schemars/tests/smol_str.rs
@@ -0,0 +1,8 @@
+mod util;
+use smol_str::SmolStr;
+use util::*;
+
+#[test]
+fn smol_str() -> TestResult {
+    test_default_generated_schema::<SmolStr>("smol_str")
+}
Repository: GREsau/schemars
Pull request #83 (2021-05-24 16:19:45)

Support generic default values
I'm trying to `derive(JsonSchema)` on a field with a default that relies
on type inference to determine it's return type.  This causes compile
errors because schemars calls the default function without providing
any types for inference to use.

This changes that - wraps the `default` in a closure with a defined
return value that it immediately calls.  Feels a bit hacky, but I
couldn't think of a better way to fix this.

rcoh: would love to see this merged!
rcoh: Actually you can work around this by just using the turbo fish and naming the generic explicitly in the serde annotation

Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 3e78341..734448f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,9 @@
 # Changelog
 
+## [0.8.9] - **in-dev**
+### Changed:
+- Support generic default values in `default` attributes (https://github.com/GREsau/schemars/pull/83)
+
 ## [0.8.8] - 2021-11-25
 ### Added:
 - Implement `JsonSchema` for types from `rust_decimal` and `bigdecimal` crates (https://github.com/GREsau/schemars/pull/101)
diff --git a/schemars_derive/src/schema_exprs.rs b/schemars_derive/src/schema_exprs.rs
index c5b1672..f41e37a 100644
--- a/schemars_derive/src/schema_exprs.rs
+++ b/schemars_derive/src/schema_exprs.rs
@@ -581,7 +581,7 @@ fn field_default_expr(field: &Field, container_has_default: bool) -> Option<Toke
             quote!(container_default.#member)
         }
         SerdeDefault::Default => quote!(<#ty>::default()),
-        SerdeDefault::Path(path) => quote!(#path()),
+        SerdeDefault::Path(path) => quote!({ #path() as #ty }),
     };
 
     let default_expr = match field.serde_attrs.skip_serializing_if() {


Test patch:
diff --git a/schemars/tests/default.rs b/schemars/tests/default.rs
index 0d68d0e..c44a3c2 100644
--- a/schemars/tests/default.rs
+++ b/schemars/tests/default.rs
@@ -54,3 +54,14 @@ pub struct NotSerialize;
 fn schema_default_values() -> TestResult {
     test_default_generated_schema::<MyStruct>("default")
 }
+
+#[derive(JsonSchema, Debug)]
+pub struct StructWithGenericDefaults {
+    #[serde(default = "Vec::new")]
+    pub a_vec: Vec<String>,
+}
+
+#[test]
+fn schema_with_generic_default_value() -> TestResult {
+    test_default_generated_schema::<StructWithGenericDefaults>("generic_default")
+}
diff --git a/schemars/tests/expected/generic_default.json b/schemars/tests/expected/generic_default.json
new file mode 100644
index 0000000..095b999
--- /dev/null
+++ b/schemars/tests/expected/generic_default.json
@@ -0,0 +1,14 @@
+{
+  "$schema": "http://json-schema.org/draft-07/schema#",
+  "title": "StructWithGenericDefaults",
+  "type": "object",
+  "properties": {
+    "a_vec": {
+      "default": [],
+      "type": "array",
+      "items": {
+        "type": "string"
+      }
+    }
+  }
+}
\ No newline at end of file
Repository: Geal/nom
Pull request #241 (2016-03-28 17:22:40)

Fix length_bytes usize issue


Patch:
diff --git a/src/bytes.rs b/src/bytes.rs
index 2e37350..c82419a 100644
--- a/src/bytes.rs
+++ b/src/bytes.rs
@@ -761,6 +761,7 @@ macro_rules! length_bytes(
         $crate::IResult::Error(a)      => $crate::IResult::Error(a),
         $crate::IResult::Incomplete(i) => $crate::IResult::Incomplete(i),
         $crate::IResult::Done(i1,nb)   => {
+          let nb = nb as usize;
           let length_remaining = i1.len();
           if length_remaining < nb {
             $crate::IResult::Incomplete($crate::Needed::Size(nb - length_remaining))


Test patch:
diff --git a/tests/issues.rs b/tests/issues.rs
index 57f4f17..a7de9b1 100644
--- a/tests/issues.rs
+++ b/tests/issues.rs
@@ -2,7 +2,7 @@
 #[macro_use]
 extern crate nom;
 
-use nom::{IResult,Needed,HexDisplay,space,digit};
+use nom::{IResult,Needed,HexDisplay,space,digit,be_u16};
 use std::str;
 
 #[allow(dead_code)]
@@ -97,6 +97,11 @@ fn issue_142(){
    assert_eq!(subject, expected)
 }
 
+#[test]
+fn usize_length_bytes_issue(){
+  length_bytes!(b"012346", be_u16);
+}
+
 /*
  DOES NOT COMPILE
 #[test]
Repository: Geal/nom
Pull request #249 (2016-04-11 22:10:01)

Fixed take_till! to be usable from the outside of nom crate
Because of private trait macro shenanigans, it was impossible to use this macro due to compilation error. The attached test, for example, doesn't compile without this patch.


Patch:
diff --git a/src/bytes.rs b/src/bytes.rs
index c82419a..cbf8885 100644
--- a/src/bytes.rs
+++ b/src/bytes.rs
@@ -487,8 +487,8 @@ macro_rules! take_while1 (
 #[macro_export]
 macro_rules! take_till (
   ($input:expr, $submac:ident!( $($args:tt)* )) => (
-
     {
+      use $crate::InputLength;
       match $input.iter().position(|c| $submac!(c, $($args)*)) {
         Some(n) => $crate::IResult::Done(&$input[n..], &$input[..n]),
         None    => $crate::IResult::Done(&$input[($input).input_len()..], $input)


Test patch:
diff --git a/tests/issues.rs b/tests/issues.rs
index a7de9b1..6466d7f 100644
--- a/tests/issues.rs
+++ b/tests/issues.rs
@@ -119,3 +119,13 @@ fn issue_152() {
   );
 }
 */
+
+#[test]
+fn take_till_issue() {
+    named!(nothing,
+        take_till!(call!(|_| true))
+    );
+
+    assert_eq!(nothing(b""), IResult::Done(&b""[..], &b""[..]));
+    assert_eq!(nothing(b"abc"), IResult::Done(&b"abc"[..], &b""[..]));
+}
Repository: Geal/nom
Pull request #958 (2019-06-13 07:28:51)

Fix escaped not returning err on failure (issue #953)
If none of the input parsers match, then `escaped` and `escaped_transform` should return an `Err` instead of `Ok("")`



Patch:
diff --git a/README.md b/README.md
index 7303ef7..a69e49d 100644
--- a/README.md
+++ b/README.md
@@ -131,7 +131,6 @@ parsing, and construct an AST in place.
 Example projects:
 
 - [PHP VM](https://github.com/tagua-vm/parser)
-- [Rust parser](https://github.com/dtolnay/syn)
 - eve language prototype
 - [xshade shading language](https://github.com/xshade-lang/xshade/)
 
diff --git a/src/bytes/complete.rs b/src/bytes/complete.rs
index 7ca6be4..9cb06a5 100644
--- a/src/bytes/complete.rs
+++ b/src/bytes/complete.rs
@@ -355,7 +355,7 @@ where
 }
 
 /// Returns an input slice containing the first N input elements (Input[..N])
-/// 
+///
 /// It will return `Err(Err::Error((_, ErrorKind::Eof)))` if the input is shorter than the argument
 ///
 /// # Example
@@ -483,6 +483,9 @@ where
             }
           } else {
             let index = input.offset(&i);
+            if index == 0 {
+              return Err(Err::Error(Error::from_error_kind(input, ErrorKind::Escaped)));
+            }
             return Ok(input.take_split(index));
           }
         }
@@ -597,6 +600,9 @@ where
               }
             }
           } else {
+            if index == 0 {
+              return Err(Err::Error(Error::from_error_kind(remainder, ErrorKind::EscapedTransform)));
+            }
             return Ok((remainder, res));
           }
         }


Test patch:
diff --git a/tests/escaped.rs b/tests/escaped.rs
new file mode 100644
index 0000000..a2cc65d
--- /dev/null
+++ b/tests/escaped.rs
@@ -0,0 +1,18 @@
+use nom::{Err, error::ErrorKind, IResult};
+use nom::character::complete::digit1;
+use nom::bytes::complete::{escaped, escaped_transform, tag};
+use nom::character::complete::one_of;
+
+fn esc(s: &str) -> IResult<&str, &str> {
+    escaped(digit1, '\\', one_of("\"n\\"))(s)
+}
+
+fn esc_trans(s: &str) -> IResult<&str, String> {
+    escaped_transform(digit1, '\\', |i: &str| tag("n")(i))(s)
+}
+
+#[test]
+fn test_escaped() {
+    assert_eq!(esc("abcd"), Err(Err::Error(("abcd", ErrorKind::Escaped))));
+    assert_eq!(esc_trans("abcd"), Err(Err::Error(("abcd", ErrorKind::EscapedTransform))));
+}
\ No newline at end of file
Repository: Geal/nom
Pull request #959 (2019-06-13 09:59:33)

escaped: Use raw strings in example
I think raw strings read easier than trying to count the number of backslashes and that figuring out the Rust escaping vs. the escape output is confusing currently.




Patch:
diff --git a/README.md b/README.md
index 7303ef7..a69e49d 100644
--- a/README.md
+++ b/README.md
@@ -131,7 +131,6 @@ parsing, and construct an AST in place.
 Example projects:
 
 - [PHP VM](https://github.com/tagua-vm/parser)
-- [Rust parser](https://github.com/dtolnay/syn)
 - eve language prototype
 - [xshade shading language](https://github.com/xshade-lang/xshade/)
 
diff --git a/src/bytes/complete.rs b/src/bytes/complete.rs
index 7ca6be4..7f98fee 100644
--- a/src/bytes/complete.rs
+++ b/src/bytes/complete.rs
@@ -355,7 +355,7 @@ where
 }
 
 /// Returns an input slice containing the first N input elements (Input[..N])
-/// 
+///
 /// It will return `Err(Err::Error((_, ErrorKind::Eof)))` if the input is shorter than the argument
 ///
 /// # Example
@@ -434,11 +434,11 @@ where
 /// use nom::character::complete::one_of;
 ///
 /// fn esc(s: &str) -> IResult<&str, &str> {
-///   escaped(digit1, '\\', one_of("\"n\\"))(s)
+///   escaped(digit1, '\\', one_of(r#""n\"#))(s)
 /// }
 ///
 /// assert_eq!(esc("123;"), Ok((";", "123")));
-/// assert_eq!(esc("12\\\"34;"), Ok((";", "12\\\"34")));
+/// assert_eq!(esc(r#"12\"34;"#), Ok((";", r#"12\"34"#)));
 /// ```
 ///
 pub fn escaped<Input, Error, F, G, O1, O2>(normal: F, control_char: char, escapable: G) -> impl Fn(Input) -> IResult<Input, Input, Error>
@@ -483,6 +483,9 @@ where
             }
           } else {
             let index = input.offset(&i);
+            if index == 0 {
+              return Err(Err::Error(Error::from_error_kind(input, ErrorKind::Escaped)));
+            }
             return Ok(input.take_split(index));
           }
         }
@@ -597,6 +600,9 @@ where
               }
             }
           } else {
+            if index == 0 {
+              return Err(Err::Error(Error::from_error_kind(remainder, ErrorKind::EscapedTransform)));
+            }
             return Ok((remainder, res));
           }
         }


Test patch:
diff --git a/tests/escaped.rs b/tests/escaped.rs
new file mode 100644
index 0000000..a2cc65d
--- /dev/null
+++ b/tests/escaped.rs
@@ -0,0 +1,18 @@
+use nom::{Err, error::ErrorKind, IResult};
+use nom::character::complete::digit1;
+use nom::bytes::complete::{escaped, escaped_transform, tag};
+use nom::character::complete::one_of;
+
+fn esc(s: &str) -> IResult<&str, &str> {
+    escaped(digit1, '\\', one_of("\"n\\"))(s)
+}
+
+fn esc_trans(s: &str) -> IResult<&str, String> {
+    escaped_transform(digit1, '\\', |i: &str| tag("n")(i))(s)
+}
+
+#[test]
+fn test_escaped() {
+    assert_eq!(esc("abcd"), Err(Err::Error(("abcd", ErrorKind::Escaped))));
+    assert_eq!(esc_trans("abcd"), Err(Err::Error(("abcd", ErrorKind::EscapedTransform))));
+}
\ No newline at end of file
Repository: Geal/nom
Pull request #995 (2019-07-16 13:55:49)

fix many_m_n for n=0
I don't think other function in multi are susceptible to the same bug (fold_many_m_n uses a for loop).


Patch:
diff --git a/src/multi/mod.rs b/src/multi/mod.rs
index 269fc44..93b3e4c 100644
--- a/src/multi/mod.rs
+++ b/src/multi/mod.rs
@@ -409,6 +409,10 @@ where
     let mut input = i.clone();
     let mut count: usize = 0;
 
+    if n == 0 {
+        return Ok((i, vec!()))
+    }
+
     loop {
       let _i = input.clone();
       match f(_i) {


Test patch:
diff --git a/tests/issues.rs b/tests/issues.rs
index a7bf516..094b47c 100644
--- a/tests/issues.rs
+++ b/tests/issues.rs
@@ -290,3 +290,11 @@ fn issue_942() {
   }
   assert_eq!(parser::<()>("aaa"), Ok(("", 3)));
 }
+
+#[test]
+fn issue_many_m_n_with_zeros() {
+    use nom::multi::many_m_n;
+    use nom::character::complete::char;
+    let parser = many_m_n::<_, _, (), _>(0, 0, char('a'));
+    assert_eq!(parser("aaa"), Ok(("aaa", vec!())));
+}
Repository: ota-meshi/eslint-plugin-regexp
Pull request #286 (2021-08-10 12:29:16)

Fix replacement escaping in string literals
I noticed a little bug:

![image](https://user-images.githubusercontent.com/20878432/128866703-1e825405-1ede-4ce9-8380-16c5e4c1ba17.png)

and fixed it:

![image](https://user-images.githubusercontent.com/20878432/128866751-666e3c53-5f1b-4a13-b2a3-13ad27e7600d.png)



Patch:
diff --git a/lib/utils/ast-utils/pattern-source.ts b/lib/utils/ast-utils/pattern-source.ts
index a0d7820..bb6aeb6 100644
--- a/lib/utils/ast-utils/pattern-source.ts
+++ b/lib/utils/ast-utils/pattern-source.ts
@@ -24,7 +24,7 @@ export interface PatternRange {
 export class PatternReplaceRange {
     public range: AST.Range
 
-    public type: "RegExp" | "String"
+    public type: "RegExp" | "SingleQuotedString" | "DoubleQuotedString"
 
     public constructor(range: AST.Range, type: PatternReplaceRange["type"]) {
         if (!range || range[0] < 0 || range[0] > range[1]) {
@@ -60,7 +60,11 @@ export class PatternReplaceRange {
             const astRange = getStringValueRange(sourceCode, node, start, end)
 
             if (astRange) {
-                return new PatternReplaceRange(astRange, "String")
+                const quote = sourceCode.text[node.range[0]]
+                return new PatternReplaceRange(
+                    astRange,
+                    quote === "'" ? "SingleQuotedString" : "DoubleQuotedString",
+                )
             }
         }
         return null
@@ -71,15 +75,23 @@ export class PatternReplaceRange {
     }
 
     public escape(text: string): string {
-        if (this.type === "String") {
-            return text
+        if (
+            this.type === "DoubleQuotedString" ||
+            this.type === "SingleQuotedString"
+        ) {
+            const base = text
                 .replace(/\\/g, "\\\\")
                 .replace(/\n/g, "\\n")
                 .replace(/\r/g, "\\r")
                 .replace(/\t/g, "\\t")
+
+            if (this.type === "DoubleQuotedString") {
+                return base.replace(/"/g, '\\"')
+            }
+            return base.replace(/'/g, "\\'")
         }
 
-        return text
+        return text.replace(/\n/g, "\\n").replace(/\r/g, "\\r")
     }
 
     public replace(fixer: Rule.RuleFixer, text: string): Rule.Fix {


Test patch:
diff --git a/tests/lib/rules/no-useless-character-class.ts b/tests/lib/rules/no-useless-character-class.ts
index 0f17d47..5bd0b00 100644
--- a/tests/lib/rules/no-useless-character-class.ts
+++ b/tests/lib/rules/no-useless-character-class.ts
@@ -145,5 +145,11 @@ tester.run("no-useless-character-class", rule as any, {
             options: [{ ignores: [] }],
             errors: 18,
         },
+        {
+            code: String.raw`RegExp("[\"]" + '[\']')`,
+            output: String.raw`RegExp("\"" + '\'')`,
+            options: [{ ignores: [] }],
+            errors: 2,
+        },
     ],
 })
Repository: ota-meshi/eslint-plugin-regexp
Pull request #293 (2021-08-11 10:02:35)

Fix `no-useless-lazy` for quantifiers with min=0
`no-useless-lazy` did not report uselessly lazy quantifiers with a minimum of 0 because the first consumed character was determined for the quantifier and not for the quantified element.


Patch:
diff --git a/lib/rules/no-useless-lazy.ts b/lib/rules/no-useless-lazy.ts
index 0459baf..e6ca63b 100644
--- a/lib/rules/no-useless-lazy.ts
+++ b/lib/rules/no-useless-lazy.ts
@@ -94,7 +94,7 @@ export default createRule("no-useless-lazy", {
 
                     const matchingDir = getMatchingDirection(qNode)
                     const firstChar = getFirstConsumedChar(
-                        qNode,
+                        qNode.element,
                         matchingDir,
                         flags,
                     )
diff --git a/lib/rules/no-useless-non-capturing-group.ts b/lib/rules/no-useless-non-capturing-group.ts
index 76daafb..bf432c6 100644
--- a/lib/rules/no-useless-non-capturing-group.ts
+++ b/lib/rules/no-useless-non-capturing-group.ts
@@ -125,7 +125,7 @@ export default createRule("no-useless-non-capturing-group", {
 
                     context.report({
                         node,
-                        loc: getRegexpLocation(gNode),
+                        loc: getRegexpLocation(gNode, [0, 3]),
                         messageId: "unexpected",
                         fix: fixReplaceNode(gNode, () => {
                             if (


Test patch:
diff --git a/tests/lib/rules/no-useless-lazy.ts b/tests/lib/rules/no-useless-lazy.ts
index 9d6029a..58e35c6 100644
--- a/tests/lib/rules/no-useless-lazy.ts
+++ b/tests/lib/rules/no-useless-lazy.ts
@@ -72,6 +72,11 @@ tester.run("no-useless-lazy", rule as any, {
             output: `/a+b+/`,
             errors: [{ messageId: "possessive" }],
         },
+        {
+            code: `/a*?b+/`,
+            output: `/a*b+/`,
+            errors: [{ messageId: "possessive" }],
+        },
         {
             code: `/(?:a|cd)+?(?:b+|zzz)/`,
             output: `/(?:a|cd)+(?:b+|zzz)/`,
diff --git a/tests/lib/rules/no-useless-non-capturing-group.ts b/tests/lib/rules/no-useless-non-capturing-group.ts
index 1f04a44..6ea70ed 100644
--- a/tests/lib/rules/no-useless-non-capturing-group.ts
+++ b/tests/lib/rules/no-useless-non-capturing-group.ts
@@ -87,7 +87,7 @@ tester.run("no-useless-non-capturing-group", rule as any, {
                     line: 1,
                     column: 2,
                     endLine: 1,
-                    endColumn: 10,
+                    endColumn: 5,
                 },
             ],
         },
@@ -100,7 +100,7 @@ tester.run("no-useless-non-capturing-group", rule as any, {
                     line: 1,
                     column: 2,
                     endLine: 1,
-                    endColumn: 12,
+                    endColumn: 5,
                 },
             ],
         },
Repository: ota-meshi/eslint-plugin-regexp
Pull request #294 (2021-08-11 10:04:12)

Shrink report range of `no-useless-non-capturing-group`
This implements [my suggestion](https://github.com/ota-meshi/eslint-plugin-regexp/pull/49#issuecomment-896682733) for `no-useless-non-capturing-group`.

![image](https://user-images.githubusercontent.com/20878432/129010535-64b96e6f-e2bd-436d-933c-db5022401776.png)



Patch:
diff --git a/lib/rules/no-useless-non-capturing-group.ts b/lib/rules/no-useless-non-capturing-group.ts
index 76daafb..bf432c6 100644
--- a/lib/rules/no-useless-non-capturing-group.ts
+++ b/lib/rules/no-useless-non-capturing-group.ts
@@ -125,7 +125,7 @@ export default createRule("no-useless-non-capturing-group", {
 
                     context.report({
                         node,
-                        loc: getRegexpLocation(gNode),
+                        loc: getRegexpLocation(gNode, [0, 3]),
                         messageId: "unexpected",
                         fix: fixReplaceNode(gNode, () => {
                             if (


Test patch:
diff --git a/tests/lib/rules/no-useless-non-capturing-group.ts b/tests/lib/rules/no-useless-non-capturing-group.ts
index 1f04a44..6ea70ed 100644
--- a/tests/lib/rules/no-useless-non-capturing-group.ts
+++ b/tests/lib/rules/no-useless-non-capturing-group.ts
@@ -87,7 +87,7 @@ tester.run("no-useless-non-capturing-group", rule as any, {
                     line: 1,
                     column: 2,
                     endLine: 1,
-                    endColumn: 10,
+                    endColumn: 5,
                 },
             ],
         },
@@ -100,7 +100,7 @@ tester.run("no-useless-non-capturing-group", rule as any, {
                     line: 1,
                     column: 2,
                     endLine: 1,
-                    endColumn: 12,
+                    endColumn: 5,
                 },
             ],
         },
Repository: ota-meshi/eslint-plugin-regexp
Pull request #316 (2021-09-04 14:48:53)

Improve `no-useless-assertion` for nested assertions
This is a branch of #315.

I noticed that `no-useless-assertion` could handle nested assertions (e.g. `/(?=a|$)b/u`). I am now able to fix this issue because `regexp-ast-analysis` exposes the function I needed to fix this.


Patch:
diff --git a/lib/rules/no-useless-assertions.ts b/lib/rules/no-useless-assertions.ts
index 0418f7f..dca0308 100644
--- a/lib/rules/no-useless-assertions.ts
+++ b/lib/rules/no-useless-assertions.ts
@@ -15,6 +15,7 @@ import {
     getMatchingDirectionFromAssertionKind,
     hasSomeDescendant,
     isPotentiallyEmpty,
+    FirstConsumedChars,
 } from "regexp-ast-analysis"
 import { mention } from "../utils/mention"
 
@@ -211,14 +212,13 @@ export default createRule("no-useless-assertions", {
                     return
                 }
 
-                const firstOf = getFirstConsumedChar(
-                    assertion.alternatives,
-                    direction,
-                    flags,
+                const firstOf = FirstConsumedChars.toLook(
+                    getFirstConsumedChar(
+                        assertion.alternatives,
+                        direction,
+                        flags,
+                    ),
                 )
-                if (firstOf.empty) {
-                    return
-                }
 
                 // the idea here is that a negate lookaround accepts when non-negated version reject and vise versa.
                 const accept = assertion.negate ? "reject" : "accept"


Test patch:
diff --git a/tests/lib/rules/no-useless-assertions.ts b/tests/lib/rules/no-useless-assertions.ts
index d1a7ba4..a511603 100644
--- a/tests/lib/rules/no-useless-assertions.ts
+++ b/tests/lib/rules/no-useless-assertions.ts
@@ -356,5 +356,9 @@ tester.run("no-useless-assertions", rule as any, {
                 },
             ],
         },
+        {
+            code: String.raw`/(?=a|$)b/u`,
+            errors: ["The lookahead '(?=a|$)' will always reject."],
+        },
     ],
 })