Refactor ast::GenericParam as a struct
This commit is contained in:
parent
fba1fe2108
commit
2c6ff2469a
16 changed files with 337 additions and 354 deletions
|
@ -759,20 +759,20 @@ impl<'a> LoweringContext<'a> {
|
|||
hir_name
|
||||
}
|
||||
|
||||
// Evaluates `f` with the lifetimes in `lt_defs` in-scope.
|
||||
// Evaluates `f` with the lifetimes in `params` in-scope.
|
||||
// This is used to track which lifetimes have already been defined, and
|
||||
// which are new in-band lifetimes that need to have a definition created
|
||||
// for them.
|
||||
fn with_in_scope_lifetime_defs<'l, T, F>(
|
||||
&mut self,
|
||||
lt_defs: impl Iterator<Item = &'l LifetimeDef>,
|
||||
params: impl Iterator<Item = &'l GenericParamAST>,
|
||||
f: F,
|
||||
) -> T
|
||||
where
|
||||
F: FnOnce(&mut LoweringContext) -> T,
|
||||
{
|
||||
let old_len = self.in_scope_lifetimes.len();
|
||||
let lt_def_names = lt_defs.map(|lt_def| lt_def.lifetime.ident.name);
|
||||
let lt_def_names = params.map(|param| param.ident.name);
|
||||
self.in_scope_lifetimes.extend(lt_def_names);
|
||||
|
||||
let res = f(self);
|
||||
|
@ -781,8 +781,8 @@ impl<'a> LoweringContext<'a> {
|
|||
res
|
||||
}
|
||||
|
||||
// Same as the method above, but accepts `hir::LifetimeDef`s
|
||||
// instead of `ast::LifetimeDef`s.
|
||||
// Same as the method above, but accepts `hir::GenericParam`s
|
||||
// instead of `ast::GenericParam`s.
|
||||
// This should only be used with generics that have already had their
|
||||
// in-band lifetimes added. In practice, this means that this function is
|
||||
// only used when lowering a child item of a trait or impl.
|
||||
|
@ -817,8 +817,8 @@ impl<'a> LoweringContext<'a> {
|
|||
F: FnOnce(&mut LoweringContext) -> T,
|
||||
{
|
||||
let (in_band_defs, (mut lowered_generics, res)) = self.with_in_scope_lifetime_defs(
|
||||
generics.params.iter().filter_map(|p| match p {
|
||||
GenericParamAST::Lifetime(ld) => Some(ld),
|
||||
generics.params.iter().filter_map(|param| match param.kind {
|
||||
GenericParamKindAST::Lifetime { .. } => Some(param),
|
||||
_ => None,
|
||||
}),
|
||||
|this| {
|
||||
|
@ -1076,8 +1076,8 @@ impl<'a> LoweringContext<'a> {
|
|||
hir::TyRptr(lifetime, self.lower_mt(mt, itctx))
|
||||
}
|
||||
TyKind::BareFn(ref f) => self.with_in_scope_lifetime_defs(
|
||||
f.generic_params.iter().filter_map(|p| match p {
|
||||
GenericParamAST::Lifetime(ld) => Some(ld),
|
||||
f.generic_params.iter().filter_map(|param| match param.kind {
|
||||
GenericParamKindAST::Lifetime { .. } => Some(param),
|
||||
_ => None,
|
||||
}),
|
||||
|this| {
|
||||
|
@ -1940,21 +1940,19 @@ impl<'a> LoweringContext<'a> {
|
|||
add_bounds: &NodeMap<Vec<TyParamBound>>,
|
||||
itctx: ImplTraitContext)
|
||||
-> hir::GenericParam {
|
||||
match param {
|
||||
GenericParamAST::Lifetime(ref lifetime_def) => {
|
||||
match param.kind {
|
||||
GenericParamKindAST::Lifetime { ref bounds, ref lifetime, .. } => {
|
||||
let was_collecting_in_band = self.is_collecting_in_band_lifetimes;
|
||||
self.is_collecting_in_band_lifetimes = false;
|
||||
|
||||
let lifetime = self.lower_lifetime(&lifetime_def.lifetime);
|
||||
let lifetime = self.lower_lifetime(lifetime);
|
||||
let param = hir::GenericParam {
|
||||
id: lifetime.id,
|
||||
span: lifetime.span,
|
||||
pure_wrt_drop: attr::contains_name(&lifetime_def.attrs, "may_dangle"),
|
||||
pure_wrt_drop: attr::contains_name(¶m.attrs, "may_dangle"),
|
||||
kind: hir::GenericParamKind::Lifetime {
|
||||
name: lifetime.name,
|
||||
bounds: lifetime_def.bounds
|
||||
.iter()
|
||||
.map(|lt| self.lower_lifetime(lt)).collect(),
|
||||
bounds: bounds.iter().map(|lt| self.lower_lifetime(lt)).collect(),
|
||||
in_band: false,
|
||||
lifetime_deprecated: lifetime,
|
||||
}
|
||||
|
@ -1964,8 +1962,8 @@ impl<'a> LoweringContext<'a> {
|
|||
|
||||
param
|
||||
}
|
||||
GenericParamAST::Type(ref ty_param) => {
|
||||
let mut name = self.lower_ident(ty_param.ident);
|
||||
GenericParamKindAST::Type { ref bounds, ref default } => {
|
||||
let mut name = self.lower_ident(param.ident);
|
||||
|
||||
// Don't expose `Self` (recovered "keyword used as ident" parse error).
|
||||
// `rustc::ty` expects `Self` to be only used for a trait's `Self`.
|
||||
|
@ -1974,8 +1972,8 @@ impl<'a> LoweringContext<'a> {
|
|||
name = Symbol::gensym("Self");
|
||||
}
|
||||
|
||||
let mut bounds = self.lower_bounds(&ty_param.bounds, itctx);
|
||||
let add_bounds = add_bounds.get(&ty_param.id).map_or(&[][..], |x| &x);
|
||||
let mut bounds = self.lower_bounds(bounds, itctx);
|
||||
let add_bounds = add_bounds.get(¶m.id).map_or(&[][..], |x| &x);
|
||||
if !add_bounds.is_empty() {
|
||||
bounds = bounds
|
||||
.into_iter()
|
||||
|
@ -1984,22 +1982,20 @@ impl<'a> LoweringContext<'a> {
|
|||
}
|
||||
|
||||
hir::GenericParam {
|
||||
id: self.lower_node_id(ty_param.id).node_id,
|
||||
span: ty_param.ident.span,
|
||||
pure_wrt_drop: attr::contains_name(&ty_param.attrs, "may_dangle"),
|
||||
id: self.lower_node_id(param.id).node_id,
|
||||
span: param.ident.span,
|
||||
pure_wrt_drop: attr::contains_name(¶m.attrs, "may_dangle"),
|
||||
kind: hir::GenericParamKind::Type {
|
||||
name,
|
||||
bounds,
|
||||
default: ty_param.default.as_ref()
|
||||
.map(|x| {
|
||||
self.lower_ty(x, ImplTraitContext::Disallowed)
|
||||
}),
|
||||
synthetic: ty_param.attrs
|
||||
.iter()
|
||||
.filter(|attr| attr.check_name("rustc_synthetic"))
|
||||
.map(|_| hir::SyntheticTyParamKind::ImplTrait)
|
||||
.nth(0),
|
||||
attrs: self.lower_attrs(&ty_param.attrs),
|
||||
default: default.as_ref().map(|x| {
|
||||
self.lower_ty(x, ImplTraitContext::Disallowed)
|
||||
}),
|
||||
synthetic: param.attrs.iter()
|
||||
.filter(|attr| attr.check_name("rustc_synthetic"))
|
||||
.map(|_| hir::SyntheticTyParamKind::ImplTrait)
|
||||
.nth(0),
|
||||
attrs: self.lower_attrs(¶m.attrs),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2015,13 +2011,18 @@ impl<'a> LoweringContext<'a> {
|
|||
params.iter().map(|param| self.lower_generic_param(param, add_bounds, itctx)).collect()
|
||||
}
|
||||
|
||||
fn lower_generics(&mut self, g: &Generics, itctx: ImplTraitContext) -> hir::Generics {
|
||||
fn lower_generics(
|
||||
&mut self,
|
||||
generics: &Generics,
|
||||
itctx: ImplTraitContext)
|
||||
-> hir::Generics
|
||||
{
|
||||
// Collect `?Trait` bounds in where clause and move them to parameter definitions.
|
||||
// FIXME: This could probably be done with less rightward drift. Also looks like two control
|
||||
// paths where report_error is called are also the only paths that advance to after
|
||||
// the match statement, so the error reporting could probably just be moved there.
|
||||
let mut add_bounds = NodeMap();
|
||||
for pred in &g.where_clause.predicates {
|
||||
for pred in &generics.where_clause.predicates {
|
||||
if let WherePredicate::BoundPredicate(ref bound_pred) = *pred {
|
||||
'next_bound: for bound in &bound_pred.bounds {
|
||||
if let TraitTyParamBound(_, TraitBoundModifier::Maybe) = *bound {
|
||||
|
@ -2045,15 +2046,17 @@ impl<'a> LoweringContext<'a> {
|
|||
if let Some(node_id) =
|
||||
self.resolver.definitions().as_local_node_id(def_id)
|
||||
{
|
||||
for param in &g.params {
|
||||
if let GenericParamAST::Type(ref ty_param) = *param {
|
||||
if node_id == ty_param.id {
|
||||
add_bounds
|
||||
.entry(ty_param.id)
|
||||
.or_insert(Vec::new())
|
||||
.push(bound.clone());
|
||||
continue 'next_bound;
|
||||
for param in &generics.params {
|
||||
match param.kind {
|
||||
GenericParamKindAST::Type { .. } => {
|
||||
if node_id == param.id {
|
||||
add_bounds.entry(param.id)
|
||||
.or_insert(Vec::new())
|
||||
.push(bound.clone());
|
||||
continue 'next_bound;
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2068,9 +2071,9 @@ impl<'a> LoweringContext<'a> {
|
|||
}
|
||||
|
||||
hir::Generics {
|
||||
params: self.lower_generic_params(&g.params, &add_bounds, itctx),
|
||||
where_clause: self.lower_where_clause(&g.where_clause),
|
||||
span: g.span,
|
||||
params: self.lower_generic_params(&generics.params, &add_bounds, itctx),
|
||||
where_clause: self.lower_where_clause(&generics.where_clause),
|
||||
span: generics.span,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2093,8 +2096,8 @@ impl<'a> LoweringContext<'a> {
|
|||
span,
|
||||
}) => {
|
||||
self.with_in_scope_lifetime_defs(
|
||||
bound_generic_params.iter().filter_map(|p| match p {
|
||||
GenericParamAST::Lifetime(ld) => Some(ld),
|
||||
bound_generic_params.iter().filter_map(|param| match param.kind {
|
||||
GenericParamKindAST::Lifetime { .. } => Some(param),
|
||||
_ => None,
|
||||
}),
|
||||
|this| {
|
||||
|
@ -2412,8 +2415,8 @@ impl<'a> LoweringContext<'a> {
|
|||
);
|
||||
|
||||
let new_impl_items = self.with_in_scope_lifetime_defs(
|
||||
ast_generics.params.iter().filter_map(|p| match p {
|
||||
GenericParamAST::Lifetime(ld) => Some(ld),
|
||||
ast_generics.params.iter().filter_map(|param| match param.kind {
|
||||
GenericParamKindAST::Lifetime { .. } => Some(param),
|
||||
_ => None,
|
||||
}),
|
||||
|this| {
|
||||
|
|
|
@ -171,24 +171,17 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
|
|||
}
|
||||
|
||||
fn visit_generic_param(&mut self, param: &'a GenericParamAST) {
|
||||
match *param {
|
||||
GenericParamAST::Lifetime(ref lifetime_def) => {
|
||||
self.create_def(
|
||||
lifetime_def.lifetime.id,
|
||||
DefPathData::LifetimeDef(lifetime_def.lifetime.ident.name.as_interned_str()),
|
||||
REGULAR_SPACE,
|
||||
lifetime_def.lifetime.ident.span
|
||||
);
|
||||
}
|
||||
GenericParamAST::Type(ref ty_param) => {
|
||||
self.create_def(
|
||||
ty_param.id,
|
||||
DefPathData::TypeParam(ty_param.ident.name.as_interned_str()),
|
||||
REGULAR_SPACE,
|
||||
ty_param.ident.span
|
||||
);
|
||||
}
|
||||
}
|
||||
let name = param.ident.name.as_interned_str();
|
||||
let def_path_data = match param.kind {
|
||||
GenericParamKindAST::Lifetime { .. } => DefPathData::LifetimeDef(name),
|
||||
GenericParamKindAST::Type { .. } => DefPathData::TypeParam(name),
|
||||
};
|
||||
self.create_def(
|
||||
param.id,
|
||||
def_path_data,
|
||||
REGULAR_SPACE,
|
||||
param.ident.span
|
||||
);
|
||||
|
||||
visit::walk_generic_param(self, param);
|
||||
}
|
||||
|
|
|
@ -139,30 +139,24 @@ impl<'a> AstValidator<'a> {
|
|||
}
|
||||
|
||||
fn check_late_bound_lifetime_defs(&self, params: &Vec<GenericParamAST>) {
|
||||
// Check: Only lifetime parameters
|
||||
let non_lifetime_param_spans : Vec<_> = params.iter()
|
||||
.filter_map(|param| match *param {
|
||||
GenericParamAST::Lifetime(_) => None,
|
||||
GenericParamAST::Type(ref t) => Some(t.ident.span),
|
||||
// Check only lifetime parameters are present and that the lifetime
|
||||
// parameters that are present have no bounds.
|
||||
let non_lifetime_param_spans: Vec<_> = params.iter()
|
||||
.filter_map(|param| match param.kind {
|
||||
GenericParamKindAST::Lifetime { ref bounds, .. } => {
|
||||
if !bounds.is_empty() {
|
||||
let spans: Vec<_> = bounds.iter().map(|b| b.ident.span).collect();
|
||||
self.err_handler().span_err(spans,
|
||||
"lifetime bounds cannot be used in this context");
|
||||
}
|
||||
None
|
||||
}
|
||||
_ => Some(param.ident.span),
|
||||
}).collect();
|
||||
if !non_lifetime_param_spans.is_empty() {
|
||||
self.err_handler().span_err(non_lifetime_param_spans,
|
||||
"only lifetime parameters can be used in this context");
|
||||
}
|
||||
|
||||
// Check: No bounds on lifetime parameters
|
||||
for param in params.iter() {
|
||||
match *param {
|
||||
GenericParamAST::Lifetime(ref l) => {
|
||||
if !l.bounds.is_empty() {
|
||||
let spans: Vec<_> = l.bounds.iter().map(|b| b.ident.span).collect();
|
||||
self.err_handler().span_err(spans,
|
||||
"lifetime bounds cannot be used in this context");
|
||||
}
|
||||
}
|
||||
GenericParamAST::Type(_) => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -335,22 +329,21 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
|||
}
|
||||
ItemKind::TraitAlias(Generics { ref params, .. }, ..) => {
|
||||
for param in params {
|
||||
if let GenericParamAST::Type(TyParam {
|
||||
ident,
|
||||
ref bounds,
|
||||
ref default,
|
||||
..
|
||||
}) = *param
|
||||
{
|
||||
if !bounds.is_empty() {
|
||||
self.err_handler().span_err(ident.span,
|
||||
"type parameters on the left side of a \
|
||||
trait alias cannot be bounded");
|
||||
}
|
||||
if !default.is_none() {
|
||||
self.err_handler().span_err(ident.span,
|
||||
"type parameters on the left side of a \
|
||||
trait alias cannot have defaults");
|
||||
match param.kind {
|
||||
GenericParamKindAST::Lifetime { .. } => {}
|
||||
GenericParamKindAST::Type { ref bounds, ref default, .. } => {
|
||||
if !bounds.is_empty() {
|
||||
self.err_handler().span_err(param.ident.span,
|
||||
"type parameters on the left side \
|
||||
of a trait alias cannot be \
|
||||
bounded");
|
||||
}
|
||||
if !default.is_none() {
|
||||
self.err_handler().span_err(param.ident.span,
|
||||
"type parameters on the left side \
|
||||
of a trait alias cannot have \
|
||||
defaults");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -413,24 +406,23 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
|||
let mut seen_non_lifetime_param = false;
|
||||
let mut seen_default = None;
|
||||
for param in &g.params {
|
||||
match (param, seen_non_lifetime_param) {
|
||||
(&GenericParamAST::Lifetime(ref ld), true) => {
|
||||
match (¶m.kind, seen_non_lifetime_param) {
|
||||
(GenericParamKindAST::Lifetime { .. }, true) => {
|
||||
self.err_handler()
|
||||
.span_err(ld.lifetime.ident.span, "lifetime parameters must be leading");
|
||||
.span_err(param.ident.span, "lifetime parameters must be leading");
|
||||
},
|
||||
(&GenericParamAST::Lifetime(_), false) => {}
|
||||
_ => {
|
||||
(GenericParamKindAST::Lifetime { .. }, false) => {}
|
||||
(GenericParamKindAST::Type { ref default, .. }, _) => {
|
||||
seen_non_lifetime_param = true;
|
||||
if default.is_some() {
|
||||
seen_default = Some(param.ident.span);
|
||||
} else if let Some(span) = seen_default {
|
||||
self.err_handler()
|
||||
.span_err(span, "type parameters with a default must be trailing");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if let GenericParamAST::Type(ref ty_param @ TyParam { default: Some(_), .. }) = *param {
|
||||
seen_default = Some(ty_param.ident.span);
|
||||
} else if let Some(span) = seen_default {
|
||||
self.err_handler()
|
||||
.span_err(span, "type parameters with a default must be trailing");
|
||||
break
|
||||
}
|
||||
}
|
||||
for predicate in &g.where_clause.predicates {
|
||||
if let WherePredicate::EqPredicate(ref predicate) = *predicate {
|
||||
|
|
|
@ -56,7 +56,7 @@ use syntax::util::lev_distance::find_best_match_for_name;
|
|||
use syntax::visit::{self, FnKind, Visitor};
|
||||
use syntax::attr;
|
||||
use syntax::ast::{Arm, BindingMode, Block, Crate, Expr, ExprKind};
|
||||
use syntax::ast::{FnDecl, ForeignItem, ForeignItemKind, GenericParamAST, Generics};
|
||||
use syntax::ast::{FnDecl, ForeignItem, ForeignItemKind, GenericParamKindAST, Generics};
|
||||
use syntax::ast::{Item, ItemKind, ImplItem, ImplItemKind};
|
||||
use syntax::ast::{Label, Local, Mutability, Pat, PatKind, Path};
|
||||
use syntax::ast::{QSelf, TraitItemKind, TraitRef, Ty, TyKind};
|
||||
|
@ -797,31 +797,43 @@ impl<'a, 'tcx> Visitor<'tcx> for Resolver<'a> {
|
|||
// put all the parameters on the ban list and then remove
|
||||
// them one by one as they are processed and become available.
|
||||
let mut default_ban_rib = Rib::new(ForwardTyParamBanRibKind);
|
||||
let mut found_default = false;
|
||||
default_ban_rib.bindings.extend(generics.params.iter()
|
||||
.filter_map(|p| if let GenericParamAST::Type(ref tp) = *p { Some(tp) } else { None })
|
||||
.skip_while(|p| p.default.is_none())
|
||||
.map(|p| (Ident::with_empty_ctxt(p.ident.name), Def::Err)));
|
||||
.filter_map(|param| match param.kind {
|
||||
GenericParamKindAST::Lifetime { .. } => None,
|
||||
GenericParamKindAST::Type { ref default, .. } => {
|
||||
if default.is_some() {
|
||||
found_default = true;
|
||||
}
|
||||
if found_default {
|
||||
return Some((Ident::with_empty_ctxt(param.ident.name), Def::Err));
|
||||
}
|
||||
None
|
||||
}
|
||||
}));
|
||||
|
||||
for param in &generics.params {
|
||||
match *param {
|
||||
GenericParamAST::Lifetime(_) => self.visit_generic_param(param),
|
||||
GenericParamAST::Type(ref ty_param) => {
|
||||
for bound in &ty_param.bounds {
|
||||
match param.kind {
|
||||
GenericParamKindAST::Lifetime { .. } => self.visit_generic_param(param),
|
||||
GenericParamKindAST::Type { ref bounds, ref default, .. } => {
|
||||
for bound in bounds {
|
||||
self.visit_ty_param_bound(bound);
|
||||
}
|
||||
|
||||
if let Some(ref ty) = ty_param.default {
|
||||
if let Some(ref ty) = default {
|
||||
self.ribs[TypeNS].push(default_ban_rib);
|
||||
self.visit_ty(ty);
|
||||
default_ban_rib = self.ribs[TypeNS].pop().unwrap();
|
||||
}
|
||||
|
||||
// Allow all following defaults to refer to this type parameter.
|
||||
default_ban_rib.bindings.remove(&Ident::with_empty_ctxt(ty_param.ident.name));
|
||||
default_ban_rib.bindings.remove(&Ident::with_empty_ctxt(param.ident.name));
|
||||
}
|
||||
}
|
||||
}
|
||||
for p in &generics.where_clause.predicates { self.visit_where_predicate(p); }
|
||||
for p in &generics.where_clause.predicates {
|
||||
self.visit_where_predicate(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2198,25 +2210,28 @@ impl<'a> Resolver<'a> {
|
|||
let mut function_type_rib = Rib::new(rib_kind);
|
||||
let mut seen_bindings = FxHashMap();
|
||||
for param in &generics.params {
|
||||
if let GenericParamAST::Type(ref type_parameter) = *param {
|
||||
let ident = type_parameter.ident.modern();
|
||||
debug!("with_type_parameter_rib: {}", type_parameter.id);
|
||||
match param.kind {
|
||||
GenericParamKindAST::Type { .. } => {
|
||||
let ident = param.ident.modern();
|
||||
debug!("with_type_parameter_rib: {}", param.id);
|
||||
|
||||
if seen_bindings.contains_key(&ident) {
|
||||
let span = seen_bindings.get(&ident).unwrap();
|
||||
let err = ResolutionError::NameAlreadyUsedInTypeParameterList(
|
||||
ident.name,
|
||||
span,
|
||||
);
|
||||
resolve_error(self, type_parameter.ident.span, err);
|
||||
if seen_bindings.contains_key(&ident) {
|
||||
let span = seen_bindings.get(&ident).unwrap();
|
||||
let err = ResolutionError::NameAlreadyUsedInTypeParameterList(
|
||||
ident.name,
|
||||
span,
|
||||
);
|
||||
resolve_error(self, param.ident.span, err);
|
||||
}
|
||||
seen_bindings.entry(ident).or_insert(param.ident.span);
|
||||
|
||||
// plain insert (no renaming)
|
||||
let def_id = self.definitions.local_def_id(param.id);
|
||||
let def = Def::TyParam(def_id);
|
||||
function_type_rib.bindings.insert(ident, def);
|
||||
self.record_def(param.id, PathResolution::new(def));
|
||||
}
|
||||
seen_bindings.entry(ident).or_insert(type_parameter.ident.span);
|
||||
|
||||
// plain insert (no renaming)
|
||||
let def_id = self.definitions.local_def_id(type_parameter.id);
|
||||
let def = Def::TyParam(def_id);
|
||||
function_type_rib.bindings.insert(ident, def);
|
||||
self.record_def(type_parameter.id, PathResolution::new(def));
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
self.ribs[TypeNS].push(function_type_rib);
|
||||
|
|
|
@ -370,35 +370,38 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> {
|
|||
id: NodeId,
|
||||
) {
|
||||
for param in &generics.params {
|
||||
if let ast::GenericParamAST::Type(ref ty_param) = *param {
|
||||
let param_ss = ty_param.ident.span;
|
||||
let name = escape(self.span.snippet(param_ss));
|
||||
// Append $id to name to make sure each one is unique
|
||||
let qualname = format!("{}::{}${}", prefix, name, id);
|
||||
if !self.span.filter_generated(Some(param_ss), full_span) {
|
||||
let id = ::id_from_node_id(ty_param.id, &self.save_ctxt);
|
||||
let span = self.span_from_span(param_ss);
|
||||
match param.kind {
|
||||
ast::GenericParamKindAST::Lifetime { .. } => {}
|
||||
ast::GenericParamKindAST::Type { .. } => {
|
||||
let param_ss = param.ident.span;
|
||||
let name = escape(self.span.snippet(param_ss));
|
||||
// Append $id to name to make sure each one is unique.
|
||||
let qualname = format!("{}::{}${}", prefix, name, id);
|
||||
if !self.span.filter_generated(Some(param_ss), full_span) {
|
||||
let id = ::id_from_node_id(param.id, &self.save_ctxt);
|
||||
let span = self.span_from_span(param_ss);
|
||||
|
||||
self.dumper.dump_def(
|
||||
&Access {
|
||||
public: false,
|
||||
reachable: false,
|
||||
},
|
||||
Def {
|
||||
kind: DefKind::Type,
|
||||
id,
|
||||
span,
|
||||
name,
|
||||
qualname,
|
||||
value: String::new(),
|
||||
parent: None,
|
||||
children: vec![],
|
||||
decl_id: None,
|
||||
docs: String::new(),
|
||||
sig: None,
|
||||
attributes: vec![],
|
||||
},
|
||||
);
|
||||
self.dumper.dump_def(
|
||||
&Access {
|
||||
public: false,
|
||||
reachable: false,
|
||||
},
|
||||
Def {
|
||||
kind: DefKind::Type,
|
||||
id,
|
||||
span,
|
||||
name,
|
||||
qualname,
|
||||
value: String::new(),
|
||||
parent: None,
|
||||
children: vec![],
|
||||
decl_id: None,
|
||||
docs: String::new(),
|
||||
sig: None,
|
||||
attributes: vec![],
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1479,14 +1482,17 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> Visitor<'l> for DumpVisitor<'l, 'tc
|
|||
|
||||
fn visit_generics(&mut self, generics: &'l ast::Generics) {
|
||||
for param in &generics.params {
|
||||
if let ast::GenericParamAST::Type(ref ty_param) = *param {
|
||||
for bound in ty_param.bounds.iter() {
|
||||
if let ast::TraitTyParamBound(ref trait_ref, _) = *bound {
|
||||
self.process_path(trait_ref.trait_ref.ref_id, &trait_ref.trait_ref.path)
|
||||
match param.kind {
|
||||
ast::GenericParamKindAST::Lifetime { .. } => {}
|
||||
ast::GenericParamKindAST::Type { ref bounds, ref default, .. } => {
|
||||
for bound in bounds {
|
||||
if let ast::TraitTyParamBound(ref trait_ref, _) = *bound {
|
||||
self.process_path(trait_ref.trait_ref.ref_id, &trait_ref.trait_ref.path)
|
||||
}
|
||||
}
|
||||
if let Some(ref ty) = default {
|
||||
self.visit_ty(&ty);
|
||||
}
|
||||
}
|
||||
if let Some(ref ty) = ty_param.default {
|
||||
self.visit_ty(&ty);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -934,9 +934,9 @@ fn make_signature(decl: &ast::FnDecl, generics: &ast::Generics) -> String {
|
|||
sig.push_str(&generics
|
||||
.params
|
||||
.iter()
|
||||
.map(|param| match *param {
|
||||
ast::GenericParamAST::Lifetime(ref l) => l.lifetime.ident.name.to_string(),
|
||||
ast::GenericParamAST::Type(ref t) => t.ident.to_string(),
|
||||
.map(|param| match param.kind {
|
||||
ast::GenericParamKindAST::Lifetime { .. } => param.ident.name.to_string(),
|
||||
ast::GenericParamKindAST::Type { .. } => param.ident.to_string(),
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.join(", "));
|
||||
|
|
|
@ -223,9 +223,9 @@ impl Sig for ast::Ty {
|
|||
text.push_str("for<");
|
||||
text.push_str(&f.generic_params
|
||||
.iter()
|
||||
.filter_map(|p| match *p {
|
||||
ast::GenericParamAST::Lifetime(ref l) => {
|
||||
Some(l.lifetime.ident.to_string())
|
||||
.filter_map(|param| match param.kind {
|
||||
ast::GenericParamKindAST::Lifetime { .. } => {
|
||||
Some(param.ident.to_string())
|
||||
}
|
||||
_ => None,
|
||||
})
|
||||
|
@ -617,45 +617,34 @@ impl Sig for ast::Generics {
|
|||
|
||||
let mut defs = vec![];
|
||||
for param in &self.params {
|
||||
match *param {
|
||||
ast::GenericParamAST::Lifetime(ref l) => {
|
||||
let mut l_text = l.lifetime.ident.to_string();
|
||||
defs.push(SigElement {
|
||||
id: id_from_node_id(l.lifetime.id, scx),
|
||||
start: offset + text.len(),
|
||||
end: offset + text.len() + l_text.len(),
|
||||
});
|
||||
|
||||
if !l.bounds.is_empty() {
|
||||
l_text.push_str(": ");
|
||||
let bounds = l.bounds
|
||||
.iter()
|
||||
let mut param_text = param.ident.to_string();
|
||||
defs.push(SigElement {
|
||||
id: id_from_node_id(param.id, scx),
|
||||
start: offset + text.len(),
|
||||
end: offset + text.len() + param_text.len(),
|
||||
});
|
||||
match param.kind {
|
||||
ast::GenericParamKindAST::Lifetime { ref bounds, .. } => {
|
||||
if !bounds.is_empty() {
|
||||
param_text.push_str(": ");
|
||||
let bounds = bounds.iter()
|
||||
.map(|l| l.ident.to_string())
|
||||
.collect::<Vec<_>>()
|
||||
.join(" + ");
|
||||
l_text.push_str(&bounds);
|
||||
param_text.push_str(&bounds);
|
||||
// FIXME add lifetime bounds refs.
|
||||
}
|
||||
text.push_str(&l_text);
|
||||
text.push(',');
|
||||
}
|
||||
ast::GenericParamAST::Type(ref t) => {
|
||||
let mut t_text = t.ident.to_string();
|
||||
defs.push(SigElement {
|
||||
id: id_from_node_id(t.id, scx),
|
||||
start: offset + text.len(),
|
||||
end: offset + text.len() + t_text.len(),
|
||||
});
|
||||
|
||||
if !t.bounds.is_empty() {
|
||||
t_text.push_str(": ");
|
||||
t_text.push_str(&pprust::bounds_to_string(&t.bounds));
|
||||
ast::GenericParamKindAST::Type { ref bounds, .. } => {
|
||||
if !bounds.is_empty() {
|
||||
param_text.push_str(": ");
|
||||
param_text.push_str(&pprust::bounds_to_string(bounds));
|
||||
// FIXME descend properly into bounds.
|
||||
}
|
||||
text.push_str(&t_text);
|
||||
text.push(',');
|
||||
}
|
||||
}
|
||||
text.push_str(¶m_text);
|
||||
text.push(',');
|
||||
}
|
||||
|
||||
text.push('>');
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -192,8 +192,8 @@ use std::collections::HashSet;
|
|||
use std::vec;
|
||||
|
||||
use rustc_target::spec::abi::Abi;
|
||||
use syntax::ast::{self, BinOpKind, EnumDef, Expr, GenericParamAST, Generics, Ident, PatKind};
|
||||
use syntax::ast::{VariantData, GenericArgAST};
|
||||
use syntax::ast::{self, BinOpKind, EnumDef, Expr, Generics, Ident, PatKind};
|
||||
use syntax::ast::{VariantData, GenericParamKindAST, GenericArgAST};
|
||||
use syntax::attr;
|
||||
use syntax::ext::base::{Annotatable, ExtCtxt};
|
||||
use syntax::ext::build::AstBuilder;
|
||||
|
@ -547,9 +547,9 @@ impl<'a> TraitDef<'a> {
|
|||
|
||||
// Create the generic parameters
|
||||
params.extend(generics.params.iter().map(|param| {
|
||||
match *param {
|
||||
ref l @ GenericParamAST::Lifetime(_) => l.clone(),
|
||||
GenericParamAST::Type(ref ty_param) => {
|
||||
match param.kind {
|
||||
GenericParamKindAST::Lifetime { .. } => param.clone(),
|
||||
GenericParamKindAST::Type { bounds: ref ty_bounds, .. } => {
|
||||
// I don't think this can be moved out of the loop, since
|
||||
// a TyParamBound requires an ast id
|
||||
let mut bounds: Vec<_> =
|
||||
|
@ -564,12 +564,11 @@ impl<'a> TraitDef<'a> {
|
|||
bounds.push(cx.typarambound(trait_path.clone()));
|
||||
|
||||
// also add in any bounds from the declaration
|
||||
for declared_bound in ty_param.bounds.iter() {
|
||||
for declared_bound in ty_bounds {
|
||||
bounds.push((*declared_bound).clone());
|
||||
}
|
||||
|
||||
let ty_param = cx.typaram(self.span, ty_param.ident, vec![], bounds, None);
|
||||
GenericParamAST::Type(ty_param)
|
||||
cx.typaram(self.span, param.ident, vec![], bounds, None)
|
||||
}
|
||||
}
|
||||
}));
|
||||
|
@ -607,8 +606,8 @@ impl<'a> TraitDef<'a> {
|
|||
// Extra scope required here so ty_params goes out of scope before params is moved
|
||||
|
||||
let mut ty_params = params.iter()
|
||||
.filter_map(|param| match *param {
|
||||
ast::GenericParamAST::Type(ref t) => Some(t),
|
||||
.filter_map(|param| match param.kind {
|
||||
ast::GenericParamKindAST::Type { .. } => Some(param),
|
||||
_ => None,
|
||||
})
|
||||
.peekable();
|
||||
|
@ -668,17 +667,16 @@ impl<'a> TraitDef<'a> {
|
|||
// Create the type parameters on the `self` path.
|
||||
let self_ty_params: Vec<P<ast::Ty>> = generics.params
|
||||
.iter()
|
||||
.filter_map(|param| match *param {
|
||||
GenericParamAST::Type(ref ty_param)
|
||||
=> Some(cx.ty_ident(self.span, ty_param.ident)),
|
||||
.filter_map(|param| match param.kind {
|
||||
GenericParamKindAST::Type { .. } => Some(cx.ty_ident(self.span, param.ident)),
|
||||
_ => None,
|
||||
})
|
||||
.collect();
|
||||
|
||||
let self_lifetimes: Vec<ast::Lifetime> = generics.params
|
||||
.iter()
|
||||
.filter_map(|param| match *param {
|
||||
GenericParamAST::Lifetime(ref ld) => Some(ld.lifetime),
|
||||
.filter_map(|param| match param.kind {
|
||||
GenericParamKindAST::Lifetime { ref lifetime, .. } => Some(*lifetime),
|
||||
_ => None,
|
||||
})
|
||||
.collect();
|
||||
|
|
|
@ -15,7 +15,7 @@ pub use self::PtrTy::*;
|
|||
pub use self::Ty::*;
|
||||
|
||||
use syntax::ast;
|
||||
use syntax::ast::{Expr, GenericParamAST, Generics, Ident, SelfKind, GenericArgAST};
|
||||
use syntax::ast::{Expr, GenericParamKindAST, Generics, Ident, SelfKind, GenericArgAST};
|
||||
use syntax::ext::base::ExtCtxt;
|
||||
use syntax::ext::build::AstBuilder;
|
||||
use syntax::codemap::{respan, DUMMY_SP};
|
||||
|
@ -191,9 +191,9 @@ impl<'a> Ty<'a> {
|
|||
Self_ => {
|
||||
let ty_params: Vec<P<ast::Ty>> = self_generics.params
|
||||
.iter()
|
||||
.filter_map(|param| match *param {
|
||||
GenericParamAST::Type(ref ty_param) => {
|
||||
Some(cx.ty_ident(span, ty_param.ident))
|
||||
.filter_map(|param| match param.kind {
|
||||
GenericParamKindAST::Type { .. } => {
|
||||
Some(cx.ty_ident(span, param.ident))
|
||||
}
|
||||
_ => None,
|
||||
})
|
||||
|
@ -201,8 +201,8 @@ impl<'a> Ty<'a> {
|
|||
|
||||
let lifetimes: Vec<ast::Lifetime> = self_generics.params
|
||||
.iter()
|
||||
.filter_map(|param| match *param {
|
||||
GenericParamAST::Lifetime(ref ld) => Some(ld.lifetime),
|
||||
.filter_map(|param| match param.kind {
|
||||
GenericParamKindAST::Lifetime { ref lifetime, .. } => Some(*lifetime),
|
||||
_ => None,
|
||||
})
|
||||
.collect();
|
||||
|
@ -234,7 +234,7 @@ fn mk_ty_param(cx: &ExtCtxt,
|
|||
bounds: &[Path],
|
||||
self_ident: Ident,
|
||||
self_generics: &Generics)
|
||||
-> ast::TyParam {
|
||||
-> ast::GenericParamAST {
|
||||
let bounds = bounds.iter()
|
||||
.map(|b| {
|
||||
let path = b.to_path(cx, span, self_ident, self_generics);
|
||||
|
@ -244,7 +244,7 @@ fn mk_ty_param(cx: &ExtCtxt,
|
|||
cx.typaram(span, cx.ident_of(name), attrs.to_owned(), bounds, None)
|
||||
}
|
||||
|
||||
fn mk_generics(params: Vec<GenericParamAST>, span: Span) -> Generics {
|
||||
fn mk_generics(params: Vec<ast::GenericParamAST>, span: Span) -> Generics {
|
||||
Generics {
|
||||
params,
|
||||
where_clause: ast::WhereClause {
|
||||
|
@ -282,16 +282,13 @@ impl<'a> LifetimeBounds<'a> {
|
|||
let bounds = bounds.iter()
|
||||
.map(|b| cx.lifetime(span, Ident::from_str(b)))
|
||||
.collect();
|
||||
let lifetime_def = cx.lifetime_def(span, Ident::from_str(lt), vec![], bounds);
|
||||
GenericParamAST::Lifetime(lifetime_def)
|
||||
cx.lifetime_def(span, Ident::from_str(lt), vec![], bounds)
|
||||
})
|
||||
.chain(self.bounds
|
||||
.iter()
|
||||
.map(|t| {
|
||||
let (name, ref bounds) = *t;
|
||||
GenericParamAST::Type(mk_ty_param(
|
||||
cx, span, name, &[], &bounds, self_ty, self_generics
|
||||
))
|
||||
mk_ty_param(cx, span, name, &[], &bounds, self_ty, self_generics)
|
||||
})
|
||||
)
|
||||
.collect();
|
||||
|
|
|
@ -134,9 +134,12 @@ fn hygienic_type_parameter(item: &Annotatable, base: &str) -> String {
|
|||
match item.node {
|
||||
ast::ItemKind::Struct(_, ast::Generics { ref params, .. }) |
|
||||
ast::ItemKind::Enum(_, ast::Generics { ref params, .. }) => {
|
||||
for param in params.iter() {
|
||||
if let ast::GenericParamAST::Type(ref ty) = *param {
|
||||
typaram.push_str(&ty.ident.as_str());
|
||||
for param in params {
|
||||
match param.kind {
|
||||
ast::GenericParamKindAST::Type { .. } => {
|
||||
typaram.push_str(¶m.ident.as_str());
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue