Reproduction
use matchit::Router;
fn main() {
let mut r1 = Router::new();
r1.insert("/foo{a}", 1).unwrap();
assert!(r1.insert("/{a}/bar", 2).is_err()); // Conflict
let mut r2 = Router::new();
r2.insert("/{a}/bar", 2).unwrap();
r2.insert("/foo{a}", 1).unwrap(); // OK
}
Also fails for /foo{a} then /{a}/{b}.
Suspected cause
The wildcard branch (src/tree.rs:390-398) has the same prefix-suffix check that commit 500698f fixed for the static branch, but still slices the suffix past the end of the segment:
let suffix = remaining.slice_off(wildcard.end); // line 392
if !matches!(*suffix, b"" | b"/") && node.prefix_wild_child_in_segment() {
return Err(InsertError::conflict(&route, remaining, node));
}
For /{a}/bar, suffix becomes /bar, so it conflicts with the existing /foo{a}. The segment-local suffix should be /.
The static branch already limits this check to the segment (src/tree.rs:313-327):
let terminator = remaining.iter().position(|&b| b == b'/').unwrap_or(remaining.len());
let suffix = remaining.slice_until(terminator).slice_off(wildcard.end);
Reproduction
Also fails for
/foo{a}then/{a}/{b}.Suspected cause
The wildcard branch (
src/tree.rs:390-398) has the same prefix-suffix check that commit500698ffixed for the static branch, but still slices the suffix past the end of the segment:For
/{a}/bar,suffixbecomes/bar, so it conflicts with the existing/foo{a}. The segment-local suffix should be/.The static branch already limits this check to the segment (
src/tree.rs:313-327):