Skip to content

Commit

Permalink
Merge pull request #1499 from dtolnay/genericconst
Browse files Browse the repository at this point in the history
Parse generic const items
  • Loading branch information
dtolnay authored Sep 3, 2023
2 parents 78f94ea + aafea03 commit cd479c0
Show file tree
Hide file tree
Showing 2 changed files with 114 additions and 75 deletions.
179 changes: 114 additions & 65 deletions src/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -985,23 +985,28 @@ pub(crate) mod parsing {
} else {
return Err(lookahead.error());
};
let mut generics: Generics = input.parse()?;
let colon_token = input.parse()?;
let ty = input.parse()?;
if input.peek(Token![;]) {
input.parse::<Token![;]>()?;
Ok(Item::Verbatim(verbatim::between(&begin, input)))
} else {
let eq_token: Token![=] = input.parse()?;
let expr: Expr = input.parse()?;
generics.where_clause = input.parse()?;
let semi_token: Token![;] = input.parse()?;
Ok(Item::Const(ItemConst {
attrs: Vec::new(),
vis,
const_token,
ident,
generics: Generics::default(),
generics,
colon_token,
ty,
eq_token: input.parse()?,
expr: input.parse()?,
semi_token: input.parse()?,
eq_token,
expr: Box::new(expr),
semi_token,
}))
}
} else if lookahead.peek(Token![unsafe]) {
Expand Down Expand Up @@ -1400,24 +1405,36 @@ pub(crate) mod parsing {
#[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
impl Parse for ItemConst {
fn parse(input: ParseStream) -> Result<Self> {
let attrs = input.call(Attribute::parse_outer)?;
let vis: Visibility = input.parse()?;
let const_token: Token![const] = input.parse()?;

let lookahead = input.lookahead1();
let ident = if lookahead.peek(Ident) || lookahead.peek(Token![_]) {
input.call(Ident::parse_any)?
} else {
return Err(lookahead.error());
};

let mut generics: Generics = input.parse()?;
let colon_token: Token![:] = input.parse()?;
let ty: Type = input.parse()?;
let eq_token: Token![=] = input.parse()?;
let expr: Expr = input.parse()?;
generics.where_clause = input.parse()?;
let semi_token: Token![;] = input.parse()?;

Ok(ItemConst {
attrs: input.call(Attribute::parse_outer)?,
vis: input.parse()?,
const_token: input.parse()?,
ident: {
let lookahead = input.lookahead1();
if lookahead.peek(Ident) || lookahead.peek(Token![_]) {
input.call(Ident::parse_any)?
} else {
return Err(lookahead.error());
}
},
generics: Generics::default(),
colon_token: input.parse()?,
ty: input.parse()?,
eq_token: input.parse()?,
expr: input.parse()?,
semi_token: input.parse()?,
attrs,
vis,
const_token,
ident,
generics,
colon_token,
ty: Box::new(ty),
eq_token,
expr: Box::new(expr),
semi_token,
})
}
}
Expand Down Expand Up @@ -2273,30 +2290,38 @@ pub(crate) mod parsing {
#[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
impl Parse for TraitItemConst {
fn parse(input: ParseStream) -> Result<Self> {
let attrs = input.call(Attribute::parse_outer)?;
let const_token: Token![const] = input.parse()?;

let lookahead = input.lookahead1();
let ident = if lookahead.peek(Ident) || lookahead.peek(Token![_]) {
input.call(Ident::parse_any)?
} else {
return Err(lookahead.error());
};

let mut generics: Generics = input.parse()?;
let colon_token: Token![:] = input.parse()?;
let ty: Type = input.parse()?;
let default = if input.peek(Token![=]) {
let eq_token: Token![=] = input.parse()?;
let default: Expr = input.parse()?;
Some((eq_token, default))
} else {
None
};
generics.where_clause = input.parse()?;
let semi_token: Token![;] = input.parse()?;

Ok(TraitItemConst {
attrs: input.call(Attribute::parse_outer)?,
const_token: input.parse()?,
ident: {
let lookahead = input.lookahead1();
if lookahead.peek(Ident) || lookahead.peek(Token![_]) {
input.call(Ident::parse_any)?
} else {
return Err(lookahead.error());
}
},
generics: Generics::default(),
colon_token: input.parse()?,
ty: input.parse()?,
default: {
if input.peek(Token![=]) {
let eq_token: Token![=] = input.parse()?;
let default: Expr = input.parse()?;
Some((eq_token, default))
} else {
None
}
},
semi_token: input.parse()?,
attrs,
const_token,
ident,
generics,
colon_token,
ty,
default,
semi_token,
})
}
}
Expand Down Expand Up @@ -2550,23 +2575,28 @@ pub(crate) mod parsing {
} else {
return Err(lookahead.error());
};
let mut generics: Generics = input.parse()?;
let colon_token: Token![:] = input.parse()?;
let ty: Type = input.parse()?;
if let Some(eq_token) = input.parse()? {
let expr: Expr = input.parse()?;
generics.where_clause = input.parse()?;
let semi_token: Token![;] = input.parse()?;
return Ok(ImplItem::Const(ImplItemConst {
attrs,
vis,
defaultness,
const_token,
ident,
generics: Generics::default(),
generics,
colon_token,
ty,
eq_token,
expr: input.parse()?,
semi_token: input.parse()?,
expr,
semi_token,
}));
} else {
input.parse::<Option<WhereClause>>()?;
input.parse::<Token![;]>()?;
return Ok(ImplItem::Verbatim(verbatim::between(&begin, input)));
}
Expand Down Expand Up @@ -2604,25 +2634,38 @@ pub(crate) mod parsing {
#[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
impl Parse for ImplItemConst {
fn parse(input: ParseStream) -> Result<Self> {
let attrs = input.call(Attribute::parse_outer)?;
let vis: Visibility = input.parse()?;
let defaultness: Option<Token![default]> = input.parse()?;
let const_token: Token![const] = input.parse()?;

let lookahead = input.lookahead1();
let ident = if lookahead.peek(Ident) || lookahead.peek(Token![_]) {
input.call(Ident::parse_any)?
} else {
return Err(lookahead.error());
};

let mut generics: Generics = input.parse()?;
let colon_token: Token![:] = input.parse()?;
let ty: Type = input.parse()?;
let eq_token: Token![=] = input.parse()?;
let expr: Expr = input.parse()?;
generics.where_clause = input.parse()?;
let semi_token: Token![;] = input.parse()?;

Ok(ImplItemConst {
attrs: input.call(Attribute::parse_outer)?,
vis: input.parse()?,
defaultness: input.parse()?,
const_token: input.parse()?,
ident: {
let lookahead = input.lookahead1();
if lookahead.peek(Ident) || lookahead.peek(Token![_]) {
input.call(Ident::parse_any)?
} else {
return Err(lookahead.error());
}
},
generics: Generics::default(),
colon_token: input.parse()?,
ty: input.parse()?,
eq_token: input.parse()?,
expr: input.parse()?,
semi_token: input.parse()?,
attrs,
vis,
defaultness,
const_token,
ident,
generics,
colon_token,
ty,
eq_token,
expr,
semi_token,
})
}
}
Expand Down Expand Up @@ -2834,10 +2877,12 @@ mod printing {
self.vis.to_tokens(tokens);
self.const_token.to_tokens(tokens);
self.ident.to_tokens(tokens);
self.generics.to_tokens(tokens);
self.colon_token.to_tokens(tokens);
self.ty.to_tokens(tokens);
self.eq_token.to_tokens(tokens);
self.expr.to_tokens(tokens);
self.generics.where_clause.to_tokens(tokens);
self.semi_token.to_tokens(tokens);
}
}
Expand Down Expand Up @@ -3084,12 +3129,14 @@ mod printing {
tokens.append_all(self.attrs.outer());
self.const_token.to_tokens(tokens);
self.ident.to_tokens(tokens);
self.generics.to_tokens(tokens);
self.colon_token.to_tokens(tokens);
self.ty.to_tokens(tokens);
if let Some((eq_token, default)) = &self.default {
eq_token.to_tokens(tokens);
default.to_tokens(tokens);
}
self.generics.where_clause.to_tokens(tokens);
self.semi_token.to_tokens(tokens);
}
}
Expand Down Expand Up @@ -3150,10 +3197,12 @@ mod printing {
self.defaultness.to_tokens(tokens);
self.const_token.to_tokens(tokens);
self.ident.to_tokens(tokens);
self.generics.to_tokens(tokens);
self.colon_token.to_tokens(tokens);
self.ty.to_tokens(tokens);
self.eq_token.to_tokens(tokens);
self.expr.to_tokens(tokens);
self.generics.where_clause.to_tokens(tokens);
self.semi_token.to_tokens(tokens);
}
}
Expand Down
10 changes: 0 additions & 10 deletions tests/repo/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,6 @@ const REVISION: &str = "9f5fc1bd443f59583e7af0d94d289f95fe1e20c4";

#[rustfmt::skip]
static EXCLUDE_FILES: &[&str] = &[
// TODO: generic const items
// https://github.com/dtolnay/syn/issues/1497
"tests/rustdoc/generic-const-items.rs",
"tests/rustdoc/inline_cross/auxiliary/generic-const-items.rs",
"tests/ui/generic-const-items/associated-const-equality.rs",
"tests/ui/generic-const-items/basic.rs",
"tests/ui/generic-const-items/recursive.rs",
"tests/ui/object-safety/assoc_const_bounds.rs",
"tests/ui/object-safety/assoc_const_bounds_sized.rs",

// CStr literals (c"…") are not yet supported by rustc's lexer
// https://github.com/rust-lang/rust/issues/113333
"src/tools/clippy/tests/ui/needless_raw_string_hashes.rs",
Expand Down

0 comments on commit cd479c0

Please sign in to comment.