Refactor ast::GenericParam as a struct
This commit is contained in:
@@ -58,14 +58,6 @@ impl fmt::Debug for Lifetime {
|
||||
}
|
||||
}
|
||||
|
||||
/// A lifetime definition, e.g. `'a: 'b+'c+'d`
|
||||
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
||||
pub struct LifetimeDef {
|
||||
pub attrs: ThinVec<Attribute>,
|
||||
pub lifetime: Lifetime,
|
||||
pub bounds: Vec<Lifetime>
|
||||
}
|
||||
|
||||
/// A "Path" is essentially Rust's notion of a name.
|
||||
///
|
||||
/// It's represented as a sequence of identifiers,
|
||||
@@ -329,31 +321,38 @@ pub enum TraitBoundModifier {
|
||||
pub type TyParamBounds = Vec<TyParamBound>;
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
||||
pub struct TyParam {
|
||||
pub attrs: ThinVec<Attribute>,
|
||||
pub ident: Ident,
|
||||
pub id: NodeId,
|
||||
pub bounds: TyParamBounds,
|
||||
pub default: Option<P<Ty>>,
|
||||
pub enum GenericParamKindAST {
|
||||
/// A lifetime definition, e.g. `'a: 'b+'c+'d`.
|
||||
Lifetime {
|
||||
bounds: Vec<Lifetime>,
|
||||
lifetime: Lifetime,
|
||||
},
|
||||
Type {
|
||||
bounds: TyParamBounds,
|
||||
default: Option<P<Ty>>,
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
||||
pub enum GenericParamAST {
|
||||
Lifetime(LifetimeDef),
|
||||
Type(TyParam),
|
||||
pub struct GenericParamAST {
|
||||
pub ident: Ident,
|
||||
pub id: NodeId,
|
||||
pub attrs: ThinVec<Attribute>,
|
||||
|
||||
pub kind: GenericParamKindAST,
|
||||
}
|
||||
|
||||
impl GenericParamAST {
|
||||
pub fn is_lifetime_param(&self) -> bool {
|
||||
match *self {
|
||||
GenericParamAST::Lifetime(_) => true,
|
||||
match self.kind {
|
||||
GenericParamKindAST::Lifetime { .. } => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_type_param(&self) -> bool {
|
||||
match *self {
|
||||
GenericParamAST::Type(_) => true,
|
||||
match self.kind {
|
||||
GenericParamKindAST::Type { .. } => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
@@ -383,10 +382,8 @@ impl Generics {
|
||||
|
||||
pub fn span_for_name(&self, name: &str) -> Option<Span> {
|
||||
for param in &self.params {
|
||||
if let GenericParamAST::Type(ref t) = *param {
|
||||
if t.ident.name == name {
|
||||
return Some(t.ident.span);
|
||||
}
|
||||
if param.ident.name == name {
|
||||
return Some(param.ident.span);
|
||||
}
|
||||
}
|
||||
None
|
||||
|
||||
@@ -69,7 +69,7 @@ pub trait AstBuilder {
|
||||
id: ast::Ident,
|
||||
attrs: Vec<ast::Attribute>,
|
||||
bounds: ast::TyParamBounds,
|
||||
default: Option<P<ast::Ty>>) -> ast::TyParam;
|
||||
default: Option<P<ast::Ty>>) -> ast::GenericParamAST;
|
||||
|
||||
fn trait_ref(&self, path: ast::Path) -> ast::TraitRef;
|
||||
fn poly_trait_ref(&self, span: Span, path: ast::Path) -> ast::PolyTraitRef;
|
||||
@@ -80,7 +80,7 @@ pub trait AstBuilder {
|
||||
ident: ast::Ident,
|
||||
attrs: Vec<ast::Attribute>,
|
||||
bounds: Vec<ast::Lifetime>)
|
||||
-> ast::LifetimeDef;
|
||||
-> ast::GenericParamAST;
|
||||
|
||||
// statements
|
||||
fn stmt_expr(&self, expr: P<ast::Expr>) -> ast::Stmt;
|
||||
@@ -437,13 +437,15 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
|
||||
ident: ast::Ident,
|
||||
attrs: Vec<ast::Attribute>,
|
||||
bounds: ast::TyParamBounds,
|
||||
default: Option<P<ast::Ty>>) -> ast::TyParam {
|
||||
ast::TyParam {
|
||||
default: Option<P<ast::Ty>>) -> ast::GenericParamAST {
|
||||
ast::GenericParamAST {
|
||||
ident: ident.with_span_pos(span),
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
attrs: attrs.into(),
|
||||
bounds,
|
||||
default,
|
||||
kind: ast::GenericParamKindAST::Type {
|
||||
bounds,
|
||||
default,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -475,11 +477,16 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
|
||||
ident: ast::Ident,
|
||||
attrs: Vec<ast::Attribute>,
|
||||
bounds: Vec<ast::Lifetime>)
|
||||
-> ast::LifetimeDef {
|
||||
ast::LifetimeDef {
|
||||
-> ast::GenericParamAST {
|
||||
let lifetime = self.lifetime(span, ident);
|
||||
ast::GenericParamAST {
|
||||
ident: lifetime.ident,
|
||||
id: lifetime.id,
|
||||
attrs: attrs.into(),
|
||||
lifetime: self.lifetime(span, ident),
|
||||
bounds,
|
||||
kind: ast::GenericParamKindAST::Lifetime {
|
||||
lifetime,
|
||||
bounds,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -687,38 +687,23 @@ pub fn noop_fold_ty_param_bound<T>(tpb: TyParamBound, fld: &mut T)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn noop_fold_ty_param<T: Folder>(tp: TyParam, fld: &mut T) -> TyParam {
|
||||
let TyParam {attrs, id, ident, bounds, default} = tp;
|
||||
let attrs: Vec<_> = attrs.into();
|
||||
TyParam {
|
||||
attrs: attrs.into_iter()
|
||||
.flat_map(|x| fld.fold_attribute(x).into_iter())
|
||||
.collect::<Vec<_>>()
|
||||
.into(),
|
||||
id: fld.new_id(id),
|
||||
ident: fld.fold_ident(ident),
|
||||
bounds: fld.fold_bounds(bounds),
|
||||
default: default.map(|x| fld.fold_ty(x)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn noop_fold_generic_param<T: Folder>(param: GenericParamAST, fld: &mut T) -> GenericParamAST {
|
||||
match param {
|
||||
GenericParamAST::Lifetime(l) => {
|
||||
let attrs: Vec<_> = l.attrs.into();
|
||||
GenericParamAST::Lifetime { bounds, lifetime } => {
|
||||
let attrs: Vec<_> = param.attrs.into();
|
||||
GenericParamAST::Lifetime(LifetimeDef {
|
||||
attrs: attrs.into_iter()
|
||||
.flat_map(|x| fld.fold_attribute(x).into_iter())
|
||||
.collect::<Vec<_>>()
|
||||
.into(),
|
||||
lifetime: Lifetime {
|
||||
id: fld.new_id(l.lifetime.id),
|
||||
ident: fld.fold_ident(l.lifetime.ident),
|
||||
id: fld.new_id(param.id),
|
||||
ident: fld.fold_ident(param.ident),
|
||||
},
|
||||
bounds: l.bounds.move_map(|l| noop_fold_lifetime(l, fld)),
|
||||
bounds: bounds.move_map(|l| noop_fold_lifetime(l, fld)),
|
||||
})
|
||||
}
|
||||
GenericParamAST::Type(t) => GenericParamAST::Type(fld.fold_ty_param(t)),
|
||||
GenericParamAST::Type { .. } => GenericParamAST::Type(fld.fold_ty_param(param)),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -21,10 +21,10 @@ use ast::EnumDef;
|
||||
use ast::{Expr, ExprKind, RangeLimits};
|
||||
use ast::{Field, FnDecl};
|
||||
use ast::{ForeignItem, ForeignItemKind, FunctionRetTy};
|
||||
use ast::GenericParamAST;
|
||||
use ast::{GenericParamAST, GenericParamKindAST};
|
||||
use ast::GenericArgAST;
|
||||
use ast::{Ident, ImplItem, IsAuto, Item, ItemKind};
|
||||
use ast::{Label, Lifetime, LifetimeDef, Lit, LitKind};
|
||||
use ast::{Label, Lifetime, Lit, LitKind};
|
||||
use ast::Local;
|
||||
use ast::MacStmtStyle;
|
||||
use ast::{Mac, Mac_, MacDelimiter};
|
||||
@@ -36,7 +36,7 @@ use ast::{VariantData, StructField};
|
||||
use ast::StrStyle;
|
||||
use ast::SelfKind;
|
||||
use ast::{TraitItem, TraitRef, TraitObjectSyntax};
|
||||
use ast::{Ty, TyKind, TypeBinding, TyParam, TyParamBounds};
|
||||
use ast::{Ty, TyKind, TypeBinding, TyParamBounds};
|
||||
use ast::{Visibility, VisibilityKind, WhereClause, CrateSugar};
|
||||
use ast::{UseTree, UseTreeKind};
|
||||
use ast::{BinOpKind, UnOp};
|
||||
@@ -1311,9 +1311,7 @@ impl<'a> Parser<'a> {
|
||||
let lo = self.span;
|
||||
|
||||
let (name, node, generics) = if self.eat_keyword(keywords::Type) {
|
||||
let (generics, TyParam {ident, bounds, default, ..}) =
|
||||
self.parse_trait_item_assoc_ty(vec![])?;
|
||||
(ident, TraitItemKind::Type(bounds, default), generics)
|
||||
self.parse_trait_item_assoc_ty()?
|
||||
} else if self.is_const_item() {
|
||||
self.expect_keyword(keywords::Const)?;
|
||||
let ident = self.parse_ident()?;
|
||||
@@ -4805,7 +4803,9 @@ impl<'a> Parser<'a> {
|
||||
}
|
||||
|
||||
/// Matches typaram = IDENT (`?` unbound)? optbounds ( EQ ty )?
|
||||
fn parse_ty_param(&mut self, preceding_attrs: Vec<Attribute>) -> PResult<'a, TyParam> {
|
||||
fn parse_ty_param(&mut self,
|
||||
preceding_attrs: Vec<Attribute>)
|
||||
-> PResult<'a, GenericParamAST> {
|
||||
let ident = self.parse_ident()?;
|
||||
|
||||
// Parse optional colon and param bounds.
|
||||
@@ -4821,19 +4821,21 @@ impl<'a> Parser<'a> {
|
||||
None
|
||||
};
|
||||
|
||||
Ok(TyParam {
|
||||
attrs: preceding_attrs.into(),
|
||||
Ok(GenericParamAST {
|
||||
ident,
|
||||
attrs: preceding_attrs.into(),
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
bounds,
|
||||
default,
|
||||
kind: GenericParamKindAST::Type {
|
||||
bounds,
|
||||
default,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// Parses the following grammar:
|
||||
/// TraitItemAssocTy = Ident ["<"...">"] [":" [TyParamBounds]] ["where" ...] ["=" Ty]
|
||||
fn parse_trait_item_assoc_ty(&mut self, preceding_attrs: Vec<Attribute>)
|
||||
-> PResult<'a, (ast::Generics, TyParam)> {
|
||||
fn parse_trait_item_assoc_ty(&mut self)
|
||||
-> PResult<'a, (Ident, TraitItemKind, ast::Generics)> {
|
||||
let ident = self.parse_ident()?;
|
||||
let mut generics = self.parse_generics()?;
|
||||
|
||||
@@ -4852,13 +4854,7 @@ impl<'a> Parser<'a> {
|
||||
};
|
||||
self.expect(&token::Semi)?;
|
||||
|
||||
Ok((generics, TyParam {
|
||||
attrs: preceding_attrs.into(),
|
||||
ident,
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
bounds,
|
||||
default,
|
||||
}))
|
||||
Ok((ident, TraitItemKind::Type(bounds, default), generics))
|
||||
}
|
||||
|
||||
/// Parses (possibly empty) list of lifetime and type parameters, possibly including
|
||||
@@ -4876,18 +4872,22 @@ impl<'a> Parser<'a> {
|
||||
} else {
|
||||
Vec::new()
|
||||
};
|
||||
params.push(ast::GenericParamAST::Lifetime(LifetimeDef {
|
||||
params.push(ast::GenericParamAST {
|
||||
ident: lifetime.ident,
|
||||
id: lifetime.id,
|
||||
attrs: attrs.into(),
|
||||
lifetime,
|
||||
bounds,
|
||||
}));
|
||||
kind: ast::GenericParamKindAST::Lifetime {
|
||||
lifetime,
|
||||
bounds,
|
||||
}
|
||||
});
|
||||
if seen_ty_param {
|
||||
self.span_err(self.prev_span,
|
||||
"lifetime parameters must be declared prior to type parameters");
|
||||
}
|
||||
} else if self.check_ident() {
|
||||
// Parse type parameter.
|
||||
params.push(ast::GenericParamAST::Type(self.parse_ty_param(attrs)?));
|
||||
params.push(self.parse_ty_param(attrs)?);
|
||||
seen_ty_param = true;
|
||||
} else {
|
||||
// Check for trailing attributes and stop parsing.
|
||||
|
||||
@@ -2878,12 +2878,24 @@ impl<'a> State<'a> {
|
||||
self.s.word("<")?;
|
||||
|
||||
self.commasep(Inconsistent, &generic_params, |s, param| {
|
||||
match *param {
|
||||
ast::GenericParamAST::Lifetime(ref lifetime_def) => {
|
||||
s.print_outer_attributes_inline(&lifetime_def.attrs)?;
|
||||
s.print_lifetime_bounds(&lifetime_def.lifetime, &lifetime_def.bounds)
|
||||
match param.kind {
|
||||
ast::GenericParamKindAST::Lifetime { ref bounds, ref lifetime } => {
|
||||
s.print_outer_attributes_inline(¶m.attrs)?;
|
||||
s.print_lifetime_bounds(lifetime, bounds)
|
||||
},
|
||||
ast::GenericParamAST::Type(ref ty_param) => s.print_ty_param(ty_param),
|
||||
ast::GenericParamKindAST::Type { ref bounds, ref default } => {
|
||||
s.print_outer_attributes_inline(¶m.attrs)?;
|
||||
s.print_ident(param.ident)?;
|
||||
s.print_bounds(":", bounds)?;
|
||||
match default {
|
||||
Some(ref default) => {
|
||||
s.s.space()?;
|
||||
s.word_space("=")?;
|
||||
s.print_type(default)
|
||||
}
|
||||
_ => Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
})?;
|
||||
|
||||
@@ -2891,20 +2903,6 @@ impl<'a> State<'a> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn print_ty_param(&mut self, param: &ast::TyParam) -> io::Result<()> {
|
||||
self.print_outer_attributes_inline(¶m.attrs)?;
|
||||
self.print_ident(param.ident)?;
|
||||
self.print_bounds(":", ¶m.bounds)?;
|
||||
match param.default {
|
||||
Some(ref default) => {
|
||||
self.s.space()?;
|
||||
self.word_space("=")?;
|
||||
self.print_type(default)
|
||||
}
|
||||
_ => Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn print_where_clause(&mut self, where_clause: &ast::WhereClause)
|
||||
-> io::Result<()> {
|
||||
if where_clause.predicates.is_empty() {
|
||||
|
||||
@@ -491,17 +491,17 @@ pub fn walk_ty_param_bound<'a, V: Visitor<'a>>(visitor: &mut V, bound: &'a TyPar
|
||||
}
|
||||
|
||||
pub fn walk_generic_param<'a, V: Visitor<'a>>(visitor: &mut V, param: &'a GenericParamAST) {
|
||||
match *param {
|
||||
GenericParamAST::Lifetime(ref l) => {
|
||||
visitor.visit_ident(l.lifetime.ident);
|
||||
walk_list!(visitor, visit_lifetime, &l.bounds);
|
||||
walk_list!(visitor, visit_attribute, &*l.attrs);
|
||||
match param.kind {
|
||||
GenericParamKindAST::Lifetime { ref bounds, ref lifetime, .. } => {
|
||||
visitor.visit_ident(param.ident);
|
||||
walk_list!(visitor, visit_lifetime, bounds);
|
||||
walk_list!(visitor, visit_attribute, param.attrs.iter());
|
||||
}
|
||||
GenericParamAST::Type(ref t) => {
|
||||
GenericParamKindAST::Type { ref bounds, ref default, .. } => {
|
||||
visitor.visit_ident(t.ident);
|
||||
walk_list!(visitor, visit_ty_param_bound, &t.bounds);
|
||||
walk_list!(visitor, visit_ty, &t.default);
|
||||
walk_list!(visitor, visit_attribute, &*t.attrs);
|
||||
walk_list!(visitor, visit_ty_param_bound, bounds);
|
||||
walk_list!(visitor, visit_ty, default);
|
||||
walk_list!(visitor, visit_attribute, param.attrs.iter());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user