diff --git a/grep-regex/src/literal.rs b/grep-regex/src/literal.rs index c3960ae..b8a0c1d 100644 --- a/grep-regex/src/literal.rs +++ b/grep-regex/src/literal.rs @@ -166,10 +166,10 @@ fn union_required(expr: &Hir, lits: &mut Literals) { lits.cut(); continue; } - if lits2.contains_empty() { + if lits2.contains_empty() || !is_simple(&e) { lits.cut(); } - if !lits.cross_product(&lits2) { + if !lits.cross_product(&lits2) || !lits2.any_complete() { // If this expression couldn't yield any literal that // could be extended, then we need to quit. Since we're // short-circuiting, we also need to freeze every member. @@ -250,6 +250,20 @@ fn alternate_literals( } } +fn is_simple(expr: &Hir) -> bool { + match *expr.kind() { + HirKind::Empty + | HirKind::Literal(_) + | HirKind::Class(_) + | HirKind::Repetition(_) + | HirKind::Concat(_) + | HirKind::Alternation(_) => true, + HirKind::Anchor(_) + | HirKind::WordBoundary(_) + | HirKind::Group(_) => false, + } +} + /// Return the number of characters in the given class. fn count_unicode_class(cls: &hir::ClassUnicode) -> u32 { cls.iter().map(|r| 1 + (r.end() as u32 - r.start() as u32)).sum() @@ -301,4 +315,12 @@ mod tests { // assert_eq!(one_regex(r"\w(foo|bar|baz)"), pat("foo|bar|baz")); // assert_eq!(one_regex(r"\w(foo|bar|baz)\w"), pat("foo|bar|baz")); } + + #[test] + fn regression_1064() { + // Regression from: + // https://github.com/BurntSushi/ripgrep/issues/1064 + // assert_eq!(one_regex(r"a.*c"), pat("a")); + assert_eq!(one_regex(r"a(.*c)"), pat("a")); + } } diff --git a/tests/regression.rs b/tests/regression.rs index f2553d9..abf29bd 100644 --- a/tests/regression.rs +++ b/tests/regression.rs @@ -562,3 +562,9 @@ rgtest!(r900, |dir: Dir, mut cmd: TestCommand| { cmd.arg("-fpat").arg("sherlock").assert_err(); }); + +// See: https://github.com/BurntSushi/ripgrep/issues/1064 +rgtest!(r1064, |dir: Dir, mut cmd: TestCommand| { + dir.create("input", "abc"); + eqnice!("input:abc\n", cmd.arg("a(.*c)").stdout()); +});