Auto merge of #45930 - jplatte:generics_refactoring, r=eddyb

Generics refactoring (groundwork for const generics)

These changes were suggested by @eddyb.

After this change, the `Generics` contain one `Vec` of an enum for the generic parameters, rather than two separate `Vec`s for lifetime and type parameters. Type params and const params will need to be in a shared `Vec` to preserve their ordering, and moving lifetimes into the same `Vec` should simplify the code that processes `Generics`.
This commit is contained in:
bors
2017-12-21 20:12:13 +00:00
51 changed files with 1020 additions and 832 deletions

View File

@@ -301,30 +301,56 @@ pub struct TyParam {
pub span: Span,
}
/// Represents lifetimes and type parameters attached to a declaration
/// of a function, enum, trait, etc.
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub enum GenericParam {
Lifetime(LifetimeDef),
Type(TyParam),
}
impl GenericParam {
pub fn is_lifetime_param(&self) -> bool {
match *self {
GenericParam::Lifetime(_) => true,
_ => false,
}
}
pub fn is_type_param(&self) -> bool {
match *self {
GenericParam::Type(_) => true,
_ => false,
}
}
}
/// Represents lifetime, type and const parameters attached to a declaration of
/// a function, enum, trait, etc.
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub struct Generics {
pub lifetimes: Vec<LifetimeDef>,
pub ty_params: Vec<TyParam>,
pub params: Vec<GenericParam>,
pub where_clause: WhereClause,
pub span: Span,
}
impl Generics {
pub fn is_lt_parameterized(&self) -> bool {
!self.lifetimes.is_empty()
self.params.iter().any(|param| param.is_lifetime_param())
}
pub fn is_type_parameterized(&self) -> bool {
!self.ty_params.is_empty()
self.params.iter().any(|param| param.is_type_param())
}
pub fn is_parameterized(&self) -> bool {
self.is_lt_parameterized() || self.is_type_parameterized()
!self.params.is_empty()
}
pub fn span_for_name(&self, name: &str) -> Option<Span> {
for t in &self.ty_params {
if t.ident.name == name {
return Some(t.span);
for param in &self.params {
if let GenericParam::Type(ref t) = *param {
if t.ident.name == name {
return Some(t.span);
}
}
}
None
@@ -335,8 +361,7 @@ impl Default for Generics {
/// Creates an instance of `Generics`.
fn default() -> Generics {
Generics {
lifetimes: Vec::new(),
ty_params: Vec::new(),
params: Vec::new(),
where_clause: WhereClause {
id: DUMMY_NODE_ID,
predicates: Vec::new(),
@@ -372,8 +397,8 @@ pub enum WherePredicate {
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub struct WhereBoundPredicate {
pub span: Span,
/// Any lifetimes from a `for` binding
pub bound_lifetimes: Vec<LifetimeDef>,
/// Any generics from a `for` binding
pub bound_generic_params: Vec<GenericParam>,
/// The type being bounded
pub bounded_ty: P<Ty>,
/// Trait and lifetime bounds (`Clone+Send+'static`)
@@ -1461,7 +1486,7 @@ impl fmt::Debug for Ty {
pub struct BareFnTy {
pub unsafety: Unsafety,
pub abi: Abi,
pub lifetimes: Vec<LifetimeDef>,
pub generic_params: Vec<GenericParam>,
pub decl: P<FnDecl>
}
@@ -1820,7 +1845,7 @@ pub struct TraitRef {
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub struct PolyTraitRef {
/// The `'a` in `<'a> Foo<&'a T>`
pub bound_lifetimes: Vec<LifetimeDef>,
pub bound_generic_params: Vec<GenericParam>,
/// The `Foo<&'a T>` in `<'a> Foo<&'a T>`
pub trait_ref: TraitRef,
@@ -1829,9 +1854,9 @@ pub struct PolyTraitRef {
}
impl PolyTraitRef {
pub fn new(lifetimes: Vec<LifetimeDef>, path: Path, span: Span) -> Self {
pub fn new(generic_params: Vec<GenericParam>, path: Path, span: Span) -> Self {
PolyTraitRef {
bound_lifetimes: lifetimes,
bound_generic_params: generic_params,
trait_ref: TraitRef { path: path, ref_id: DUMMY_NODE_ID },
span,
}