diff --git a/src/exec.rs b/src/exec.rs index 68a9e18f43..3192ce7928 100644 --- a/src/exec.rs +++ b/src/exec.rs @@ -210,6 +210,9 @@ impl ExecBuilder { let mut prefixes = Some(Literals::empty()); let mut suffixes = Some(Literals::empty()); let mut bytes = false; + let is_set = self.options.pats.len() > 1; + // If we're compiling a regex set and that set has any anchored + // expressions, then disable all literal optimizations. for pat in &self.options.pats { let parser = ExprBuilder::new() @@ -227,6 +230,10 @@ impl ExecBuilder { // Partial anchors unfortunately make it hard to use prefixes, // so disable them. prefixes = None; + } else if is_set && expr.is_anchored_start() { + // Regex sets with anchors do not go well with literal + // optimizations. + prefixes = None; } prefixes = prefixes.and_then(|mut prefixes| { if !prefixes.union_prefixes(&expr) { @@ -240,6 +247,10 @@ impl ExecBuilder { // Partial anchors unfortunately make it hard to use suffixes, // so disable them. suffixes = None; + } else if is_set && expr.is_anchored_end() { + // Regex sets with anchors do not go well with literal + // optimizations. + prefixes = None; } suffixes = suffixes.and_then(|mut suffixes| { if !suffixes.union_suffixes(&expr) { diff --git a/tests/set.rs b/tests/set.rs index 70cfba830f..d9842ace6a 100644 --- a/tests/set.rs +++ b/tests/set.rs @@ -20,6 +20,7 @@ matset!(set18, &["a", "β"], "β", 1); nomatset!(nset1, &["a", "a"], "b"); nomatset!(nset2, &["^foo", "bar$"], "bar foo"); nomatset!(nset3, { let xs: &[&str] = &[]; xs }, "a"); +nomatset!(nset4, &[r"^rooted$", r"\.log$"], "notrooted"); // See: https://github.com/rust-lang/regex/issues/187 #[test]