Skip to content

Commit

Permalink
Parse generic associated type equality constraint
Browse files Browse the repository at this point in the history
  • Loading branch information
dtolnay committed Mar 29, 2021
1 parent 1a31fb2 commit d3b0276
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 23 deletions.
74 changes: 57 additions & 17 deletions src/path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,44 @@ 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 if input.peek(Token![=]) {
input.parse::<Token![=]>()?;
input.parse::<Type>()?;
true
} else if input.peek(Token![:]) {
input.parse::<Token![:]>()?;
input.call(constraint_bounds)?;
true
} else {
false
} {
let verbatim = verbatim::between(begin, input);
return Ok(GenericArgument::Type(Type::Verbatim(verbatim)));
}
}
}

Ok(GenericArgument::Type(argument))
}
}

Expand Down Expand Up @@ -368,26 +405,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<Punctuated<TypeParamBound, Token![+]>> {
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.
///
Expand Down
6 changes: 0 additions & 6 deletions tests/repo/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down

0 comments on commit d3b0276

Please sign in to comment.