Make `alt!` unify generic type `E` to prevent underspecification
Add a compiler-time hack to ensure that the `E` type of a subexpression
is not underspecified, leading to the error "unable to infer enough type
information about `E`".
No change to runtime behaviour.
Fixes
@@ -138,8 +138,17 @@ macro_rules! alt (
match $subrule!( $i, $($args)* ) {
$crate::IResult::Done(i,o) => $crate::IResult::Done(i,$gen(o)),
$crate::IResult::Incomplete(x) => $crate::IResult::Incomplete(x),
- $crate::IResult::Error(_) => {
- alt!(__impl $i, $($rest)*)
+ $crate::IResult::Error(e) => {
+ let out = alt!(__impl $i, $($rest)*);
+
+ // Compile-time hack to ensure that res's E type is not under-specified.
+ // This all has no effect at runtime.
+ fn unify_types<T>(_: &T, _: &T) {}
+ if let $crate::IResult::Error(ref e2) = out {
+ unify_types(&e, e2);
+ }
+
+ out
}
}
}
@@ -656,6 +665,11 @@ mod tests {
assert_eq!(alt5(a), Done(&b""[..], false));
assert_eq!(alt5(b), Done(&b""[..], true));
+ // compile-time test guarding against an underspecified E generic type (#474)
+ named!(alt_eof1, alt!(eof!() | eof!()));
+ named!(alt_eof2, alt!(eof!() => {|x| x} | eof!() => {|x| x}));
+ let _ = (alt_eof1, alt_eof2);
+
}
#[test]
