When writing a macro to match a type parameter, I ran into the requirement that paths must not be followed by a +
character. Ideally the bound on the type could be matched with : $bound:path $(+ $bounds:path)*
, but this is not allowed. It seems like allowing a +
to occur here should not make the grammar ambiguous, or open Rust to future ambiguity if paths get changed, because a +
is already used to separate bounds in the Rust grammar. Am I missing some compelling reason why +
should not be allowed in this position?
It might be because something like Fn() -> &dyn Error
is also considered a path (yeah, I know, not the most intuitive thing.. but try it out), and terminating that with a +
might be confusing.
That's a good idea! However, it looks like there's already a rule keeping it from being ambiguous.
macro_rules! check_if_path {
{ $a:path } => {}
}
check_if_path!{Fn() -> &dyn Error + 'a}
Errors with:
error: ambiguous `+` in a type
--> src/lib.rs:5:25
|
5 | check_if_path!{Fn() -> &dyn Error + 'a}
| ^^^^^^^^^^^^^^ help: use parentheses to disambiguate: `(dyn Error + 'a)`
At the risk of going off topic...why is that considered a path?
Fn(Args..) -> Ret
is syntax sugar for the type path ::core::ops::Fn::<Args=Args.., Result=Ret>
. Writing the former would ideally be identical to writing the latter.
Not sure I particularly agree with it, but at least there's a valid reason
Paths are used in the grammar to specify trait bounds, which include Fn(Args) -> Ret
syntax. See https://doc.rust-lang.org/reference/trait-bounds.html (the nonterminal is called TypePath).
This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.