diff --git a/src/path.rs b/src/path.rs index 90e2970d30..df1788db53 100644 --- a/src/path.rs +++ b/src/path.rs @@ -245,7 +245,42 @@ pub mod parsing { return const_argument(input).map(GenericArgument::Const); } - input.parse().map(GenericArgument::Type) + #[cfg(feature = "full")] + let begin = input.fork(); + + let argument: Type = input.parse()?; + + #[cfg(feature = "full")] + { + if match &argument { + Type::Path(argument) + if argument.qself.is_none() + && argument.path.leading_colon.is_none() + && argument.path.segments.len() == 1 => + { + match argument.path.segments[0].arguments { + PathArguments::AngleBracketed(_) => true, + _ => false, + } + } + _ => false, + } && if input.peek(Token![=]) { + input.parse::()?; + input.parse::()?; + true + } else if input.peek(Token![:]) { + input.parse::()?; + input.call(constraint_bounds)?; + true + } else { + false + } { + let verbatim = verbatim::between(begin, input); + return Ok(GenericArgument::Type(Type::Verbatim(verbatim))); + } + } + + Ok(GenericArgument::Type(argument)) } } @@ -368,26 +403,29 @@ pub mod parsing { Ok(Constraint { ident: input.parse()?, colon_token: input.parse()?, - bounds: { - let mut bounds = Punctuated::new(); - loop { - if input.peek(Token![,]) || input.peek(Token![>]) { - break; - } - let value = input.parse()?; - bounds.push_value(value); - if !input.peek(Token![+]) { - break; - } - let punct = input.parse()?; - bounds.push_punct(punct); - } - bounds - }, + bounds: constraint_bounds(input)?, }) } } + #[cfg(feature = "full")] + fn constraint_bounds(input: ParseStream) -> Result> { + let mut bounds = Punctuated::new(); + loop { + if input.peek(Token![,]) || input.peek(Token![>]) { + break; + } + let value = input.parse()?; + bounds.push_value(value); + if !input.peek(Token![+]) { + break; + } + let punct = input.parse()?; + bounds.push_punct(punct); + } + Ok(bounds) + } + impl Path { /// Parse a `Path` containing no path arguments on any of its segments. /// diff --git a/tests/repo/mod.rs b/tests/repo/mod.rs index eeebbb8279..24b620c51f 100644 --- a/tests/repo/mod.rs +++ b/tests/repo/mod.rs @@ -12,12 +12,6 @@ const REVISION: &str = "52e3dffa50cfffdcfa145c0cc0ba48b49abc0c07"; #[rustfmt::skip] static EXCLUDE: &[&str] = &[ - // TODO: generic associated type equality constraint - // https://github.com/dtolnay/syn/issues/979 - "src/test/pretty/gat-bounds.rs", - "src/test/ui/generic-associated-types/generic-associated-type-bounds.rs", - "src/test/ui/generic-associated-types/issue-80433-reduced.rs", - // Compile-fail expr parameter in const generic position: f::<1 + 2>() "src/test/ui/const-generics/closing-args-token.rs", "src/test/ui/const-generics/const-expression-parameter.rs",