Skip to content

Commit

Permalink
Merge pull request #1503 from dtolnay/constverbatim
Browse files Browse the repository at this point in the history
Parse const item with generics as Verbatim
  • Loading branch information
dtolnay authored Sep 3, 2023
2 parents b80156e + 8cdfd09 commit 0cfdca7
Show file tree
Hide file tree
Showing 2 changed files with 108 additions and 52 deletions.
116 changes: 68 additions & 48 deletions src/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -996,21 +996,24 @@ pub(crate) mod parsing {
};
generics.where_clause = input.parse()?;
let semi_token: Token![;] = input.parse()?;
if let Some((eq_token, expr)) = value {
Ok(Item::Const(ItemConst {
attrs: Vec::new(),
vis,
const_token,
ident,
generics,
colon_token,
ty,
eq_token,
expr: Box::new(expr),
semi_token,
}))
} else {
Ok(Item::Verbatim(verbatim::between(&begin, input)))
match value {
Some((eq_token, expr))
if generics.lt_token.is_none() && generics.where_clause.is_none() =>
{
Ok(Item::Const(ItemConst {
attrs: Vec::new(),
vis,
const_token,
ident,
generics,
colon_token,
ty,
eq_token,
expr: Box::new(expr),
semi_token,
}))
}
_ => Ok(Item::Verbatim(verbatim::between(&begin, input))),
}
} else if lookahead.peek(Token![unsafe]) {
ahead.parse::<Token![unsafe]>()?;
Expand Down Expand Up @@ -1419,20 +1422,18 @@ pub(crate) mod parsing {
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,
vis,
const_token,
ident,
generics,
generics: Generics::default(),
colon_token,
ty: Box::new(ty),
eq_token,
Expand Down Expand Up @@ -2244,10 +2245,36 @@ pub(crate) mod parsing {
let mut item = if lookahead.peek(Token![fn]) || peek_signature(&ahead) {
input.parse().map(TraitItem::Fn)
} else if lookahead.peek(Token![const]) {
ahead.parse::<Token![const]>()?;
let const_token: Token![const] = ahead.parse()?;
let lookahead = ahead.lookahead1();
if lookahead.peek(Ident) || lookahead.peek(Token![_]) {
input.parse().map(TraitItem::Const)
input.advance_to(&ahead);
let ident = input.call(Ident::parse_any)?;
let mut generics: Generics = input.parse()?;
let colon_token: Token![:] = input.parse()?;
let ty: Type = input.parse()?;
let default = if let Some(eq_token) = input.parse::<Option<Token![=]>>()? {
let expr: Expr = input.parse()?;
Some((eq_token, expr))
} else {
None
};
generics.where_clause = input.parse()?;
let semi_token: Token![;] = input.parse()?;
if generics.lt_token.is_none() && generics.where_clause.is_none() {
Ok(TraitItem::Const(TraitItemConst {
attrs: Vec::new(),
const_token,
ident,
generics,
colon_token,
ty,
default,
semi_token,
}))
} else {
return Ok(TraitItem::Verbatim(verbatim::between(&begin, input)));
}
} else if lookahead.peek(Token![async])
|| lookahead.peek(Token![unsafe])
|| lookahead.peek(Token![extern])
Expand Down Expand Up @@ -2303,7 +2330,6 @@ pub(crate) mod parsing {
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![=]) {
Expand All @@ -2313,14 +2339,13 @@ pub(crate) mod parsing {
} else {
None
};
generics.where_clause = input.parse()?;
let semi_token: Token![;] = input.parse()?;

Ok(TraitItemConst {
attrs,
const_token,
ident,
generics,
generics: Generics::default(),
colon_token,
ty,
default,
Expand Down Expand Up @@ -2589,22 +2614,25 @@ pub(crate) mod parsing {
};
generics.where_clause = input.parse()?;
let semi_token: Token![;] = input.parse()?;
return if let Some((eq_token, expr)) = value {
Ok(ImplItem::Const(ImplItemConst {
attrs,
vis,
defaultness,
const_token,
ident,
generics,
colon_token,
ty,
eq_token,
expr,
semi_token,
}))
} else {
Ok(ImplItem::Verbatim(verbatim::between(&begin, input)))
return match value {
Some((eq_token, expr))
if generics.lt_token.is_none() && generics.where_clause.is_none() =>
{
Ok(ImplItem::Const(ImplItemConst {
attrs,
vis,
defaultness,
const_token,
ident,
generics,
colon_token,
ty,
eq_token,
expr,
semi_token,
}))
}
_ => Ok(ImplItem::Verbatim(verbatim::between(&begin, input))),
};
} else if lookahead.peek(Token![type]) {
parse_impl_item_type(begin, input)
Expand Down Expand Up @@ -2652,12 +2680,10 @@ pub(crate) mod parsing {
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 {
Expand All @@ -2666,7 +2692,7 @@ pub(crate) mod parsing {
defaultness,
const_token,
ident,
generics,
generics: Generics::default(),
colon_token,
ty,
eq_token,
Expand Down Expand Up @@ -2883,12 +2909,10 @@ 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 @@ -3135,14 +3159,12 @@ 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 @@ -3203,12 +3225,10 @@ 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
44 changes: 40 additions & 4 deletions tests/test_precedence.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ extern crate rustc_ast_pretty;
extern crate rustc_data_structures;
extern crate rustc_driver;
extern crate rustc_span;
extern crate smallvec;
extern crate thin_vec;

use crate::common::eq::SpanlessEq;
Expand Down Expand Up @@ -168,15 +169,17 @@ fn librustc_parse_and_rewrite(input: &str) -> Option<P<ast::Expr>> {
/// This method operates on librustc objects.
fn librustc_brackets(mut librustc_expr: P<ast::Expr>) -> Option<P<ast::Expr>> {
use rustc_ast::ast::{
Attribute, BinOpKind, Block, BorrowKind, Expr, ExprField, ExprKind, GenericArg,
GenericBound, Local, LocalKind, Pat, Stmt, StmtKind, StructExpr, StructRest,
TraitBoundModifier, Ty,
AssocItem, AssocItemKind, Attribute, BinOpKind, Block, BorrowKind, Expr, ExprField,
ExprKind, GenericArg, GenericBound, ItemKind, Local, LocalKind, Pat, Stmt, StmtKind,
StructExpr, StructRest, TraitBoundModifier, Ty,
};
use rustc_ast::mut_visit::{
noop_visit_generic_arg, noop_visit_local, noop_visit_param_bound, MutVisitor,
noop_flat_map_assoc_item, noop_visit_generic_arg, noop_visit_item_kind, noop_visit_local,
noop_visit_param_bound, MutVisitor,
};
use rustc_data_structures::flat_map_in_place::FlatMapInPlace;
use rustc_span::DUMMY_SP;
use smallvec::SmallVec;
use std::mem;
use std::ops::DerefMut;
use thin_vec::ThinVec;
Expand Down Expand Up @@ -300,6 +303,39 @@ fn librustc_brackets(mut librustc_expr: P<ast::Expr>) -> Option<P<ast::Expr>> {
}
}

fn visit_item_kind(&mut self, item: &mut ItemKind) {
match item {
ItemKind::Const(const_item)
if !const_item.generics.params.is_empty()
|| !const_item.generics.where_clause.predicates.is_empty() => {}
_ => noop_visit_item_kind(item, self),
}
}

fn flat_map_trait_item(&mut self, item: P<AssocItem>) -> SmallVec<[P<AssocItem>; 1]> {
match &item.kind {
AssocItemKind::Const(const_item)
if !const_item.generics.params.is_empty()
|| !const_item.generics.where_clause.predicates.is_empty() =>
{
SmallVec::from([item])
}
_ => noop_flat_map_assoc_item(item, self),
}
}

fn flat_map_impl_item(&mut self, item: P<AssocItem>) -> SmallVec<[P<AssocItem>; 1]> {
match &item.kind {
AssocItemKind::Const(const_item)
if !const_item.generics.params.is_empty()
|| !const_item.generics.where_clause.predicates.is_empty() =>
{
SmallVec::from([item])
}
_ => noop_flat_map_assoc_item(item, self),
}
}

// We don't want to look at expressions that might appear in patterns or
// types yet. We'll look into comparing those in the future. For now
// focus on expressions appearing in other places.
Expand Down

0 comments on commit 0cfdca7

Please sign in to comment.